History

Merge branch 'oprofile-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'oprofile-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: oprofile/x86: fix msr access to reserved counters oprofile/x86: use kzalloc() instead of kmalloc() oprofile/x86: fix perfctr nmi reservation for mulitplexing oprofile/x86: add comment to counter-in-use warning oprofile/x86: warn user if a counter is already active oprofile/x86: implement randomization for IBS periodic op counter oprofile/x86: implement lsfr pseudo-random number generator for IBS oprofile/x86: implement IBS cpuid feature detection oprofile/x86: remove node check in AMD IBS initialization oprofile/x86: remove OPROFILE_IBS config option oprofile: remove EXPERIMENTAL from the config option description oprofile: remove tracing build dependency

Linus Torvalds committed 16 years ago

Commit d25e8db2 parents 642c4c7 cfc9c0b7 files · +200 −124Browse files

Unified · Split

7 files
  1. arch/Kconfig +1 −17
  2. arch/x86/oprofile/nmi_int.c +9 −8
  3. arch/x86/oprofile/op_model_amd.c +158 −86
  4. arch/x86/oprofile/op_model_p4.c +0 −6
  5. arch/x86/oprofile/op_model_ppro.c +11 −6
  6. arch/x86/oprofile/op_x86_model.h +20 −0
  7. init/Kconfig +1 −1
arch/Kconfig+1−17
@@ -3,11 +3,9 @@ · 2 unmodified lines
33 #
44
55 config OPROFILE
6− tristate "OProfile system profiling (EXPERIMENTAL)"
6+ tristate "OProfile system profiling"
77 depends on PROFILING
88 depends on HAVE_OPROFILE
9− depends on TRACING_SUPPORT
10− select TRACING
119 select RING_BUFFER
1210 select RING_BUFFER_ALLOW_SWAP
1311 help
@@ -17,20 +15,6 @@ config OPROFILE · 3 unmodified lines
1715
1816 If unsure, say N.
1917
20−config OPROFILE_IBS
21− bool "OProfile AMD IBS support (EXPERIMENTAL)"
22− default n
23− depends on OPROFILE && SMP && X86
24− help
25− Instruction-Based Sampling (IBS) is a new profiling
26− technique that provides rich, precise program performance
27− information. IBS is introduced by AMD Family10h processors
28− (AMD Opteron Quad-Core processor "Barcelona") to overcome
29− the limitations of conventional performance counter
30− sampling.
31−
32− If unsure, say N.
33−
3418 config OPROFILE_EVENT_MULTIPLEX
3519 bool "OProfile multiplexing support (EXPERIMENTAL)"
3620 default n
arch/x86/oprofile/nmi_int.c+9−8
@@ -159,7 +159,7 @@ static int nmi_setup_mux(void) · 158 unmodified lines
159159
160160 for_each_possible_cpu(i) {
161161 per_cpu(cpu_msrs, i).multiplex =
162− kmalloc(multiplex_size, GFP_KERNEL);
162+ kzalloc(multiplex_size, GFP_KERNEL);
163163 if (!per_cpu(cpu_msrs, i).multiplex)
164164 return 0;
165165 }
@@ -179,7 +179,6 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) · 13 unmodified lines
179179 if (counter_config[i].enabled) {
180180 multiplex[i].saved = -(u64)counter_config[i].count;
181181 } else {
182− multiplex[i].addr = 0;
183182 multiplex[i].saved = 0;
184183 }
185184 }
@@ -189,25 +188,27 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) · 3 unmodified lines
189188
190189 static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs)
191190 {
191+ struct op_msr *counters = msrs->counters;
192192 struct op_msr *multiplex = msrs->multiplex;
193193 int i;
194194
195195 for (i = 0; i < model->num_counters; ++i) {
196196 int virt = op_x86_phys_to_virt(i);
197− if (multiplex[virt].addr)
198− rdmsrl(multiplex[virt].addr, multiplex[virt].saved);
197+ if (counters[i].addr)
198+ rdmsrl(counters[i].addr, multiplex[virt].saved);
199199 }
200200 }
201201
202202 static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs)
203203 {
204+ struct op_msr *counters = msrs->counters;
204205 struct op_msr *multiplex = msrs->multiplex;
205206 int i;
206207
207208 for (i = 0; i < model->num_counters; ++i) {
208209 int virt = op_x86_phys_to_virt(i);
209− if (multiplex[virt].addr)
210− wrmsrl(multiplex[virt].addr, multiplex[virt].saved);
210+ if (counters[i].addr)
211+ wrmsrl(counters[i].addr, multiplex[virt].saved);
211212 }
212213 }
213214
@@ -303,11 +304,11 @@ static int allocate_msrs(void) · 89 unmodified lines
303304
304305 int i;
305306 for_each_possible_cpu(i) {
306− per_cpu(cpu_msrs, i).counters = kmalloc(counters_size,
307+ per_cpu(cpu_msrs, i).counters = kzalloc(counters_size,
307308 GFP_KERNEL);
308309 if (!per_cpu(cpu_msrs, i).counters)
309310 return 0;
310− per_cpu(cpu_msrs, i).controls = kmalloc(controls_size,
311+ per_cpu(cpu_msrs, i).controls = kzalloc(controls_size,
311312 GFP_KERNEL);
312313 if (!per_cpu(cpu_msrs, i).controls)
313314 return 0;
arch/x86/oprofile/op_model_amd.c+158−86
@@ -22,6 +22,9 @@ · 21 unmodified lines
2222 #include <asm/ptrace.h>
2323 #include <asm/msr.h>
2424 #include <asm/nmi.h>
25+#include <asm/apic.h>
26+#include <asm/processor.h>
27+#include <asm/cpufeature.h>
2528
2629 #include "op_x86_model.h"
2730 #include "op_counter.h"
@@ -43,15 +46,13 @@ · 15 unmodified lines
4346
4447 static unsigned long reset_value[NUM_VIRT_COUNTERS];
4548
46−#ifdef CONFIG_OPROFILE_IBS
47−
4849 /* IbsFetchCtl bits/masks */
4950 #define IBS_FETCH_RAND_EN (1ULL<<57)
5051 #define IBS_FETCH_VAL (1ULL<<49)
5152 #define IBS_FETCH_ENABLE (1ULL<<48)
5253 #define IBS_FETCH_CNT_MASK 0xFFFF0000ULL
5354
54−/*IbsOpCtl bits */
55+/* IbsOpCtl bits */
5556 #define IBS_OP_CNT_CTL (1ULL<<19)
5657 #define IBS_OP_VAL (1ULL<<18)
5758 #define IBS_OP_ENABLE (1ULL<<17)
@@ -59,7 +60,7 @@ static unsigned long reset_value[NUM_VIRT_COUNTERS]; · 1 unmodified line
5960 #define IBS_FETCH_SIZE 6
6061 #define IBS_OP_SIZE 12
6162
62−static int has_ibs; /* AMD Family10h and later */
63+static u32 ibs_caps;
6364
6465 struct op_ibs_config {
6566 unsigned long op_enabled;
@@ -71,24 +72,52 @@ struct op_ibs_config { · 5 unmodified lines
7172 };
7273
7374 static struct op_ibs_config ibs_config;
75+static u64 ibs_op_ctl;
7476
75−#endif
77+/*
78+ * IBS cpuid feature detection
79+ */
7680
77−#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
81+#define IBS_CPUID_FEATURES 0x8000001b
82+
83+/*
84+ * Same bit mask as for IBS cpuid feature flags (Fn8000_001B_EAX), but
85+ * bit 0 is used to indicate the existence of IBS.
86+ */
87+#define IBS_CAPS_AVAIL (1LL<<0)
88+#define IBS_CAPS_RDWROPCNT (1LL<<3)
89+#define IBS_CAPS_OPCNT (1LL<<4)
90+
91+/*
92+ * IBS randomization macros
93+ */
94+#define IBS_RANDOM_BITS 12
95+#define IBS_RANDOM_MASK ((1ULL << IBS_RANDOM_BITS) - 1)
96+#define IBS_RANDOM_MAXCNT_OFFSET (1ULL << (IBS_RANDOM_BITS - 5))
7897
79−static void op_mux_fill_in_addresses(struct op_msrs * const msrs)
98+static u32 get_ibs_caps(void)
8099 {
81− int i;
100+ u32 ibs_caps;
101+ unsigned int max_level;
82102
83− for (i = 0; i < NUM_VIRT_COUNTERS; i++) {
84− int hw_counter = op_x86_virt_to_phys(i);
85− if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
86− msrs->multiplex[i].addr = MSR_K7_PERFCTR0 + hw_counter;
87− else
88− msrs->multiplex[i].addr = 0;
89− }
103+ if (!boot_cpu_has(X86_FEATURE_IBS))
104+ return 0;
105+
106+ /* check IBS cpuid feature flags */
107+ max_level = cpuid_eax(0x80000000);
108+ if (max_level < IBS_CPUID_FEATURES)
109+ return IBS_CAPS_AVAIL;
110+
111+ ibs_caps = cpuid_eax(IBS_CPUID_FEATURES);
112+ if (!(ibs_caps & IBS_CAPS_AVAIL))
113+ /* cpuid flags not valid */
114+ return IBS_CAPS_AVAIL;
115+
116+ return ibs_caps;
90117 }
91118
119+#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
120+
92121 static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
93122 struct op_msrs const * const msrs)
94123 {
@@ -98,7 +127,7 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, · 3 unmodified lines
98127 /* enable active counters */
99128 for (i = 0; i < NUM_COUNTERS; ++i) {
100129 int virt = op_x86_phys_to_virt(i);
101− if (!counter_config[virt].enabled)
130+ if (!reset_value[virt])
102131 continue;
103132 rdmsrl(msrs->controls[i].addr, val);
104133 val &= model->reserved;
@@ -107,10 +136,6 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, · 2 unmodified lines
107136 }
108137 }
109138
110−#else
111−
112−static inline void op_mux_fill_in_addresses(struct op_msrs * const msrs) { }
113−
114139 #endif
115140
116141 /* functions for op_amd_spec */
@@ -122,18 +147,12 @@ static void op_amd_fill_in_addresses(struct op_msrs * const msrs) · 5 unmodified lines
122147 for (i = 0; i < NUM_COUNTERS; i++) {
123148 if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
124149 msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
125− else
126− msrs->counters[i].addr = 0;
127150 }
128151
129152 for (i = 0; i < NUM_CONTROLS; i++) {
130153 if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
131154 msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
132− else
133− msrs->controls[i].addr = 0;
134155 }
135−
136− op_mux_fill_in_addresses(msrs);
137156 }
138157
139158 static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
@@ -144,7 +163,8 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, · 4 unmodified lines
144163
145164 /* setup reset_value */
146165 for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
147− if (counter_config[i].enabled)
166+ if (counter_config[i].enabled
167+ && msrs->counters[op_x86_virt_to_phys(i)].addr)
148168 reset_value[i] = counter_config[i].count;
149169 else
150170 reset_value[i] = 0;
@@ -152,9 +172,18 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, · 1 unmodified line
152172
153173 /* clear all counters */
154174 for (i = 0; i < NUM_CONTROLS; ++i) {
155− if (unlikely(!msrs->controls[i].addr))
175+ if (unlikely(!msrs->controls[i].addr)) {
176+ if (counter_config[i].enabled && !smp_processor_id())
177+ /*
178+ * counter is reserved, this is on all
179+ * cpus, so report only for cpu #0
180+ */
181+ op_x86_warn_reserved(i);
156182 continue;
183+ }
157184 rdmsrl(msrs->controls[i].addr, val);
185+ if (val & ARCH_PERFMON_EVENTSEL0_ENABLE)
186+ op_x86_warn_in_use(i);
158187 val &= model->reserved;
159188 wrmsrl(msrs->controls[i].addr, val);
160189 }
@@ -169,9 +198,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, · 8 unmodified lines
169198 /* enable active counters */
170199 for (i = 0; i < NUM_COUNTERS; ++i) {
171200 int virt = op_x86_phys_to_virt(i);
172− if (!counter_config[virt].enabled)
173− continue;
174− if (!msrs->counters[i].addr)
201+ if (!reset_value[virt])
175202 continue;
176203
177204 /* setup counter registers */
@@ -185,7 +212,60 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, · 7 unmodified lines
185212 }
186213 }
187214
188−#ifdef CONFIG_OPROFILE_IBS
215+/*
216+ * 16-bit Linear Feedback Shift Register (LFSR)
217+ *
218+ * 16 14 13 11
219+ * Feedback polynomial = X + X + X + X + 1
220+ */
221+static unsigned int lfsr_random(void)
222+{
223+ static unsigned int lfsr_value = 0xF00D;
224+ unsigned int bit;
225+
226+ /* Compute next bit to shift in */
227+ bit = ((lfsr_value >> 0) ^
228+ (lfsr_value >> 2) ^
229+ (lfsr_value >> 3) ^
230+ (lfsr_value >> 5)) & 0x0001;
231+
232+ /* Advance to next register value */
233+ lfsr_value = (lfsr_value >> 1) | (bit << 15);
234+
235+ return lfsr_value;
236+}
237+
238+/*
239+ * IBS software randomization
240+ *
241+ * The IBS periodic op counter is randomized in software. The lower 12
242+ * bits of the 20 bit counter are randomized. IbsOpCurCnt is
243+ * initialized with a 12 bit random value.
244+ */
245+static inline u64 op_amd_randomize_ibs_op(u64 val)
246+{
247+ unsigned int random = lfsr_random();
248+
249+ if (!(ibs_caps & IBS_CAPS_RDWROPCNT))
250+ /*
251+ * Work around if the hw can not write to IbsOpCurCnt
252+ *
253+ * Randomize the lower 8 bits of the 16 bit
254+ * IbsOpMaxCnt [15:0] value in the range of -128 to
255+ * +127 by adding/subtracting an offset to the
256+ * maximum count (IbsOpMaxCnt).
257+ *
258+ * To avoid over or underflows and protect upper bits
259+ * starting at bit 16, the initial value for
260+ * IbsOpMaxCnt must fit in the range from 0x0081 to
261+ * 0xff80.
262+ */
263+ val += (s8)(random >> 4);
264+ else
265+ val |= (u64)(random & IBS_RANDOM_MASK) << 32;
266+
267+ return val;
268+}
189269
190270 static inline void
191271 op_amd_handle_ibs(struct pt_regs * const regs,
@@ -194,7 +274,7 @@ op_amd_handle_ibs(struct pt_regs * const regs, · 2 unmodified lines
194274 u64 val, ctl;
195275 struct op_entry entry;
196276
197− if (!has_ibs)
277+ if (!ibs_caps)
198278 return;
199279
200280 if (ibs_config.fetch_enabled) {
@@ -236,8 +316,7 @@ op_amd_handle_ibs(struct pt_regs * const regs, · 35 unmodified lines
236316 oprofile_write_commit(&entry);
237317
238318 /* reenable the IRQ */
239− ctl &= ~IBS_OP_VAL & 0xFFFFFFFF;
240− ctl |= IBS_OP_ENABLE;
319+ ctl = op_amd_randomize_ibs_op(ibs_op_ctl);
241320 wrmsrl(MSR_AMD64_IBSOPCTL, ctl);
242321 }
243322 }
@@ -246,41 +325,57 @@ op_amd_handle_ibs(struct pt_regs * const regs, · 2 unmodified lines
246325 static inline void op_amd_start_ibs(void)
247326 {
248327 u64 val;
249− if (has_ibs && ibs_config.fetch_enabled) {
328+
329+ if (!ibs_caps)
330+ return;
331+
332+ if (ibs_config.fetch_enabled) {
250333 val = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF;
251334 val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0;
252335 val |= IBS_FETCH_ENABLE;
253336 wrmsrl(MSR_AMD64_IBSFETCHCTL, val);
254337 }
255338
256− if (has_ibs && ibs_config.op_enabled) {
257− val = (ibs_config.max_cnt_op >> 4) & 0xFFFF;
258− val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0;
259− val |= IBS_OP_ENABLE;
339+ if (ibs_config.op_enabled) {
340+ ibs_op_ctl = ibs_config.max_cnt_op >> 4;
341+ if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) {
342+ /*
343+ * IbsOpCurCnt not supported. See
344+ * op_amd_randomize_ibs_op() for details.
345+ */
346+ ibs_op_ctl = clamp(ibs_op_ctl, 0x0081ULL, 0xFF80ULL);
347+ } else {
348+ /*
349+ * The start value is randomized with a
350+ * positive offset, we need to compensate it
351+ * with the half of the randomized range. Also
352+ * avoid underflows.
353+ */
354+ ibs_op_ctl = min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET,
355+ 0xFFFFULL);
356+ }
357+ if (ibs_caps & IBS_CAPS_OPCNT && ibs_config.dispatched_ops)
358+ ibs_op_ctl |= IBS_OP_CNT_CTL;
359+ ibs_op_ctl |= IBS_OP_ENABLE;
360+ val = op_amd_randomize_ibs_op(ibs_op_ctl);
260361 wrmsrl(MSR_AMD64_IBSOPCTL, val);
261362 }
262363 }
263364
264365 static void op_amd_stop_ibs(void)
265366 {
266− if (has_ibs && ibs_config.fetch_enabled)
367+ if (!ibs_caps)
368+ return;
369+
370+ if (ibs_config.fetch_enabled)
267371 /* clear max count and enable */
268372 wrmsrl(MSR_AMD64_IBSFETCHCTL, 0);
269373
270− if (has_ibs && ibs_config.op_enabled)
374+ if (ibs_config.op_enabled)
271375 /* clear max count and enable */
272376 wrmsrl(MSR_AMD64_IBSOPCTL, 0);
273377 }
274378
275−#else
276−
277−static inline void op_amd_handle_ibs(struct pt_regs * const regs,
278− struct op_msrs const * const msrs) { }
279−static inline void op_amd_start_ibs(void) { }
280−static inline void op_amd_stop_ibs(void) { }
281−
282−#endif
283−
284379 static int op_amd_check_ctrs(struct pt_regs * const regs,
285380 struct op_msrs const * const msrs)
286381 {
@@ -355,8 +450,6 @@ static void op_amd_shutdown(struct op_msrs const * const msrs) · 68 unmodified lines
355450 }
356451 }
357452
358−#ifdef CONFIG_OPROFILE_IBS
359−
360453 static u8 ibs_eilvt_off;
361454
362455 static inline void apic_init_ibs_nmi_per_cpu(void *arg)
@@ -405,45 +498,36 @@ static int init_ibs_nmi(void) · 42 unmodified lines
405498 return 1;
406499 }
407500
408−#ifdef CONFIG_NUMA
409− /* Sanity check */
410− /* Works only for 64bit with proper numa implementation. */
411− if (nodes != num_possible_nodes()) {
412− printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, "
413− "found: %d, expected %d",
414− nodes, num_possible_nodes());
415− return 1;
416− }
417−#endif
418501 return 0;
419502 }
420503
421504 /* uninitialize the APIC for the IBS interrupts if needed */
422505 static void clear_ibs_nmi(void)
423506 {
424− if (has_ibs)
507+ if (ibs_caps)
425508 on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1);
426509 }
427510
428511 /* initialize the APIC for the IBS interrupts if available */
429512 static void ibs_init(void)
430513 {
431− has_ibs = boot_cpu_has(X86_FEATURE_IBS);
514+ ibs_caps = get_ibs_caps();
432515
433− if (!has_ibs)
516+ if (!ibs_caps)
434517 return;
435518
436519 if (init_ibs_nmi()) {
437− has_ibs = 0;
520+ ibs_caps = 0;
438521 return;
439522 }
440523
441− printk(KERN_INFO "oprofile: AMD IBS detected\n");
524+ printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n",
525+ (unsigned)ibs_caps);
442526 }
443527
444528 static void ibs_exit(void)
445529 {
446− if (!has_ibs)
530+ if (!ibs_caps)
447531 return;
448532
449533 clear_ibs_nmi();
@@ -463,7 +547,7 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root) · 13 unmodified lines
463547 if (ret)
464548 return ret;
465549
466− if (!has_ibs)
550+ if (!ibs_caps)
467551 return ret;
468552
469553 /* model specific files */
@@ -473,7 +557,7 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root) · 3 unmodified lines
473557 ibs_config.fetch_enabled = 0;
474558 ibs_config.max_cnt_op = 250000;
475559 ibs_config.op_enabled = 0;
476− ibs_config.dispatched_ops = 1;
560+ ibs_config.dispatched_ops = 0;
477561
478562 dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
479563 oprofilefs_create_ulong(sb, dir, "enable",
@@ -488,8 +572,9 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root) · 8 unmodified lines
488572 &ibs_config.op_enabled);
489573 oprofilefs_create_ulong(sb, dir, "max_count",
490574 &ibs_config.max_cnt_op);
491− oprofilefs_create_ulong(sb, dir, "dispatched_ops",
492− &ibs_config.dispatched_ops);
575+ if (ibs_caps & IBS_CAPS_OPCNT)
576+ oprofilefs_create_ulong(sb, dir, "dispatched_ops",
577+ &ibs_config.dispatched_ops);
493578
494579 return 0;
495580 }
@@ -507,19 +592,6 @@ static void op_amd_exit(void) · 11 unmodified lines
507592 ibs_exit();
508593 }
509594
510−#else
511−
512−/* no IBS support */
513−
514−static int op_amd_init(struct oprofile_operations *ops)
515−{
516− return 0;
517−}
518−
519−static void op_amd_exit(void) {}
520−
521−#endif /* CONFIG_OPROFILE_IBS */
522−
523595 struct op_x86_model_spec op_amd_spec = {
524596 .num_counters = NUM_COUNTERS,
525597 .num_controls = NUM_CONTROLS,
arch/x86/oprofile/op_model_p4.c+0−6
@@ -394,12 +394,6 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) · 393 unmodified lines
394394 setup_num_counters();
395395 stag = get_stagger();
396396
397− /* initialize some registers */
398− for (i = 0; i < num_counters; ++i)
399− msrs->counters[i].addr = 0;
400− for (i = 0; i < num_controls; ++i)
401− msrs->controls[i].addr = 0;
402−
403397 /* the counter & cccr registers we pay attention to */
404398 for (i = 0; i < num_counters; ++i) {
405399 addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
arch/x86/oprofile/op_model_ppro.c+11−6
@@ -37,15 +37,11 @@ static void ppro_fill_in_addresses(struct op_msrs * const msrs) · 36 unmodified lines
3737 for (i = 0; i < num_counters; i++) {
3838 if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
3939 msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
40− else
41− msrs->counters[i].addr = 0;
4240 }
4341
4442 for (i = 0; i < num_counters; i++) {
4543 if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i))
4644 msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
47− else
48− msrs->controls[i].addr = 0;
4945 }
5046 }
5147
@@ -57,7 +53,7 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, · 5 unmodified lines
5753 int i;
5854
5955 if (!reset_value) {
60− reset_value = kmalloc(sizeof(reset_value[0]) * num_counters,
56+ reset_value = kzalloc(sizeof(reset_value[0]) * num_counters,
6157 GFP_ATOMIC);
6258 if (!reset_value)
6359 return;
@@ -82,9 +78,18 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, · 18 unmodified lines
8278
8379 /* clear all counters */
8480 for (i = 0; i < num_counters; ++i) {
85− if (unlikely(!msrs->controls[i].addr))
81+ if (unlikely(!msrs->controls[i].addr)) {
82+ if (counter_config[i].enabled && !smp_processor_id())
83+ /*
84+ * counter is reserved, this is on all
85+ * cpus, so report only for cpu #0
86+ */
87+ op_x86_warn_reserved(i);
8688 continue;
89+ }
8790 rdmsrl(msrs->controls[i].addr, val);
91+ if (val & ARCH_PERFMON_EVENTSEL0_ENABLE)
92+ op_x86_warn_in_use(i);
8893 val &= model->reserved;
8994 wrmsrl(msrs->controls[i].addr, val);
9095 }
arch/x86/oprofile/op_x86_model.h+20−0
@@ -57,6 +57,26 @@ struct op_x86_model_spec { · 56 unmodified lines
5757
5858 struct op_counter_config;
5959
60+static inline void op_x86_warn_in_use(int counter)
61+{
62+ /*
63+ * The warning indicates an already running counter. If
64+ * oprofile doesn't collect data, then try using a different
65+ * performance counter on your platform to monitor the desired
66+ * event. Delete counter #%d from the desired event by editing
67+ * the /usr/share/oprofile/%s/<cpu>/events file. If the event
68+ * cannot be monitored by any other counter, contact your
69+ * hardware or BIOS vendor.
70+ */
71+ pr_warning("oprofile: counter #%d on cpu #%d may already be used\n",
72+ counter, smp_processor_id());
73+}
74+
75+static inline void op_x86_warn_reserved(int counter)
76+{
77+ pr_warning("oprofile: counter #%d is already reserved\n", counter);
78+}
79+
6080 extern u64 op_x86_get_ctrl(struct op_x86_model_spec const *model,
6181 struct op_counter_config *counter_config);
6282 extern int op_x86_phys_to_virt(int phys);
init/Kconfig+1−1
@@ -1128,7 +1128,7 @@ config MMAP_ALLOW_UNINITIALIZED · 1127 unmodified lines
11281128 See Documentation/nommu-mmap.txt for more information.
11291129
11301130 config PROFILING
1131− bool "Profiling support (EXPERIMENTAL)"
1131+ bool "Profiling support"
11321132 help
11331133 Say Y here to enable the extended profiling support mechanisms used
11341134 by profilers such as OProfile.