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

Commit e9a22d1f authored by Ingo Molnar's avatar Ingo Molnar
Browse files

x86, bts: cleanups



Impact: cleanup, no code changed

Cc: Markus Metzger <markus.t.metzger@intel.com>
LKML-Reference: <20090313104218.A30096@sedona.ch.intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 321bb5e1
Loading
Loading
Loading
Loading
+80 −62
Original line number Diff line number Diff line
@@ -19,44 +19,53 @@
 * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
 */


#include <asm/ds.h>

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/kernel.h>

#include <asm/ds.h>

#include "ds_selftest.h"

/*
 * The configuration for a particular DS hardware implementation.
 * The configuration for a particular DS hardware implementation:
 */
struct ds_configuration {
	/* The name of the configuration. */
	/* The name of the configuration: */
	const char		*name;
	/* The size of pointer-typed fields in DS, BTS, and PEBS. */

	/* The size of pointer-typed fields in DS, BTS, and PEBS: */
	unsigned char		sizeof_ptr_field;
	/* The size of a BTS/PEBS record in bytes. */

	/* The size of a BTS/PEBS record in bytes: */
	unsigned char		sizeof_rec[2];
	/* Control bit-masks indexed by enum ds_feature. */

	/* Control bit-masks indexed by enum ds_feature: */
	unsigned long		ctl[dsf_ctl_max];
};
static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array);

#define ds_cfg per_cpu(ds_cfg_array, smp_processor_id())

#define MAX_SIZEOF_DS (12 * 8)	/* Maximal size of a DS configuration. */
#define MAX_SIZEOF_BTS (3 * 8)	/* Maximal size of a BTS record. */
#define DS_ALIGNMENT (1 << 3)	/* BTS and PEBS buffer alignment. */
/* Maximal size of a DS configuration: */
#define MAX_SIZEOF_DS		(12 * 8)

/* Maximal size of a BTS record: */
#define MAX_SIZEOF_BTS		(3 * 8)

/* BTS and PEBS buffer alignment: */
#define DS_ALIGNMENT		(1 << 3)

/* Mask of control bits in the DS MSR register: */
#define BTS_CONTROL				  \
 (ds_cfg.ctl[dsf_bts] | ds_cfg.ctl[dsf_bts_kernel] | ds_cfg.ctl[dsf_bts_user] |\
	( ds_cfg.ctl[dsf_bts]			| \
	  ds_cfg.ctl[dsf_bts_kernel]		| \
	  ds_cfg.ctl[dsf_bts_user]		| \
	  ds_cfg.ctl[dsf_bts_overflow] )


/*
 * A BTS or PEBS tracer.
 *
@@ -72,20 +81,24 @@ struct ds_tracer {
};

struct bts_tracer {
	/* The common DS part. */
	/* The common DS part: */
	struct ds_tracer	ds;
	/* The trace including the DS configuration. */

	/* The trace including the DS configuration: */
	struct bts_trace	trace;
	/* Buffer overflow notification function. */

	/* Buffer overflow notification function: */
	bts_ovfl_callback_t	ovfl;
};

struct pebs_tracer {
	/* The common DS part. */
	/* The common DS part: */
	struct ds_tracer	ds;
	/* The trace including the DS configuration. */

	/* The trace including the DS configuration: */
	struct pebs_trace	trace;
	/* Buffer overflow notification function. */

	/* Buffer overflow notification function: */
	pebs_ovfl_callback_t	ovfl;
};

@@ -95,6 +108,7 @@ struct pebs_tracer {
 *
 * The DS configuration consists of the following fields; different
 * architetures vary in the size of those fields.
 *
 * - double-word aligned base linear address of the BTS buffer
 * - write pointer into the BTS buffer
 * - end linear address of the BTS buffer (one byte beyond the end of
@@ -137,15 +151,16 @@ enum ds_qualifier {
	ds_pebs
};

static inline unsigned long ds_get(const unsigned char *base,
				   enum ds_qualifier qual, enum ds_field field)
static inline unsigned long
ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field)
{
	base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
	return *(unsigned long *)base;
}

static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
			  enum ds_field field, unsigned long value)
static inline void
ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field,
       unsigned long value)
{
	base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
	(*(unsigned long *)base) = value;
@@ -157,7 +172,6 @@ static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
 */
static DEFINE_SPINLOCK(ds_lock);


/*
 * We either support (system-wide) per-cpu or per-thread allocation.
 * We distinguish the two based on the task_struct pointer, where a
@@ -211,16 +225,20 @@ static inline int check_tracer(struct task_struct *task)
 * deallocated when the last user puts the context.
 */
struct ds_context {
	/* The DS configuration; goes into MSR_IA32_DS_AREA. */
	/* The DS configuration; goes into MSR_IA32_DS_AREA: */
	unsigned char		ds[MAX_SIZEOF_DS];
	/* The owner of the BTS and PEBS configuration, respectively. */

	/* The owner of the BTS and PEBS configuration, respectively: */
	struct bts_tracer	*bts_master;
	struct pebs_tracer	*pebs_master;
	/* Use count. */

	/* Use count: */
	unsigned long count;
	/* Pointer to the context pointer field. */

	/* Pointer to the context pointer field: */
	struct ds_context	**this;
	/* The traced task; NULL for current cpu. */

	/* The traced task; NULL for current cpu: */
	struct task_struct	*task;
};

@@ -461,8 +479,8 @@ static inline void bts_set(char *base, enum bts_field field, unsigned long val)
 *
 * return: bytes read/written on success; -Eerrno, otherwise
 */
static int bts_read(struct bts_tracer *tracer, const void *at,
		    struct bts_struct *out)
static int
bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
{
	if (!tracer)
		return -EINVAL;
+1 −1
Original line number Diff line number Diff line
@@ -12,4 +12,4 @@ extern int ds_selftest_pebs(void);
#else
static inline int ds_selftest_bts(void) { return 0; }
static inline int ds_selftest_pebs(void) { return 0; }
#endif /* CONFIG_X86_DS_SELFTEST */
#endif
+3 −3
Original line number Diff line number Diff line
/*
 * h/w branch tracer for x86 based on bts
 * h/w branch tracer for x86 based on BTS
 *
 * Copyright (C) 2008-2009 Intel Corporation.
 * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009
@@ -15,8 +15,8 @@

#include <asm/ds.h>

#include "trace.h"
#include "trace_output.h"
#include "trace.h"


#define BTS_BUFFER_SIZE (1 << 13)
@@ -197,10 +197,10 @@ static void bts_trace_print_header(struct seq_file *m)

static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
{
	unsigned long symflags = TRACE_ITER_SYM_OFFSET;
	struct trace_entry *entry = iter->ent;
	struct trace_seq *seq = &iter->seq;
	struct hw_branch_entry *it;
	unsigned long symflags = TRACE_ITER_SYM_OFFSET;

	trace_assign_type(it, entry);

+3 −2
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
#else
# define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; })
#endif /* CONFIG_DYNAMIC_FTRACE */

/*
 * Simple verification test of ftrace function tracer.
 * Enable ftrace, sleep 1/10 second, and then read the trace
@@ -698,10 +699,10 @@ int
trace_selftest_startup_hw_branches(struct tracer *trace,
				   struct trace_array *tr)
{
	unsigned long count;
	int ret;
	struct trace_iterator iter;
	struct tracer tracer;
	unsigned long count;
	int ret;

	if (!trace->open) {
		printk(KERN_CONT "missing open function...");