aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig14
-rw-r--r--arch/x86/oprofile/op_model_athlon.c33
2 files changed, 37 insertions, 10 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index b0fabfa864ff..2651af48b2e5 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -13,6 +13,20 @@ config OPROFILE
13 13
14 If unsure, say N. 14 If unsure, say N.
15 15
16config OPROFILE_IBS
17 bool "OProfile AMD IBS support (EXPERIMENTAL)"
18 default n
19 depends on OPROFILE && SMP && X86
20 help
21 Instruction-Based Sampling (IBS) is a new profiling
22 technique that provides rich, precise program performance
23 information. IBS is introduced by AMD Family10h processors
24 (AMD Opteron Quad-Core processor “Barcelona”) to overcome
25 the limitations of conventional performance counter
26 sampling.
27
28 If unsure, say N.
29
16config HAVE_OPROFILE 30config HAVE_OPROFILE
17 def_bool n 31 def_bool n
18 32
diff --git a/arch/x86/oprofile/op_model_athlon.c b/arch/x86/oprofile/op_model_athlon.c
index 9c8c8c583132..fb6015c1132b 100644
--- a/arch/x86/oprofile/op_model_athlon.c
+++ b/arch/x86/oprofile/op_model_athlon.c
@@ -47,6 +47,10 @@
47#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9)) 47#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9))
48#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8)) 48#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8))
49 49
50static unsigned long reset_value[NUM_COUNTERS];
51
52#ifdef CONFIG_OPROFILE_IBS
53
50/* IbsFetchCtl bits/masks */ 54/* IbsFetchCtl bits/masks */
51#define IBS_FETCH_HIGH_VALID_BIT (1UL << 17) /* bit 49 */ 55#define IBS_FETCH_HIGH_VALID_BIT (1UL << 17) /* bit 49 */
52#define IBS_FETCH_HIGH_ENABLE (1UL << 16) /* bit 48 */ 56#define IBS_FETCH_HIGH_ENABLE (1UL << 16) /* bit 48 */
@@ -104,7 +108,6 @@ struct ibs_op_sample {
104*/ 108*/
105static void clear_ibs_nmi(void); 109static void clear_ibs_nmi(void);
106 110
107static unsigned long reset_value[NUM_COUNTERS];
108static int ibs_allowed; /* AMD Family10h and later */ 111static int ibs_allowed; /* AMD Family10h and later */
109 112
110struct op_ibs_config { 113struct op_ibs_config {
@@ -118,6 +121,8 @@ struct op_ibs_config {
118 121
119static struct op_ibs_config ibs_config; 122static struct op_ibs_config ibs_config;
120 123
124#endif
125
121/* functions for op_amd_spec */ 126/* functions for op_amd_spec */
122 127
123static void op_amd_fill_in_addresses(struct op_msrs * const msrs) 128static void op_amd_fill_in_addresses(struct op_msrs * const msrs)
@@ -188,6 +193,8 @@ static void op_amd_setup_ctrs(struct op_msrs const * const msrs)
188 } 193 }
189} 194}
190 195
196#ifdef CONFIG_OPROFILE_IBS
197
191static inline int 198static inline int
192op_amd_handle_ibs(struct pt_regs * const regs, 199op_amd_handle_ibs(struct pt_regs * const regs,
193 struct op_msrs const * const msrs) 200 struct op_msrs const * const msrs)
@@ -261,6 +268,8 @@ op_amd_handle_ibs(struct pt_regs * const regs,
261 return 1; 268 return 1;
262} 269}
263 270
271#endif
272
264static int op_amd_check_ctrs(struct pt_regs * const regs, 273static int op_amd_check_ctrs(struct pt_regs * const regs,
265 struct op_msrs const * const msrs) 274 struct op_msrs const * const msrs)
266{ 275{
@@ -277,7 +286,9 @@ static int op_amd_check_ctrs(struct pt_regs * const regs,
277 } 286 }
278 } 287 }
279 288
289#ifdef CONFIG_OPROFILE_IBS
280 op_amd_handle_ibs(regs, msrs); 290 op_amd_handle_ibs(regs, msrs);
291#endif
281 292
282 /* See op_model_ppro.c */ 293 /* See op_model_ppro.c */
283 return 1; 294 return 1;
@@ -294,6 +305,8 @@ static void op_amd_start(struct op_msrs const * const msrs)
294 CTRL_WRITE(low, high, msrs, i); 305 CTRL_WRITE(low, high, msrs, i);
295 } 306 }
296 } 307 }
308
309#ifdef CONFIG_OPROFILE_IBS
297 if (ibs_allowed && ibs_config.fetch_enabled) { 310 if (ibs_allowed && ibs_config.fetch_enabled) {
298 low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; 311 low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF;
299 high = IBS_FETCH_HIGH_ENABLE; 312 high = IBS_FETCH_HIGH_ENABLE;
@@ -305,6 +318,7 @@ static void op_amd_start(struct op_msrs const * const msrs)
305 high = 0; 318 high = 0;
306 wrmsr(MSR_AMD64_IBSOPCTL, low, high); 319 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
307 } 320 }
321#endif
308} 322}
309 323
310 324
@@ -323,6 +337,7 @@ static void op_amd_stop(struct op_msrs const * const msrs)
323 CTRL_WRITE(low, high, msrs, i); 337 CTRL_WRITE(low, high, msrs, i);
324 } 338 }
325 339
340#ifdef CONFIG_OPROFILE_IBS
326 if (ibs_allowed && ibs_config.fetch_enabled) { 341 if (ibs_allowed && ibs_config.fetch_enabled) {
327 low = 0; /* clear max count and enable */ 342 low = 0; /* clear max count and enable */
328 high = 0; 343 high = 0;
@@ -334,6 +349,7 @@ static void op_amd_stop(struct op_msrs const * const msrs)
334 high = 0; 349 high = 0;
335 wrmsr(MSR_AMD64_IBSOPCTL, low, high); 350 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
336 } 351 }
352#endif
337} 353}
338 354
339static void op_amd_shutdown(struct op_msrs const * const msrs) 355static void op_amd_shutdown(struct op_msrs const * const msrs)
@@ -350,17 +366,10 @@ static void op_amd_shutdown(struct op_msrs const * const msrs)
350 } 366 }
351} 367}
352 368
353#ifndef CONFIG_SMP 369#ifndef CONFIG_OPROFILE_IBS
354 370
355/* no IBS support */ 371/* no IBS support */
356 372
357static void setup_ibs(void)
358{
359 ibs_allowed = 0;
360}
361
362static void clear_ibs_nmi(void) {}
363
364static int op_amd_init(struct oprofile_operations *ops) 373static int op_amd_init(struct oprofile_operations *ops)
365{ 374{
366 return 0; 375 return 0;
@@ -441,8 +450,12 @@ static void setup_ibs(void)
441 if (!ibs_allowed) 450 if (!ibs_allowed)
442 return; 451 return;
443 452
444 if (pfm_amd64_setup_eilvt()) 453 if (pfm_amd64_setup_eilvt()) {
445 ibs_allowed = 0; 454 ibs_allowed = 0;
455 return;
456 }
457
458 printk(KERN_INFO "oprofile: AMD IBS detected\n");
446} 459}
447 460
448 461