Commit e9a22d1fb94050b7d600019c32e6b672d539054b
1 parent
321bb5e1ac
Exists in
master
and in
7 other branches
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: Ingo Molnar <mingo@elte.hu>
Showing 4 changed files with 87 additions and 68 deletions Side-by-side Diff
arch/x86/kernel/ds.c
... | ... | @@ -19,44 +19,53 @@ |
19 | 19 | * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009 |
20 | 20 | */ |
21 | 21 | |
22 | - | |
23 | -#include <asm/ds.h> | |
24 | - | |
25 | -#include <linux/errno.h> | |
22 | +#include <linux/kernel.h> | |
26 | 23 | #include <linux/string.h> |
27 | -#include <linux/slab.h> | |
24 | +#include <linux/errno.h> | |
28 | 25 | #include <linux/sched.h> |
26 | +#include <linux/slab.h> | |
29 | 27 | #include <linux/mm.h> |
30 | -#include <linux/kernel.h> | |
31 | 28 | |
29 | +#include <asm/ds.h> | |
30 | + | |
32 | 31 | #include "ds_selftest.h" |
33 | 32 | |
34 | 33 | /* |
35 | - * The configuration for a particular DS hardware implementation. | |
34 | + * The configuration for a particular DS hardware implementation: | |
36 | 35 | */ |
37 | 36 | struct ds_configuration { |
38 | - /* The name of the configuration. */ | |
39 | - const char *name; | |
40 | - /* The size of pointer-typed fields in DS, BTS, and PEBS. */ | |
41 | - unsigned char sizeof_ptr_field; | |
42 | - /* The size of a BTS/PEBS record in bytes. */ | |
43 | - unsigned char sizeof_rec[2]; | |
44 | - /* Control bit-masks indexed by enum ds_feature. */ | |
45 | - unsigned long ctl[dsf_ctl_max]; | |
37 | + /* The name of the configuration: */ | |
38 | + const char *name; | |
39 | + | |
40 | + /* The size of pointer-typed fields in DS, BTS, and PEBS: */ | |
41 | + unsigned char sizeof_ptr_field; | |
42 | + | |
43 | + /* The size of a BTS/PEBS record in bytes: */ | |
44 | + unsigned char sizeof_rec[2]; | |
45 | + | |
46 | + /* Control bit-masks indexed by enum ds_feature: */ | |
47 | + unsigned long ctl[dsf_ctl_max]; | |
46 | 48 | }; |
47 | 49 | static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array); |
48 | 50 | |
49 | 51 | #define ds_cfg per_cpu(ds_cfg_array, smp_processor_id()) |
50 | 52 | |
51 | -#define MAX_SIZEOF_DS (12 * 8) /* Maximal size of a DS configuration. */ | |
52 | -#define MAX_SIZEOF_BTS (3 * 8) /* Maximal size of a BTS record. */ | |
53 | -#define DS_ALIGNMENT (1 << 3) /* BTS and PEBS buffer alignment. */ | |
53 | +/* Maximal size of a DS configuration: */ | |
54 | +#define MAX_SIZEOF_DS (12 * 8) | |
54 | 55 | |
55 | -#define BTS_CONTROL \ | |
56 | - (ds_cfg.ctl[dsf_bts] | ds_cfg.ctl[dsf_bts_kernel] | ds_cfg.ctl[dsf_bts_user] |\ | |
57 | - ds_cfg.ctl[dsf_bts_overflow]) | |
56 | +/* Maximal size of a BTS record: */ | |
57 | +#define MAX_SIZEOF_BTS (3 * 8) | |
58 | 58 | |
59 | +/* BTS and PEBS buffer alignment: */ | |
60 | +#define DS_ALIGNMENT (1 << 3) | |
59 | 61 | |
62 | +/* Mask of control bits in the DS MSR register: */ | |
63 | +#define BTS_CONTROL \ | |
64 | + ( ds_cfg.ctl[dsf_bts] | \ | |
65 | + ds_cfg.ctl[dsf_bts_kernel] | \ | |
66 | + ds_cfg.ctl[dsf_bts_user] | \ | |
67 | + ds_cfg.ctl[dsf_bts_overflow] ) | |
68 | + | |
60 | 69 | /* |
61 | 70 | * A BTS or PEBS tracer. |
62 | 71 | * |
63 | 72 | |
64 | 73 | |
65 | 74 | |
... | ... | @@ -65,28 +74,32 @@ |
65 | 74 | */ |
66 | 75 | struct ds_tracer { |
67 | 76 | /* The DS context (partially) owned by this tracer. */ |
68 | - struct ds_context *context; | |
77 | + struct ds_context *context; | |
69 | 78 | /* The buffer provided on ds_request() and its size in bytes. */ |
70 | - void *buffer; | |
71 | - size_t size; | |
79 | + void *buffer; | |
80 | + size_t size; | |
72 | 81 | }; |
73 | 82 | |
74 | 83 | struct bts_tracer { |
75 | - /* The common DS part. */ | |
76 | - struct ds_tracer ds; | |
77 | - /* The trace including the DS configuration. */ | |
78 | - struct bts_trace trace; | |
79 | - /* Buffer overflow notification function. */ | |
80 | - bts_ovfl_callback_t ovfl; | |
84 | + /* The common DS part: */ | |
85 | + struct ds_tracer ds; | |
86 | + | |
87 | + /* The trace including the DS configuration: */ | |
88 | + struct bts_trace trace; | |
89 | + | |
90 | + /* Buffer overflow notification function: */ | |
91 | + bts_ovfl_callback_t ovfl; | |
81 | 92 | }; |
82 | 93 | |
83 | 94 | struct pebs_tracer { |
84 | - /* The common DS part. */ | |
85 | - struct ds_tracer ds; | |
86 | - /* The trace including the DS configuration. */ | |
87 | - struct pebs_trace trace; | |
88 | - /* Buffer overflow notification function. */ | |
89 | - pebs_ovfl_callback_t ovfl; | |
95 | + /* The common DS part: */ | |
96 | + struct ds_tracer ds; | |
97 | + | |
98 | + /* The trace including the DS configuration: */ | |
99 | + struct pebs_trace trace; | |
100 | + | |
101 | + /* Buffer overflow notification function: */ | |
102 | + pebs_ovfl_callback_t ovfl; | |
90 | 103 | }; |
91 | 104 | |
92 | 105 | /* |
... | ... | @@ -95,6 +108,7 @@ |
95 | 108 | * |
96 | 109 | * The DS configuration consists of the following fields; different |
97 | 110 | * architetures vary in the size of those fields. |
111 | + * | |
98 | 112 | * - double-word aligned base linear address of the BTS buffer |
99 | 113 | * - write pointer into the BTS buffer |
100 | 114 | * - end linear address of the BTS buffer (one byte beyond the end of |
101 | 115 | |
102 | 116 | |
... | ... | @@ -133,19 +147,20 @@ |
133 | 147 | }; |
134 | 148 | |
135 | 149 | enum ds_qualifier { |
136 | - ds_bts = 0, | |
150 | + ds_bts = 0, | |
137 | 151 | ds_pebs |
138 | 152 | }; |
139 | 153 | |
140 | -static inline unsigned long ds_get(const unsigned char *base, | |
141 | - enum ds_qualifier qual, enum ds_field field) | |
154 | +static inline unsigned long | |
155 | +ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field) | |
142 | 156 | { |
143 | 157 | base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual))); |
144 | 158 | return *(unsigned long *)base; |
145 | 159 | } |
146 | 160 | |
147 | -static inline void ds_set(unsigned char *base, enum ds_qualifier qual, | |
148 | - enum ds_field field, unsigned long value) | |
161 | +static inline void | |
162 | +ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field, | |
163 | + unsigned long value) | |
149 | 164 | { |
150 | 165 | base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual))); |
151 | 166 | (*(unsigned long *)base) = value; |
... | ... | @@ -157,7 +172,6 @@ |
157 | 172 | */ |
158 | 173 | static DEFINE_SPINLOCK(ds_lock); |
159 | 174 | |
160 | - | |
161 | 175 | /* |
162 | 176 | * We either support (system-wide) per-cpu or per-thread allocation. |
163 | 177 | * We distinguish the two based on the task_struct pointer, where a |
164 | 178 | |
... | ... | @@ -211,17 +225,21 @@ |
211 | 225 | * deallocated when the last user puts the context. |
212 | 226 | */ |
213 | 227 | struct ds_context { |
214 | - /* The DS configuration; goes into MSR_IA32_DS_AREA. */ | |
215 | - unsigned char ds[MAX_SIZEOF_DS]; | |
216 | - /* The owner of the BTS and PEBS configuration, respectively. */ | |
217 | - struct bts_tracer *bts_master; | |
218 | - struct pebs_tracer *pebs_master; | |
219 | - /* Use count. */ | |
228 | + /* The DS configuration; goes into MSR_IA32_DS_AREA: */ | |
229 | + unsigned char ds[MAX_SIZEOF_DS]; | |
230 | + | |
231 | + /* The owner of the BTS and PEBS configuration, respectively: */ | |
232 | + struct bts_tracer *bts_master; | |
233 | + struct pebs_tracer *pebs_master; | |
234 | + | |
235 | + /* Use count: */ | |
220 | 236 | unsigned long count; |
221 | - /* Pointer to the context pointer field. */ | |
222 | - struct ds_context **this; | |
223 | - /* The traced task; NULL for current cpu. */ | |
224 | - struct task_struct *task; | |
237 | + | |
238 | + /* Pointer to the context pointer field: */ | |
239 | + struct ds_context **this; | |
240 | + | |
241 | + /* The traced task; NULL for current cpu: */ | |
242 | + struct task_struct *task; | |
225 | 243 | }; |
226 | 244 | |
227 | 245 | static DEFINE_PER_CPU(struct ds_context *, system_context_array); |
... | ... | @@ -328,9 +346,9 @@ |
328 | 346 | * The remainder of any partially written record is zeroed out. |
329 | 347 | * |
330 | 348 | * context: the DS context |
331 | - * qual: the buffer type | |
332 | - * record: the data to write | |
333 | - * size: the size of the data | |
349 | + * qual: the buffer type | |
350 | + * record: the data to write | |
351 | + * size: the size of the data | |
334 | 352 | */ |
335 | 353 | static int ds_write(struct ds_context *context, enum ds_qualifier qual, |
336 | 354 | const void *record, size_t size) |
337 | 355 | |
... | ... | @@ -429,12 +447,12 @@ |
429 | 447 | bts_to, |
430 | 448 | bts_flags, |
431 | 449 | |
432 | - bts_qual = bts_from, | |
433 | - bts_jiffies = bts_to, | |
434 | - bts_pid = bts_flags, | |
450 | + bts_qual = bts_from, | |
451 | + bts_jiffies = bts_to, | |
452 | + bts_pid = bts_flags, | |
435 | 453 | |
436 | - bts_qual_mask = (bts_qual_max - 1), | |
437 | - bts_escape = ((unsigned long)-1 & ~bts_qual_mask) | |
454 | + bts_qual_mask = (bts_qual_max - 1), | |
455 | + bts_escape = ((unsigned long)-1 & ~bts_qual_mask) | |
438 | 456 | }; |
439 | 457 | |
440 | 458 | static inline unsigned long bts_get(const char *base, enum bts_field field) |
... | ... | @@ -461,8 +479,8 @@ |
461 | 479 | * |
462 | 480 | * return: bytes read/written on success; -Eerrno, otherwise |
463 | 481 | */ |
464 | -static int bts_read(struct bts_tracer *tracer, const void *at, | |
465 | - struct bts_struct *out) | |
482 | +static int | |
483 | +bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out) | |
466 | 484 | { |
467 | 485 | if (!tracer) |
468 | 486 | return -EINVAL; |
arch/x86/kernel/ds_selftest.h
kernel/trace/trace_hw_branches.c
1 | 1 | /* |
2 | - * h/w branch tracer for x86 based on bts | |
2 | + * h/w branch tracer for x86 based on BTS | |
3 | 3 | * |
4 | 4 | * Copyright (C) 2008-2009 Intel Corporation. |
5 | 5 | * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009 |
6 | 6 | |
... | ... | @@ -15,8 +15,8 @@ |
15 | 15 | |
16 | 16 | #include <asm/ds.h> |
17 | 17 | |
18 | -#include "trace.h" | |
19 | 18 | #include "trace_output.h" |
19 | +#include "trace.h" | |
20 | 20 | |
21 | 21 | |
22 | 22 | #define BTS_BUFFER_SIZE (1 << 13) |
23 | 23 | |
... | ... | @@ -197,10 +197,10 @@ |
197 | 197 | |
198 | 198 | static enum print_line_t bts_trace_print_line(struct trace_iterator *iter) |
199 | 199 | { |
200 | + unsigned long symflags = TRACE_ITER_SYM_OFFSET; | |
200 | 201 | struct trace_entry *entry = iter->ent; |
201 | 202 | struct trace_seq *seq = &iter->seq; |
202 | 203 | struct hw_branch_entry *it; |
203 | - unsigned long symflags = TRACE_ITER_SYM_OFFSET; | |
204 | 204 | |
205 | 205 | trace_assign_type(it, entry); |
206 | 206 |
kernel/trace/trace_selftest.c
... | ... | @@ -189,6 +189,7 @@ |
189 | 189 | #else |
190 | 190 | # define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; }) |
191 | 191 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
192 | + | |
192 | 193 | /* |
193 | 194 | * Simple verification test of ftrace function tracer. |
194 | 195 | * Enable ftrace, sleep 1/10 second, and then read the trace |
195 | 196 | |
... | ... | @@ -698,10 +699,10 @@ |
698 | 699 | trace_selftest_startup_hw_branches(struct tracer *trace, |
699 | 700 | struct trace_array *tr) |
700 | 701 | { |
701 | - unsigned long count; | |
702 | - int ret; | |
703 | 702 | struct trace_iterator iter; |
704 | 703 | struct tracer tracer; |
704 | + unsigned long count; | |
705 | + int ret; | |
705 | 706 | |
706 | 707 | if (!trace->open) { |
707 | 708 | printk(KERN_CONT "missing open function..."); |