Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit faa4602e authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

x86, perf, bts, mm: Delete the never used BTS-ptrace code



Support for the PMU's BTS features has been upstreamed in
v2.6.32, but we still have the old and disabled ptrace-BTS,
as Linus noticed it not so long ago.

It's buggy: TIF_DEBUGCTLMSR is trampling all over that MSR without
regard for other uses (perf) and doesn't provide the flexibility
needed for perf either.

Its users are ptrace-block-step and ptrace-bts, since ptrace-bts
was never used and ptrace-block-step can be implemented using a
much simpler approach.

So axe all 3000 lines of it. That includes the *locked_memory*()
APIs in mm/mlock.c as well.

Reported-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Roland McGrath <roland@redhat.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Markus Metzger <markus.t.metzger@intel.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
LKML-Reference: <20100325135413.938004390@chello.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 7c5ecaf7
Loading
Loading
Loading
Loading
+0 −20
Original line number Diff line number Diff line
@@ -502,23 +502,3 @@ config CPU_SUP_UMC_32
	  CPU might render the kernel unbootable.

	  If unsure, say N.

config X86_DS
	def_bool X86_PTRACE_BTS
	depends on X86_DEBUGCTLMSR
	select HAVE_HW_BRANCH_TRACER

config X86_PTRACE_BTS
	bool "Branch Trace Store"
	default y
	depends on X86_DEBUGCTLMSR
	depends on BROKEN
	---help---
	  This adds a ptrace interface to the hardware's branch trace store.

	  Debuggers may use it to collect an execution trace of the debugged
	  application in order to answer the question 'how did I get here?'.
	  Debuggers may trace user mode as well as kernel mode.

	  Say Y unless there is no application development on this machine
	  and you want to save a small amount of code size.
+0 −9
Original line number Diff line number Diff line
@@ -174,15 +174,6 @@ config IOMMU_LEAK
	  Add a simple leak tracer to the IOMMU code. This is useful when you
	  are debugging a buggy device driver that leaks IOMMU mappings.

config X86_DS_SELFTEST
    bool "DS selftest"
    default y
    depends on DEBUG_KERNEL
    depends on X86_DS
	---help---
	  Perform Debug Store selftests at boot time.
	  If in doubt, say "N".

config HAVE_MMIOTRACE_SUPPORT
	def_bool y

arch/x86/include/asm/ds.h

deleted100644 → 0
+0 −302
Original line number Diff line number Diff line
/*
 * Debug Store (DS) support
 *
 * This provides a low-level interface to the hardware's Debug Store
 * feature that is used for branch trace store (BTS) and
 * precise-event based sampling (PEBS).
 *
 * It manages:
 * - DS and BTS hardware configuration
 * - buffer overflow handling (to be done)
 * - buffer access
 *
 * It does not do:
 * - security checking (is the caller allowed to trace the task)
 * - buffer allocation (memory accounting)
 *
 *
 * Copyright (C) 2007-2009 Intel Corporation.
 * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
 */

#ifndef _ASM_X86_DS_H
#define _ASM_X86_DS_H


#include <linux/types.h>
#include <linux/init.h>
#include <linux/err.h>


#ifdef CONFIG_X86_DS

struct task_struct;
struct ds_context;
struct ds_tracer;
struct bts_tracer;
struct pebs_tracer;

typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);


/*
 * A list of features plus corresponding macros to talk about them in
 * the ds_request function's flags parameter.
 *
 * We use the enum to index an array of corresponding control bits;
 * we use the macro to index a flags bit-vector.
 */
enum ds_feature {
	dsf_bts = 0,
	dsf_bts_kernel,
#define BTS_KERNEL (1 << dsf_bts_kernel)
	/* trace kernel-mode branches */

	dsf_bts_user,
#define BTS_USER (1 << dsf_bts_user)
	/* trace user-mode branches */

	dsf_bts_overflow,
	dsf_bts_max,
	dsf_pebs = dsf_bts_max,

	dsf_pebs_max,
	dsf_ctl_max = dsf_pebs_max,
	dsf_bts_timestamps = dsf_ctl_max,
#define BTS_TIMESTAMPS (1 << dsf_bts_timestamps)
	/* add timestamps into BTS trace */

#define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS)
};


/*
 * Request BTS or PEBS
 *
 * Due to alignement constraints, the actual buffer may be slightly
 * smaller than the requested or provided buffer.
 *
 * Returns a pointer to a tracer structure on success, or
 * ERR_PTR(errcode) on failure.
 *
 * The interrupt threshold is independent from the overflow callback
 * to allow users to use their own overflow interrupt handling mechanism.
 *
 * The function might sleep.
 *
 * task: the task to request recording for
 * cpu:  the cpu to request recording for
 * base: the base pointer for the (non-pageable) buffer;
 * size: the size of the provided buffer in bytes
 * ovfl: pointer to a function to be called on buffer overflow;
 *       NULL if cyclic buffer requested
 * th: the interrupt threshold in records from the end of the buffer;
 *     -1 if no interrupt threshold is requested.
 * flags: a bit-mask of the above flags
 */
extern struct bts_tracer *ds_request_bts_task(struct task_struct *task,
					      void *base, size_t size,
					      bts_ovfl_callback_t ovfl,
					      size_t th, unsigned int flags);
extern struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
					     bts_ovfl_callback_t ovfl,
					     size_t th, unsigned int flags);
extern struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
						void *base, size_t size,
						pebs_ovfl_callback_t ovfl,
						size_t th, unsigned int flags);
extern struct pebs_tracer *ds_request_pebs_cpu(int cpu,
					       void *base, size_t size,
					       pebs_ovfl_callback_t ovfl,
					       size_t th, unsigned int flags);

/*
 * Release BTS or PEBS resources
 * Suspend and resume BTS or PEBS tracing
 *
 * Must be called with irq's enabled.
 *
 * tracer: the tracer handle returned from ds_request_~()
 */
extern void ds_release_bts(struct bts_tracer *tracer);
extern void ds_suspend_bts(struct bts_tracer *tracer);
extern void ds_resume_bts(struct bts_tracer *tracer);
extern void ds_release_pebs(struct pebs_tracer *tracer);
extern void ds_suspend_pebs(struct pebs_tracer *tracer);
extern void ds_resume_pebs(struct pebs_tracer *tracer);

/*
 * Release BTS or PEBS resources
 * Suspend and resume BTS or PEBS tracing
 *
 * Cpu tracers must call this on the traced cpu.
 * Task tracers must call ds_release_~_noirq() for themselves.
 *
 * May be called with irq's disabled.
 *
 * Returns 0 if successful;
 * -EPERM if the cpu tracer does not trace the current cpu.
 * -EPERM if the task tracer does not trace itself.
 *
 * tracer: the tracer handle returned from ds_request_~()
 */
extern int ds_release_bts_noirq(struct bts_tracer *tracer);
extern int ds_suspend_bts_noirq(struct bts_tracer *tracer);
extern int ds_resume_bts_noirq(struct bts_tracer *tracer);
extern int ds_release_pebs_noirq(struct pebs_tracer *tracer);
extern int ds_suspend_pebs_noirq(struct pebs_tracer *tracer);
extern int ds_resume_pebs_noirq(struct pebs_tracer *tracer);


/*
 * The raw DS buffer state as it is used for BTS and PEBS recording.
 *
 * This is the low-level, arch-dependent interface for working
 * directly on the raw trace data.
 */
struct ds_trace {
	/* the number of bts/pebs records */
	size_t n;
	/* the size of a bts/pebs record in bytes */
	size_t size;
	/* pointers into the raw buffer:
	   - to the first entry */
	void *begin;
	/* - one beyond the last entry */
	void *end;
	/* - one beyond the newest entry */
	void *top;
	/* - the interrupt threshold */
	void *ith;
	/* flags given on ds_request() */
	unsigned int flags;
};

/*
 * An arch-independent view on branch trace data.
 */
enum bts_qualifier {
	bts_invalid,
#define BTS_INVALID bts_invalid

	bts_branch,
#define BTS_BRANCH bts_branch

	bts_task_arrives,
#define BTS_TASK_ARRIVES bts_task_arrives

	bts_task_departs,
#define BTS_TASK_DEPARTS bts_task_departs

	bts_qual_bit_size = 4,
	bts_qual_max = (1 << bts_qual_bit_size),
};

struct bts_struct {
	__u64 qualifier;
	union {
		/* BTS_BRANCH */
		struct {
			__u64 from;
			__u64 to;
		} lbr;
		/* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
		struct {
			__u64 clock;
			pid_t pid;
		} event;
	} variant;
};


/*
 * The BTS state.
 *
 * This gives access to the raw DS state and adds functions to provide
 * an arch-independent view of the BTS data.
 */
struct bts_trace {
	struct ds_trace ds;

	int (*read)(struct bts_tracer *tracer, const void *at,
		    struct bts_struct *out);
	int (*write)(struct bts_tracer *tracer, const struct bts_struct *in);
};


/*
 * The PEBS state.
 *
 * This gives access to the raw DS state and the PEBS-specific counter
 * reset value.
 */
struct pebs_trace {
	struct ds_trace ds;

	/* the number of valid counters in the below array */
	unsigned int counters;

#define MAX_PEBS_COUNTERS 4
	/* the counter reset value */
	unsigned long long counter_reset[MAX_PEBS_COUNTERS];
};


/*
 * Read the BTS or PEBS trace.
 *
 * Returns a view on the trace collected for the parameter tracer.
 *
 * The view remains valid as long as the traced task is not running or
 * the tracer is suspended.
 * Writes into the trace buffer are not reflected.
 *
 * tracer: the tracer handle returned from ds_request_~()
 */
extern const struct bts_trace *ds_read_bts(struct bts_tracer *tracer);
extern const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer);


/*
 * Reset the write pointer of the BTS/PEBS buffer.
 *
 * Returns 0 on success; -Eerrno on error
 *
 * tracer: the tracer handle returned from ds_request_~()
 */
extern int ds_reset_bts(struct bts_tracer *tracer);
extern int ds_reset_pebs(struct pebs_tracer *tracer);

/*
 * Set the PEBS counter reset value.
 *
 * Returns 0 on success; -Eerrno on error
 *
 * tracer: the tracer handle returned from ds_request_pebs()
 * counter: the index of the counter
 * value: the new counter reset value
 */
extern int ds_set_pebs_reset(struct pebs_tracer *tracer,
			     unsigned int counter, u64 value);

/*
 * Initialization
 */
struct cpuinfo_x86;
extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);

/*
 * Context switch work
 */
extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);

#else /* CONFIG_X86_DS */

struct cpuinfo_x86;
static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
static inline void ds_switch_to(struct task_struct *prev,
				struct task_struct *next) {}

#endif /* CONFIG_X86_DS */
#endif /* _ASM_X86_DS_H */
+1 −32
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ struct mm_struct;
#include <asm/msr.h>
#include <asm/desc_defs.h>
#include <asm/nops.h>
#include <asm/ds.h>

#include <linux/personality.h>
#include <linux/cpumask.h>
@@ -29,6 +28,7 @@ struct mm_struct;
#include <linux/threads.h>
#include <linux/math64.h>
#include <linux/init.h>
#include <linux/err.h>

#define HBP_NUM 4
/*
@@ -473,10 +473,6 @@ struct thread_struct {
	unsigned long		iopl;
	/* Max allowed port in the bitmap, in bytes: */
	unsigned		io_bitmap_max;
/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set.  */
	unsigned long	debugctlmsr;
	/* Debug Store context; see asm/ds.h */
	struct ds_context	*ds_ctx;
};

static inline unsigned long native_get_debugreg(int regno)
@@ -814,21 +810,6 @@ static inline unsigned long get_debugctlmsr(void)
    return debugctlmsr;
}

static inline unsigned long get_debugctlmsr_on_cpu(int cpu)
{
	u64 debugctlmsr = 0;
	u32 val1, val2;

#ifndef CONFIG_X86_DEBUGCTLMSR
	if (boot_cpu_data.x86 < 6)
		return 0;
#endif
	rdmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR, &val1, &val2);
	debugctlmsr = val1 | ((u64)val2 << 32);

	return debugctlmsr;
}

static inline void update_debugctlmsr(unsigned long debugctlmsr)
{
#ifndef CONFIG_X86_DEBUGCTLMSR
@@ -838,18 +819,6 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr)
	wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
}

static inline void update_debugctlmsr_on_cpu(int cpu,
					     unsigned long debugctlmsr)
{
#ifndef CONFIG_X86_DEBUGCTLMSR
	if (boot_cpu_data.x86 < 6)
		return;
#endif
	wrmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR,
		     (u32)((u64)debugctlmsr),
		     (u32)((u64)debugctlmsr >> 32));
}

/*
 * from system description table in BIOS. Mostly for MCA use, but
 * others may find it useful:
+1 −56
Original line number Diff line number Diff line
@@ -82,61 +82,6 @@

#ifndef __ASSEMBLY__
#include <linux/types.h>

/* configuration/status structure used in PTRACE_BTS_CONFIG and
   PTRACE_BTS_STATUS commands.
*/
struct ptrace_bts_config {
	/* requested or actual size of BTS buffer in bytes */
	__u32 size;
	/* bitmask of below flags */
	__u32 flags;
	/* buffer overflow signal */
	__u32 signal;
	/* actual size of bts_struct in bytes */
	__u32 bts_size;
};
#endif /* __ASSEMBLY__ */

#define PTRACE_BTS_O_TRACE	0x1 /* branch trace */
#define PTRACE_BTS_O_SCHED	0x2 /* scheduling events w/ jiffies */
#define PTRACE_BTS_O_SIGNAL     0x4 /* send SIG<signal> on buffer overflow
				       instead of wrapping around */
#define PTRACE_BTS_O_ALLOC	0x8 /* (re)allocate buffer */

#define PTRACE_BTS_CONFIG	40
/* Configure branch trace recording.
   ADDR points to a struct ptrace_bts_config.
   DATA gives the size of that buffer.
   A new buffer is allocated, if requested in the flags.
   An overflow signal may only be requested for new buffers.
   Returns the number of bytes read.
*/
#define PTRACE_BTS_STATUS	41
/* Return the current configuration in a struct ptrace_bts_config
   pointed to by ADDR; DATA gives the size of that buffer.
   Returns the number of bytes written.
*/
#define PTRACE_BTS_SIZE		42
/* Return the number of available BTS records for draining.
   DATA and ADDR are ignored.
*/
#define PTRACE_BTS_GET		43
/* Get a single BTS record.
   DATA defines the index into the BTS array, where 0 is the newest
   entry, and higher indices refer to older entries.
   ADDR is pointing to struct bts_struct (see asm/ds.h).
*/
#define PTRACE_BTS_CLEAR	44
/* Clear the BTS buffer.
   DATA and ADDR are ignored.
*/
#define PTRACE_BTS_DRAIN	45
/* Read all available BTS records and clear the buffer.
   ADDR points to an array of struct bts_struct.
   DATA gives the size of that buffer.
   BTS records are read from oldest to newest.
   Returns number of BTS records drained.
*/
#endif

#endif /* _ASM_X86_PTRACE_ABI_H */
Loading