diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:05:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:05:40 -0400 |
commit | 92fb83afd6664a6f8a05f990d264c998f9b99f69 (patch) | |
tree | b5c65f2a14d1019d8e00d94dafbc65696906455c | |
parent | a5344876065e047d507800d0801a637d68d3b129 (diff) | |
parent | df13b31c286b3e91c556167954eda088d90a4295 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile: (21 commits)
OProfile: Fix buffer synchronization for IBS
oprofile: hotplug cpu fix
oprofile: fixing whitespaces in arch/x86/oprofile/*
oprofile: fixing whitespaces in arch/x86/oprofile/*
oprofile: fixing whitespaces in drivers/oprofile/*
x86/oprofile: add the logic for enabling additional IBS bits
x86/oprofile: reordering functions in nmi_int.c
x86/oprofile: removing unused function parameter in add_ibs_begin()
oprofile: more whitespace fixes
oprofile: whitespace fixes
OProfile: Rename IBS sysfs dir into "ibs_op"
OProfile: Rework string handling in setup_ibs_files()
OProfile: Rework oprofile_add_ibs_sample() function
oprofile: discover counters for op ppro too
oprofile: Implement Intel architectural perfmon support
oprofile: Don't report Nehalem as core_2
oprofile: drop const in num counters field
Revert "Oprofile Multiplexing Patch"
x86, oprofile: BUG: using smp_processor_id() in preemptible code
x86/oprofile: fix on_each_cpu build error
...
Manually fixed trivial conflicts in
drivers/oprofile/{cpu_buffer.c,event_buffer.h}
31 files changed, 431 insertions, 371 deletions
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c index 7c3d5ec6ec67..bd8ac533a504 100644 --- a/arch/alpha/oprofile/common.c +++ b/arch/alpha/oprofile/common.c | |||
@@ -106,7 +106,7 @@ op_axp_stop(void) | |||
106 | } | 106 | } |
107 | 107 | ||
108 | static int | 108 | static int |
109 | op_axp_create_files(struct super_block * sb, struct dentry * root) | 109 | op_axp_create_files(struct super_block *sb, struct dentry *root) |
110 | { | 110 | { |
111 | int i; | 111 | int i; |
112 | 112 | ||
diff --git a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c index 125a602a660d..31b545c35460 100644 --- a/arch/ia64/oprofile/init.c +++ b/arch/ia64/oprofile/init.c | |||
@@ -12,11 +12,11 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | 14 | ||
15 | extern int perfmon_init(struct oprofile_operations * ops); | 15 | extern int perfmon_init(struct oprofile_operations *ops); |
16 | extern void perfmon_exit(void); | 16 | extern void perfmon_exit(void); |
17 | extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth); | 17 | extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth); |
18 | 18 | ||
19 | int __init oprofile_arch_init(struct oprofile_operations * ops) | 19 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
20 | { | 20 | { |
21 | int ret = -ENODEV; | 21 | int ret = -ENODEV; |
22 | 22 | ||
diff --git a/arch/ia64/oprofile/perfmon.c b/arch/ia64/oprofile/perfmon.c index bc41dd32fec6..192d3e8e1f65 100644 --- a/arch/ia64/oprofile/perfmon.c +++ b/arch/ia64/oprofile/perfmon.c | |||
@@ -56,7 +56,7 @@ static pfm_buffer_fmt_t oprofile_fmt = { | |||
56 | }; | 56 | }; |
57 | 57 | ||
58 | 58 | ||
59 | static char * get_cpu_type(void) | 59 | static char *get_cpu_type(void) |
60 | { | 60 | { |
61 | __u8 family = local_cpu_data->family; | 61 | __u8 family = local_cpu_data->family; |
62 | 62 | ||
@@ -75,7 +75,7 @@ static char * get_cpu_type(void) | |||
75 | 75 | ||
76 | static int using_perfmon; | 76 | static int using_perfmon; |
77 | 77 | ||
78 | int perfmon_init(struct oprofile_operations * ops) | 78 | int perfmon_init(struct oprofile_operations *ops) |
79 | { | 79 | { |
80 | int ret = pfm_register_buffer_fmt(&oprofile_fmt); | 80 | int ret = pfm_register_buffer_fmt(&oprofile_fmt); |
81 | if (ret) | 81 | if (ret) |
diff --git a/arch/m32r/oprofile/init.c b/arch/m32r/oprofile/init.c index b7773e45c43f..fa56860f4258 100644 --- a/arch/m32r/oprofile/init.c +++ b/arch/m32r/oprofile/init.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | 14 | ||
15 | int __init oprofile_arch_init(struct oprofile_operations * ops) | 15 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
16 | { | 16 | { |
17 | return -ENODEV; | 17 | return -ENODEV; |
18 | } | 18 | } |
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index dd2fbd6645c1..3bf3354547f6 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
@@ -32,7 +32,7 @@ static int op_mips_setup(void) | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | static int op_mips_create_files(struct super_block * sb, struct dentry * root) | 35 | static int op_mips_create_files(struct super_block *sb, struct dentry *root) |
36 | { | 36 | { |
37 | int i; | 37 | int i; |
38 | 38 | ||
diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h index 2bfc17c30106..f04b54fb37d1 100644 --- a/arch/mips/oprofile/op_impl.h +++ b/arch/mips/oprofile/op_impl.h | |||
@@ -27,7 +27,7 @@ struct op_counter_config { | |||
27 | /* Per-architecture configury and hooks. */ | 27 | /* Per-architecture configury and hooks. */ |
28 | struct op_mips_model { | 28 | struct op_mips_model { |
29 | void (*reg_setup) (struct op_counter_config *); | 29 | void (*reg_setup) (struct op_counter_config *); |
30 | void (*cpu_setup) (void * dummy); | 30 | void (*cpu_setup) (void *dummy); |
31 | int (*init)(void); | 31 | int (*init)(void); |
32 | void (*exit)(void); | 32 | void (*exit)(void); |
33 | void (*cpu_start)(void *args); | 33 | void (*cpu_start)(void *args); |
diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c index a45d3202894f..3aa81384966d 100644 --- a/arch/mips/oprofile/op_model_rm9000.c +++ b/arch/mips/oprofile/op_model_rm9000.c | |||
@@ -80,7 +80,7 @@ static void rm9000_cpu_stop(void *args) | |||
80 | write_c0_perfcontrol(0); | 80 | write_c0_perfcontrol(0); |
81 | } | 81 | } |
82 | 82 | ||
83 | static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id) | 83 | static irqreturn_t rm9000_perfcount_handler(int irq, void *dev_id) |
84 | { | 84 | { |
85 | unsigned int control = read_c0_perfcontrol(); | 85 | unsigned int control = read_c0_perfcontrol(); |
86 | struct pt_regs *regs = get_irq_regs(); | 86 | struct pt_regs *regs = get_irq_regs(); |
diff --git a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c index 113f5139f551..026cba2af07a 100644 --- a/arch/parisc/oprofile/init.c +++ b/arch/parisc/oprofile/init.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/oprofile.h> | 13 | #include <linux/oprofile.h> |
14 | 14 | ||
15 | int __init oprofile_arch_init(struct oprofile_operations * ops) | 15 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
16 | { | 16 | { |
17 | return -ENODEV; | 17 | return -ENODEV; |
18 | } | 18 | } |
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 5ff4de3eb3be..35141a8bc3d9 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c | |||
@@ -404,7 +404,7 @@ set_count_mode(u32 kernel, u32 user) | |||
404 | } | 404 | } |
405 | } | 405 | } |
406 | 406 | ||
407 | static inline void enable_ctr(u32 cpu, u32 ctr, u32 * pm07_cntrl) | 407 | static inline void enable_ctr(u32 cpu, u32 ctr, u32 *pm07_cntrl) |
408 | { | 408 | { |
409 | 409 | ||
410 | pm07_cntrl[ctr] |= CBE_PM_CTR_ENABLE; | 410 | pm07_cntrl[ctr] |= CBE_PM_CTR_ENABLE; |
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c index 9ab815b95b5a..17bb6035069b 100644 --- a/arch/sparc/oprofile/init.c +++ b/arch/sparc/oprofile/init.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | 14 | ||
15 | int __init oprofile_arch_init(struct oprofile_operations * ops) | 15 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
16 | { | 16 | { |
17 | return -ENODEV; | 17 | return -ENODEV; |
18 | } | 18 | } |
diff --git a/arch/sparc64/oprofile/init.c b/arch/sparc64/oprofile/init.c index 9ab815b95b5a..17bb6035069b 100644 --- a/arch/sparc64/oprofile/init.c +++ b/arch/sparc64/oprofile/init.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | 14 | ||
15 | int __init oprofile_arch_init(struct oprofile_operations * ops) | 15 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
16 | { | 16 | { |
17 | return -ENODEV; | 17 | return -ENODEV; |
18 | } | 18 | } |
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index e2095cba409f..04df67f8a7ba 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c | |||
@@ -52,8 +52,7 @@ struct frame_head { | |||
52 | unsigned long ret; | 52 | unsigned long ret; |
53 | } __attribute__((packed)); | 53 | } __attribute__((packed)); |
54 | 54 | ||
55 | static struct frame_head * | 55 | static struct frame_head *dump_user_backtrace(struct frame_head *head) |
56 | dump_user_backtrace(struct frame_head * head) | ||
57 | { | 56 | { |
58 | struct frame_head bufhead[2]; | 57 | struct frame_head bufhead[2]; |
59 | 58 | ||
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 57f6c9088081..022cd41ea9b4 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -28,85 +28,9 @@ static struct op_x86_model_spec const *model; | |||
28 | static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); | 28 | static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); |
29 | static DEFINE_PER_CPU(unsigned long, saved_lvtpc); | 29 | static DEFINE_PER_CPU(unsigned long, saved_lvtpc); |
30 | 30 | ||
31 | static int nmi_start(void); | ||
32 | static void nmi_stop(void); | ||
33 | static void nmi_cpu_start(void *dummy); | ||
34 | static void nmi_cpu_stop(void *dummy); | ||
35 | |||
36 | /* 0 == registered but off, 1 == registered and on */ | 31 | /* 0 == registered but off, 1 == registered and on */ |
37 | static int nmi_enabled = 0; | 32 | static int nmi_enabled = 0; |
38 | 33 | ||
39 | #ifdef CONFIG_SMP | ||
40 | static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action, | ||
41 | void *data) | ||
42 | { | ||
43 | int cpu = (unsigned long)data; | ||
44 | switch (action) { | ||
45 | case CPU_DOWN_FAILED: | ||
46 | case CPU_ONLINE: | ||
47 | smp_call_function_single(cpu, nmi_cpu_start, NULL, 0); | ||
48 | break; | ||
49 | case CPU_DOWN_PREPARE: | ||
50 | smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1); | ||
51 | break; | ||
52 | } | ||
53 | return NOTIFY_DONE; | ||
54 | } | ||
55 | |||
56 | static struct notifier_block oprofile_cpu_nb = { | ||
57 | .notifier_call = oprofile_cpu_notifier | ||
58 | }; | ||
59 | #endif | ||
60 | |||
61 | #ifdef CONFIG_PM | ||
62 | |||
63 | static int nmi_suspend(struct sys_device *dev, pm_message_t state) | ||
64 | { | ||
65 | /* Only one CPU left, just stop that one */ | ||
66 | if (nmi_enabled == 1) | ||
67 | nmi_cpu_stop(NULL); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int nmi_resume(struct sys_device *dev) | ||
72 | { | ||
73 | if (nmi_enabled == 1) | ||
74 | nmi_cpu_start(NULL); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static struct sysdev_class oprofile_sysclass = { | ||
79 | .name = "oprofile", | ||
80 | .resume = nmi_resume, | ||
81 | .suspend = nmi_suspend, | ||
82 | }; | ||
83 | |||
84 | static struct sys_device device_oprofile = { | ||
85 | .id = 0, | ||
86 | .cls = &oprofile_sysclass, | ||
87 | }; | ||
88 | |||
89 | static int __init init_sysfs(void) | ||
90 | { | ||
91 | int error; | ||
92 | |||
93 | error = sysdev_class_register(&oprofile_sysclass); | ||
94 | if (!error) | ||
95 | error = sysdev_register(&device_oprofile); | ||
96 | return error; | ||
97 | } | ||
98 | |||
99 | static void exit_sysfs(void) | ||
100 | { | ||
101 | sysdev_unregister(&device_oprofile); | ||
102 | sysdev_class_unregister(&oprofile_sysclass); | ||
103 | } | ||
104 | |||
105 | #else | ||
106 | #define init_sysfs() do { } while (0) | ||
107 | #define exit_sysfs() do { } while (0) | ||
108 | #endif /* CONFIG_PM */ | ||
109 | |||
110 | static int profile_exceptions_notify(struct notifier_block *self, | 34 | static int profile_exceptions_notify(struct notifier_block *self, |
111 | unsigned long val, void *data) | 35 | unsigned long val, void *data) |
112 | { | 36 | { |
@@ -361,6 +285,77 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) | |||
361 | return 0; | 285 | return 0; |
362 | } | 286 | } |
363 | 287 | ||
288 | #ifdef CONFIG_SMP | ||
289 | static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action, | ||
290 | void *data) | ||
291 | { | ||
292 | int cpu = (unsigned long)data; | ||
293 | switch (action) { | ||
294 | case CPU_DOWN_FAILED: | ||
295 | case CPU_ONLINE: | ||
296 | smp_call_function_single(cpu, nmi_cpu_start, NULL, 0); | ||
297 | break; | ||
298 | case CPU_DOWN_PREPARE: | ||
299 | smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1); | ||
300 | break; | ||
301 | } | ||
302 | return NOTIFY_DONE; | ||
303 | } | ||
304 | |||
305 | static struct notifier_block oprofile_cpu_nb = { | ||
306 | .notifier_call = oprofile_cpu_notifier | ||
307 | }; | ||
308 | #endif | ||
309 | |||
310 | #ifdef CONFIG_PM | ||
311 | |||
312 | static int nmi_suspend(struct sys_device *dev, pm_message_t state) | ||
313 | { | ||
314 | /* Only one CPU left, just stop that one */ | ||
315 | if (nmi_enabled == 1) | ||
316 | nmi_cpu_stop(NULL); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int nmi_resume(struct sys_device *dev) | ||
321 | { | ||
322 | if (nmi_enabled == 1) | ||
323 | nmi_cpu_start(NULL); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static struct sysdev_class oprofile_sysclass = { | ||
328 | .name = "oprofile", | ||
329 | .resume = nmi_resume, | ||
330 | .suspend = nmi_suspend, | ||
331 | }; | ||
332 | |||
333 | static struct sys_device device_oprofile = { | ||
334 | .id = 0, | ||
335 | .cls = &oprofile_sysclass, | ||
336 | }; | ||
337 | |||
338 | static int __init init_sysfs(void) | ||
339 | { | ||
340 | int error; | ||
341 | |||
342 | error = sysdev_class_register(&oprofile_sysclass); | ||
343 | if (!error) | ||
344 | error = sysdev_register(&device_oprofile); | ||
345 | return error; | ||
346 | } | ||
347 | |||
348 | static void exit_sysfs(void) | ||
349 | { | ||
350 | sysdev_unregister(&device_oprofile); | ||
351 | sysdev_class_unregister(&oprofile_sysclass); | ||
352 | } | ||
353 | |||
354 | #else | ||
355 | #define init_sysfs() do { } while (0) | ||
356 | #define exit_sysfs() do { } while (0) | ||
357 | #endif /* CONFIG_PM */ | ||
358 | |||
364 | static int p4force; | 359 | static int p4force; |
365 | module_param(p4force, int, 0); | 360 | module_param(p4force, int, 0); |
366 | 361 | ||
@@ -420,9 +415,6 @@ static int __init ppro_init(char **cpu_type) | |||
420 | case 15: case 23: | 415 | case 15: case 23: |
421 | *cpu_type = "i386/core_2"; | 416 | *cpu_type = "i386/core_2"; |
422 | break; | 417 | break; |
423 | case 26: | ||
424 | *cpu_type = "i386/core_2"; | ||
425 | break; | ||
426 | default: | 418 | default: |
427 | /* Unknown */ | 419 | /* Unknown */ |
428 | return 0; | 420 | return 0; |
@@ -432,6 +424,16 @@ static int __init ppro_init(char **cpu_type) | |||
432 | return 1; | 424 | return 1; |
433 | } | 425 | } |
434 | 426 | ||
427 | static int __init arch_perfmon_init(char **cpu_type) | ||
428 | { | ||
429 | if (!cpu_has_arch_perfmon) | ||
430 | return 0; | ||
431 | *cpu_type = "i386/arch_perfmon"; | ||
432 | model = &op_arch_perfmon_spec; | ||
433 | arch_perfmon_setup_counters(); | ||
434 | return 1; | ||
435 | } | ||
436 | |||
435 | /* in order to get sysfs right */ | 437 | /* in order to get sysfs right */ |
436 | static int using_nmi; | 438 | static int using_nmi; |
437 | 439 | ||
@@ -439,7 +441,7 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
439 | { | 441 | { |
440 | __u8 vendor = boot_cpu_data.x86_vendor; | 442 | __u8 vendor = boot_cpu_data.x86_vendor; |
441 | __u8 family = boot_cpu_data.x86; | 443 | __u8 family = boot_cpu_data.x86; |
442 | char *cpu_type; | 444 | char *cpu_type = NULL; |
443 | int ret = 0; | 445 | int ret = 0; |
444 | 446 | ||
445 | if (!cpu_has_apic) | 447 | if (!cpu_has_apic) |
@@ -477,19 +479,20 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
477 | switch (family) { | 479 | switch (family) { |
478 | /* Pentium IV */ | 480 | /* Pentium IV */ |
479 | case 0xf: | 481 | case 0xf: |
480 | if (!p4_init(&cpu_type)) | 482 | p4_init(&cpu_type); |
481 | return -ENODEV; | ||
482 | break; | 483 | break; |
483 | 484 | ||
484 | /* A P6-class processor */ | 485 | /* A P6-class processor */ |
485 | case 6: | 486 | case 6: |
486 | if (!ppro_init(&cpu_type)) | 487 | ppro_init(&cpu_type); |
487 | return -ENODEV; | ||
488 | break; | 488 | break; |
489 | 489 | ||
490 | default: | 490 | default: |
491 | return -ENODEV; | 491 | break; |
492 | } | 492 | } |
493 | |||
494 | if (!cpu_type && !arch_perfmon_init(&cpu_type)) | ||
495 | return -ENODEV; | ||
493 | break; | 496 | break; |
494 | 497 | ||
495 | default: | 498 | default: |
diff --git a/arch/x86/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h index 2880b15c4675..91b6a116165e 100644 --- a/arch/x86/oprofile/op_counter.h +++ b/arch/x86/oprofile/op_counter.h | |||
@@ -6,22 +6,22 @@ | |||
6 | * | 6 | * |
7 | * @author John Levon | 7 | * @author John Levon |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef OP_COUNTER_H | 10 | #ifndef OP_COUNTER_H |
11 | #define OP_COUNTER_H | 11 | #define OP_COUNTER_H |
12 | 12 | ||
13 | #define OP_MAX_COUNTER 8 | 13 | #define OP_MAX_COUNTER 8 |
14 | 14 | ||
15 | /* Per-perfctr configuration as set via | 15 | /* Per-perfctr configuration as set via |
16 | * oprofilefs. | 16 | * oprofilefs. |
17 | */ | 17 | */ |
18 | struct op_counter_config { | 18 | struct op_counter_config { |
19 | unsigned long count; | 19 | unsigned long count; |
20 | unsigned long enabled; | 20 | unsigned long enabled; |
21 | unsigned long event; | 21 | unsigned long event; |
22 | unsigned long kernel; | 22 | unsigned long kernel; |
23 | unsigned long user; | 23 | unsigned long user; |
24 | unsigned long unit_mask; | 24 | unsigned long unit_mask; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | extern struct op_counter_config counter_config[]; | 27 | extern struct op_counter_config counter_config[]; |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index d9faf607b3a6..509513760a6e 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -67,8 +67,9 @@ static unsigned long reset_value[NUM_COUNTERS]; | |||
67 | 67 | ||
68 | /* The function interface needs to be fixed, something like add | 68 | /* The function interface needs to be fixed, something like add |
69 | data. Should then be added to linux/oprofile.h. */ | 69 | data. Should then be added to linux/oprofile.h. */ |
70 | extern void oprofile_add_ibs_sample(struct pt_regs *const regs, | 70 | extern void |
71 | unsigned int * const ibs_sample, u8 code); | 71 | oprofile_add_ibs_sample(struct pt_regs *const regs, |
72 | unsigned int *const ibs_sample, int ibs_code); | ||
72 | 73 | ||
73 | struct ibs_fetch_sample { | 74 | struct ibs_fetch_sample { |
74 | /* MSRC001_1031 IBS Fetch Linear Address Register */ | 75 | /* MSRC001_1031 IBS Fetch Linear Address Register */ |
@@ -309,12 +310,15 @@ static void op_amd_start(struct op_msrs const * const msrs) | |||
309 | #ifdef CONFIG_OPROFILE_IBS | 310 | #ifdef CONFIG_OPROFILE_IBS |
310 | if (ibs_allowed && ibs_config.fetch_enabled) { | 311 | if (ibs_allowed && ibs_config.fetch_enabled) { |
311 | low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; | 312 | low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; |
312 | high = IBS_FETCH_HIGH_ENABLE; | 313 | high = ((ibs_config.rand_en & 0x1) << 25) /* bit 57 */ |
314 | + IBS_FETCH_HIGH_ENABLE; | ||
313 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); | 315 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); |
314 | } | 316 | } |
315 | 317 | ||
316 | if (ibs_allowed && ibs_config.op_enabled) { | 318 | if (ibs_allowed && ibs_config.op_enabled) { |
317 | low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF) + IBS_OP_LOW_ENABLE; | 319 | low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF) |
320 | + ((ibs_config.dispatched_ops & 0x1) << 19) /* bit 19 */ | ||
321 | + IBS_OP_LOW_ENABLE; | ||
318 | high = 0; | 322 | high = 0; |
319 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); | 323 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); |
320 | } | 324 | } |
@@ -468,11 +472,10 @@ static void clear_ibs_nmi(void) | |||
468 | on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1); | 472 | on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1); |
469 | } | 473 | } |
470 | 474 | ||
471 | static int (*create_arch_files)(struct super_block * sb, struct dentry * root); | 475 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); |
472 | 476 | ||
473 | static int setup_ibs_files(struct super_block * sb, struct dentry * root) | 477 | static int setup_ibs_files(struct super_block *sb, struct dentry *root) |
474 | { | 478 | { |
475 | char buf[12]; | ||
476 | struct dentry *dir; | 479 | struct dentry *dir; |
477 | int ret = 0; | 480 | int ret = 0; |
478 | 481 | ||
@@ -494,22 +497,22 @@ static int setup_ibs_files(struct super_block * sb, struct dentry * root) | |||
494 | ibs_config.max_cnt_op = 250000; | 497 | ibs_config.max_cnt_op = 250000; |
495 | ibs_config.op_enabled = 0; | 498 | ibs_config.op_enabled = 0; |
496 | ibs_config.dispatched_ops = 1; | 499 | ibs_config.dispatched_ops = 1; |
497 | snprintf(buf, sizeof(buf), "ibs_fetch"); | 500 | |
498 | dir = oprofilefs_mkdir(sb, root, buf); | 501 | dir = oprofilefs_mkdir(sb, root, "ibs_fetch"); |
499 | oprofilefs_create_ulong(sb, dir, "rand_enable", | ||
500 | &ibs_config.rand_en); | ||
501 | oprofilefs_create_ulong(sb, dir, "enable", | 502 | oprofilefs_create_ulong(sb, dir, "enable", |
502 | &ibs_config.fetch_enabled); | 503 | &ibs_config.fetch_enabled); |
503 | oprofilefs_create_ulong(sb, dir, "max_count", | 504 | oprofilefs_create_ulong(sb, dir, "max_count", |
504 | &ibs_config.max_cnt_fetch); | 505 | &ibs_config.max_cnt_fetch); |
505 | snprintf(buf, sizeof(buf), "ibs_uops"); | 506 | oprofilefs_create_ulong(sb, dir, "rand_enable", |
506 | dir = oprofilefs_mkdir(sb, root, buf); | 507 | &ibs_config.rand_en); |
508 | |||
509 | dir = oprofilefs_mkdir(sb, root, "ibs_op"); | ||
507 | oprofilefs_create_ulong(sb, dir, "enable", | 510 | oprofilefs_create_ulong(sb, dir, "enable", |
508 | &ibs_config.op_enabled); | 511 | &ibs_config.op_enabled); |
509 | oprofilefs_create_ulong(sb, dir, "max_count", | 512 | oprofilefs_create_ulong(sb, dir, "max_count", |
510 | &ibs_config.max_cnt_op); | 513 | &ibs_config.max_cnt_op); |
511 | oprofilefs_create_ulong(sb, dir, "dispatched_ops", | 514 | oprofilefs_create_ulong(sb, dir, "dispatched_ops", |
512 | &ibs_config.dispatched_ops); | 515 | &ibs_config.dispatched_ops); |
513 | 516 | ||
514 | return 0; | 517 | return 0; |
515 | } | 518 | } |
@@ -530,14 +533,14 @@ static void op_amd_exit(void) | |||
530 | #endif | 533 | #endif |
531 | 534 | ||
532 | struct op_x86_model_spec const op_amd_spec = { | 535 | struct op_x86_model_spec const op_amd_spec = { |
533 | .init = op_amd_init, | 536 | .init = op_amd_init, |
534 | .exit = op_amd_exit, | 537 | .exit = op_amd_exit, |
535 | .num_counters = NUM_COUNTERS, | 538 | .num_counters = NUM_COUNTERS, |
536 | .num_controls = NUM_CONTROLS, | 539 | .num_controls = NUM_CONTROLS, |
537 | .fill_in_addresses = &op_amd_fill_in_addresses, | 540 | .fill_in_addresses = &op_amd_fill_in_addresses, |
538 | .setup_ctrs = &op_amd_setup_ctrs, | 541 | .setup_ctrs = &op_amd_setup_ctrs, |
539 | .check_ctrs = &op_amd_check_ctrs, | 542 | .check_ctrs = &op_amd_check_ctrs, |
540 | .start = &op_amd_start, | 543 | .start = &op_amd_start, |
541 | .stop = &op_amd_stop, | 544 | .stop = &op_amd_stop, |
542 | .shutdown = &op_amd_shutdown | 545 | .shutdown = &op_amd_shutdown |
543 | }; | 546 | }; |
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 43ac5af338d8..4c4a51c90bc2 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c | |||
@@ -698,24 +698,24 @@ static void p4_shutdown(struct op_msrs const * const msrs) | |||
698 | 698 | ||
699 | #ifdef CONFIG_SMP | 699 | #ifdef CONFIG_SMP |
700 | struct op_x86_model_spec const op_p4_ht2_spec = { | 700 | struct op_x86_model_spec const op_p4_ht2_spec = { |
701 | .num_counters = NUM_COUNTERS_HT2, | 701 | .num_counters = NUM_COUNTERS_HT2, |
702 | .num_controls = NUM_CONTROLS_HT2, | 702 | .num_controls = NUM_CONTROLS_HT2, |
703 | .fill_in_addresses = &p4_fill_in_addresses, | 703 | .fill_in_addresses = &p4_fill_in_addresses, |
704 | .setup_ctrs = &p4_setup_ctrs, | 704 | .setup_ctrs = &p4_setup_ctrs, |
705 | .check_ctrs = &p4_check_ctrs, | 705 | .check_ctrs = &p4_check_ctrs, |
706 | .start = &p4_start, | 706 | .start = &p4_start, |
707 | .stop = &p4_stop, | 707 | .stop = &p4_stop, |
708 | .shutdown = &p4_shutdown | 708 | .shutdown = &p4_shutdown |
709 | }; | 709 | }; |
710 | #endif | 710 | #endif |
711 | 711 | ||
712 | struct op_x86_model_spec const op_p4_spec = { | 712 | struct op_x86_model_spec const op_p4_spec = { |
713 | .num_counters = NUM_COUNTERS_NON_HT, | 713 | .num_counters = NUM_COUNTERS_NON_HT, |
714 | .num_controls = NUM_CONTROLS_NON_HT, | 714 | .num_controls = NUM_CONTROLS_NON_HT, |
715 | .fill_in_addresses = &p4_fill_in_addresses, | 715 | .fill_in_addresses = &p4_fill_in_addresses, |
716 | .setup_ctrs = &p4_setup_ctrs, | 716 | .setup_ctrs = &p4_setup_ctrs, |
717 | .check_ctrs = &p4_check_ctrs, | 717 | .check_ctrs = &p4_check_ctrs, |
718 | .start = &p4_start, | 718 | .start = &p4_start, |
719 | .stop = &p4_stop, | 719 | .stop = &p4_stop, |
720 | .shutdown = &p4_shutdown | 720 | .shutdown = &p4_shutdown |
721 | }; | 721 | }; |
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index eff431f6c57b..0620d6d45f7d 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c | |||
@@ -1,32 +1,34 @@ | |||
1 | /* | 1 | /* |
2 | * @file op_model_ppro.h | 2 | * @file op_model_ppro.h |
3 | * pentium pro / P6 model-specific MSR operations | 3 | * Family 6 perfmon and architectural perfmon MSR operations |
4 | * | 4 | * |
5 | * @remark Copyright 2002 OProfile authors | 5 | * @remark Copyright 2002 OProfile authors |
6 | * @remark Copyright 2008 Intel Corporation | ||
6 | * @remark Read the file COPYING | 7 | * @remark Read the file COPYING |
7 | * | 8 | * |
8 | * @author John Levon | 9 | * @author John Levon |
9 | * @author Philippe Elie | 10 | * @author Philippe Elie |
10 | * @author Graydon Hoare | 11 | * @author Graydon Hoare |
12 | * @author Andi Kleen | ||
11 | */ | 13 | */ |
12 | 14 | ||
13 | #include <linux/oprofile.h> | 15 | #include <linux/oprofile.h> |
16 | #include <linux/slab.h> | ||
14 | #include <asm/ptrace.h> | 17 | #include <asm/ptrace.h> |
15 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
16 | #include <asm/apic.h> | 19 | #include <asm/apic.h> |
17 | #include <asm/nmi.h> | 20 | #include <asm/nmi.h> |
21 | #include <asm/intel_arch_perfmon.h> | ||
18 | 22 | ||
19 | #include "op_x86_model.h" | 23 | #include "op_x86_model.h" |
20 | #include "op_counter.h" | 24 | #include "op_counter.h" |
21 | 25 | ||
22 | #define NUM_COUNTERS 2 | 26 | static int num_counters = 2; |
23 | #define NUM_CONTROLS 2 | 27 | static int counter_width = 32; |
24 | 28 | ||
25 | #define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) | 29 | #define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) |
26 | #define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0) | 30 | #define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0) |
27 | #define CTR_32BIT_WRITE(l, msrs, c) \ | 31 | #define CTR_OVERFLOWED(n) (!((n) & (1U<<(counter_width-1)))) |
28 | do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), 0); } while (0) | ||
29 | #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) | ||
30 | 32 | ||
31 | #define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) | 33 | #define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) |
32 | #define CTRL_READ(l, h, msrs, c) do {rdmsr((msrs->controls[(c)].addr), (l), (h)); } while (0) | 34 | #define CTRL_READ(l, h, msrs, c) do {rdmsr((msrs->controls[(c)].addr), (l), (h)); } while (0) |
@@ -40,20 +42,20 @@ | |||
40 | #define CTRL_SET_UM(val, m) (val |= (m << 8)) | 42 | #define CTRL_SET_UM(val, m) (val |= (m << 8)) |
41 | #define CTRL_SET_EVENT(val, e) (val |= e) | 43 | #define CTRL_SET_EVENT(val, e) (val |= e) |
42 | 44 | ||
43 | static unsigned long reset_value[NUM_COUNTERS]; | 45 | static u64 *reset_value; |
44 | 46 | ||
45 | static void ppro_fill_in_addresses(struct op_msrs * const msrs) | 47 | static void ppro_fill_in_addresses(struct op_msrs * const msrs) |
46 | { | 48 | { |
47 | int i; | 49 | int i; |
48 | 50 | ||
49 | for (i = 0; i < NUM_COUNTERS; i++) { | 51 | for (i = 0; i < num_counters; i++) { |
50 | if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) | 52 | if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) |
51 | msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; | 53 | msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; |
52 | else | 54 | else |
53 | msrs->counters[i].addr = 0; | 55 | msrs->counters[i].addr = 0; |
54 | } | 56 | } |
55 | 57 | ||
56 | for (i = 0; i < NUM_CONTROLS; i++) { | 58 | for (i = 0; i < num_counters; i++) { |
57 | if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) | 59 | if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) |
58 | msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; | 60 | msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; |
59 | else | 61 | else |
@@ -67,8 +69,22 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) | |||
67 | unsigned int low, high; | 69 | unsigned int low, high; |
68 | int i; | 70 | int i; |
69 | 71 | ||
72 | if (!reset_value) { | ||
73 | reset_value = kmalloc(sizeof(unsigned) * num_counters, | ||
74 | GFP_ATOMIC); | ||
75 | if (!reset_value) | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | if (cpu_has_arch_perfmon) { | ||
80 | union cpuid10_eax eax; | ||
81 | eax.full = cpuid_eax(0xa); | ||
82 | if (counter_width < eax.split.bit_width) | ||
83 | counter_width = eax.split.bit_width; | ||
84 | } | ||
85 | |||
70 | /* clear all counters */ | 86 | /* clear all counters */ |
71 | for (i = 0 ; i < NUM_CONTROLS; ++i) { | 87 | for (i = 0 ; i < num_counters; ++i) { |
72 | if (unlikely(!CTRL_IS_RESERVED(msrs, i))) | 88 | if (unlikely(!CTRL_IS_RESERVED(msrs, i))) |
73 | continue; | 89 | continue; |
74 | CTRL_READ(low, high, msrs, i); | 90 | CTRL_READ(low, high, msrs, i); |
@@ -77,18 +93,18 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) | |||
77 | } | 93 | } |
78 | 94 | ||
79 | /* avoid a false detection of ctr overflows in NMI handler */ | 95 | /* avoid a false detection of ctr overflows in NMI handler */ |
80 | for (i = 0; i < NUM_COUNTERS; ++i) { | 96 | for (i = 0; i < num_counters; ++i) { |
81 | if (unlikely(!CTR_IS_RESERVED(msrs, i))) | 97 | if (unlikely(!CTR_IS_RESERVED(msrs, i))) |
82 | continue; | 98 | continue; |
83 | CTR_32BIT_WRITE(1, msrs, i); | 99 | wrmsrl(msrs->counters[i].addr, -1LL); |
84 | } | 100 | } |
85 | 101 | ||
86 | /* enable active counters */ | 102 | /* enable active counters */ |
87 | for (i = 0; i < NUM_COUNTERS; ++i) { | 103 | for (i = 0; i < num_counters; ++i) { |
88 | if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { | 104 | if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { |
89 | reset_value[i] = counter_config[i].count; | 105 | reset_value[i] = counter_config[i].count; |
90 | 106 | ||
91 | CTR_32BIT_WRITE(counter_config[i].count, msrs, i); | 107 | wrmsrl(msrs->counters[i].addr, -reset_value[i]); |
92 | 108 | ||
93 | CTRL_READ(low, high, msrs, i); | 109 | CTRL_READ(low, high, msrs, i); |
94 | CTRL_CLEAR(low); | 110 | CTRL_CLEAR(low); |
@@ -111,13 +127,13 @@ static int ppro_check_ctrs(struct pt_regs * const regs, | |||
111 | unsigned int low, high; | 127 | unsigned int low, high; |
112 | int i; | 128 | int i; |
113 | 129 | ||
114 | for (i = 0 ; i < NUM_COUNTERS; ++i) { | 130 | for (i = 0 ; i < num_counters; ++i) { |
115 | if (!reset_value[i]) | 131 | if (!reset_value[i]) |
116 | continue; | 132 | continue; |
117 | CTR_READ(low, high, msrs, i); | 133 | CTR_READ(low, high, msrs, i); |
118 | if (CTR_OVERFLOWED(low)) { | 134 | if (CTR_OVERFLOWED(low)) { |
119 | oprofile_add_sample(regs, i); | 135 | oprofile_add_sample(regs, i); |
120 | CTR_32BIT_WRITE(reset_value[i], msrs, i); | 136 | wrmsrl(msrs->counters[i].addr, -reset_value[i]); |
121 | } | 137 | } |
122 | } | 138 | } |
123 | 139 | ||
@@ -141,7 +157,7 @@ static void ppro_start(struct op_msrs const * const msrs) | |||
141 | unsigned int low, high; | 157 | unsigned int low, high; |
142 | int i; | 158 | int i; |
143 | 159 | ||
144 | for (i = 0; i < NUM_COUNTERS; ++i) { | 160 | for (i = 0; i < num_counters; ++i) { |
145 | if (reset_value[i]) { | 161 | if (reset_value[i]) { |
146 | CTRL_READ(low, high, msrs, i); | 162 | CTRL_READ(low, high, msrs, i); |
147 | CTRL_SET_ACTIVE(low); | 163 | CTRL_SET_ACTIVE(low); |
@@ -156,7 +172,7 @@ static void ppro_stop(struct op_msrs const * const msrs) | |||
156 | unsigned int low, high; | 172 | unsigned int low, high; |
157 | int i; | 173 | int i; |
158 | 174 | ||
159 | for (i = 0; i < NUM_COUNTERS; ++i) { | 175 | for (i = 0; i < num_counters; ++i) { |
160 | if (!reset_value[i]) | 176 | if (!reset_value[i]) |
161 | continue; | 177 | continue; |
162 | CTRL_READ(low, high, msrs, i); | 178 | CTRL_READ(low, high, msrs, i); |
@@ -169,24 +185,70 @@ static void ppro_shutdown(struct op_msrs const * const msrs) | |||
169 | { | 185 | { |
170 | int i; | 186 | int i; |
171 | 187 | ||
172 | for (i = 0 ; i < NUM_COUNTERS ; ++i) { | 188 | for (i = 0 ; i < num_counters ; ++i) { |
173 | if (CTR_IS_RESERVED(msrs, i)) | 189 | if (CTR_IS_RESERVED(msrs, i)) |
174 | release_perfctr_nmi(MSR_P6_PERFCTR0 + i); | 190 | release_perfctr_nmi(MSR_P6_PERFCTR0 + i); |
175 | } | 191 | } |
176 | for (i = 0 ; i < NUM_CONTROLS ; ++i) { | 192 | for (i = 0 ; i < num_counters ; ++i) { |
177 | if (CTRL_IS_RESERVED(msrs, i)) | 193 | if (CTRL_IS_RESERVED(msrs, i)) |
178 | release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); | 194 | release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); |
179 | } | 195 | } |
196 | if (reset_value) { | ||
197 | kfree(reset_value); | ||
198 | reset_value = NULL; | ||
199 | } | ||
180 | } | 200 | } |
181 | 201 | ||
182 | 202 | ||
183 | struct op_x86_model_spec const op_ppro_spec = { | 203 | struct op_x86_model_spec op_ppro_spec = { |
184 | .num_counters = NUM_COUNTERS, | 204 | .num_counters = 2, /* can be overriden */ |
185 | .num_controls = NUM_CONTROLS, | 205 | .num_controls = 2, /* dito */ |
186 | .fill_in_addresses = &ppro_fill_in_addresses, | 206 | .fill_in_addresses = &ppro_fill_in_addresses, |
187 | .setup_ctrs = &ppro_setup_ctrs, | 207 | .setup_ctrs = &ppro_setup_ctrs, |
188 | .check_ctrs = &ppro_check_ctrs, | 208 | .check_ctrs = &ppro_check_ctrs, |
189 | .start = &ppro_start, | 209 | .start = &ppro_start, |
190 | .stop = &ppro_stop, | 210 | .stop = &ppro_stop, |
191 | .shutdown = &ppro_shutdown | 211 | .shutdown = &ppro_shutdown |
212 | }; | ||
213 | |||
214 | /* | ||
215 | * Architectural performance monitoring. | ||
216 | * | ||
217 | * Newer Intel CPUs (Core1+) have support for architectural | ||
218 | * events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details. | ||
219 | * The advantage of this is that it can be done without knowing about | ||
220 | * the specific CPU. | ||
221 | */ | ||
222 | |||
223 | void arch_perfmon_setup_counters(void) | ||
224 | { | ||
225 | union cpuid10_eax eax; | ||
226 | |||
227 | eax.full = cpuid_eax(0xa); | ||
228 | |||
229 | /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */ | ||
230 | if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 && | ||
231 | current_cpu_data.x86_model == 15) { | ||
232 | eax.split.version_id = 2; | ||
233 | eax.split.num_counters = 2; | ||
234 | eax.split.bit_width = 40; | ||
235 | } | ||
236 | |||
237 | num_counters = eax.split.num_counters; | ||
238 | |||
239 | op_arch_perfmon_spec.num_counters = num_counters; | ||
240 | op_arch_perfmon_spec.num_controls = num_counters; | ||
241 | op_ppro_spec.num_counters = num_counters; | ||
242 | op_ppro_spec.num_controls = num_counters; | ||
243 | } | ||
244 | |||
245 | struct op_x86_model_spec op_arch_perfmon_spec = { | ||
246 | /* num_counters/num_controls filled in at runtime */ | ||
247 | .fill_in_addresses = &ppro_fill_in_addresses, | ||
248 | /* user space does the cpuid check for available events */ | ||
249 | .setup_ctrs = &ppro_setup_ctrs, | ||
250 | .check_ctrs = &ppro_check_ctrs, | ||
251 | .start = &ppro_start, | ||
252 | .stop = &ppro_stop, | ||
253 | .shutdown = &ppro_shutdown | ||
192 | }; | 254 | }; |
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h index 05a0261ba0c3..825e79064d64 100644 --- a/arch/x86/oprofile/op_x86_model.h +++ b/arch/x86/oprofile/op_x86_model.h | |||
@@ -22,8 +22,8 @@ struct op_msr { | |||
22 | }; | 22 | }; |
23 | 23 | ||
24 | struct op_msrs { | 24 | struct op_msrs { |
25 | struct op_msr * counters; | 25 | struct op_msr *counters; |
26 | struct op_msr * controls; | 26 | struct op_msr *controls; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | struct pt_regs; | 29 | struct pt_regs; |
@@ -34,8 +34,8 @@ struct pt_regs; | |||
34 | struct op_x86_model_spec { | 34 | struct op_x86_model_spec { |
35 | int (*init)(struct oprofile_operations *ops); | 35 | int (*init)(struct oprofile_operations *ops); |
36 | void (*exit)(void); | 36 | void (*exit)(void); |
37 | unsigned int const num_counters; | 37 | unsigned int num_counters; |
38 | unsigned int const num_controls; | 38 | unsigned int num_controls; |
39 | void (*fill_in_addresses)(struct op_msrs * const msrs); | 39 | void (*fill_in_addresses)(struct op_msrs * const msrs); |
40 | void (*setup_ctrs)(struct op_msrs const * const msrs); | 40 | void (*setup_ctrs)(struct op_msrs const * const msrs); |
41 | int (*check_ctrs)(struct pt_regs * const regs, | 41 | int (*check_ctrs)(struct pt_regs * const regs, |
@@ -45,9 +45,12 @@ struct op_x86_model_spec { | |||
45 | void (*shutdown)(struct op_msrs const * const msrs); | 45 | void (*shutdown)(struct op_msrs const * const msrs); |
46 | }; | 46 | }; |
47 | 47 | ||
48 | extern struct op_x86_model_spec const op_ppro_spec; | 48 | extern struct op_x86_model_spec op_ppro_spec; |
49 | extern struct op_x86_model_spec const op_p4_spec; | 49 | extern struct op_x86_model_spec const op_p4_spec; |
50 | extern struct op_x86_model_spec const op_p4_ht2_spec; | 50 | extern struct op_x86_model_spec const op_p4_ht2_spec; |
51 | extern struct op_x86_model_spec const op_amd_spec; | 51 | extern struct op_x86_model_spec const op_amd_spec; |
52 | extern struct op_x86_model_spec op_arch_perfmon_spec; | ||
53 | |||
54 | extern void arch_perfmon_setup_counters(void); | ||
52 | 55 | ||
53 | #endif /* OP_X86_MODEL_H */ | 56 | #endif /* OP_X86_MODEL_H */ |
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index 37681700b61a..b55cd23ffdef 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c | |||
@@ -41,7 +41,6 @@ static cpumask_t marked_cpus = CPU_MASK_NONE; | |||
41 | static DEFINE_SPINLOCK(task_mortuary); | 41 | static DEFINE_SPINLOCK(task_mortuary); |
42 | static void process_task_mortuary(void); | 42 | static void process_task_mortuary(void); |
43 | 43 | ||
44 | |||
45 | /* Take ownership of the task struct and place it on the | 44 | /* Take ownership of the task struct and place it on the |
46 | * list for processing. Only after two full buffer syncs | 45 | * list for processing. Only after two full buffer syncs |
47 | * does the task eventually get freed, because by then | 46 | * does the task eventually get freed, because by then |
@@ -341,7 +340,7 @@ static void add_trace_begin(void) | |||
341 | * Add IBS fetch and op entries to event buffer | 340 | * Add IBS fetch and op entries to event buffer |
342 | */ | 341 | */ |
343 | static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code, | 342 | static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code, |
344 | int in_kernel, struct mm_struct *mm) | 343 | struct mm_struct *mm) |
345 | { | 344 | { |
346 | unsigned long rip; | 345 | unsigned long rip; |
347 | int i, count; | 346 | int i, count; |
@@ -565,9 +564,11 @@ void sync_buffer(int cpu) | |||
565 | struct task_struct *new; | 564 | struct task_struct *new; |
566 | unsigned long cookie = 0; | 565 | unsigned long cookie = 0; |
567 | int in_kernel = 1; | 566 | int in_kernel = 1; |
568 | unsigned int i; | ||
569 | sync_buffer_state state = sb_buffer_start; | 567 | sync_buffer_state state = sb_buffer_start; |
568 | #ifndef CONFIG_OPROFILE_IBS | ||
569 | unsigned int i; | ||
570 | unsigned long available; | 570 | unsigned long available; |
571 | #endif | ||
571 | 572 | ||
572 | mutex_lock(&buffer_mutex); | 573 | mutex_lock(&buffer_mutex); |
573 | 574 | ||
@@ -575,9 +576,13 @@ void sync_buffer(int cpu) | |||
575 | 576 | ||
576 | /* Remember, only we can modify tail_pos */ | 577 | /* Remember, only we can modify tail_pos */ |
577 | 578 | ||
579 | #ifndef CONFIG_OPROFILE_IBS | ||
578 | available = get_slots(cpu_buf); | 580 | available = get_slots(cpu_buf); |
579 | 581 | ||
580 | for (i = 0; i < available; ++i) { | 582 | for (i = 0; i < available; ++i) { |
583 | #else | ||
584 | while (get_slots(cpu_buf)) { | ||
585 | #endif | ||
581 | struct op_sample *s = &cpu_buf->buffer[cpu_buf->tail_pos]; | 586 | struct op_sample *s = &cpu_buf->buffer[cpu_buf->tail_pos]; |
582 | 587 | ||
583 | if (is_code(s->eip)) { | 588 | if (is_code(s->eip)) { |
@@ -593,12 +598,10 @@ void sync_buffer(int cpu) | |||
593 | #ifdef CONFIG_OPROFILE_IBS | 598 | #ifdef CONFIG_OPROFILE_IBS |
594 | } else if (s->event == IBS_FETCH_BEGIN) { | 599 | } else if (s->event == IBS_FETCH_BEGIN) { |
595 | state = sb_bt_start; | 600 | state = sb_bt_start; |
596 | add_ibs_begin(cpu_buf, | 601 | add_ibs_begin(cpu_buf, IBS_FETCH_CODE, mm); |
597 | IBS_FETCH_CODE, in_kernel, mm); | ||
598 | } else if (s->event == IBS_OP_BEGIN) { | 602 | } else if (s->event == IBS_OP_BEGIN) { |
599 | state = sb_bt_start; | 603 | state = sb_bt_start; |
600 | add_ibs_begin(cpu_buf, | 604 | add_ibs_begin(cpu_buf, IBS_OP_CODE, mm); |
601 | IBS_OP_CODE, in_kernel, mm); | ||
602 | #endif | 605 | #endif |
603 | } else { | 606 | } else { |
604 | struct mm_struct *oldmm = mm; | 607 | struct mm_struct *oldmm = mm; |
diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h index 08866f6a96a3..3110732c1835 100644 --- a/drivers/oprofile/buffer_sync.h +++ b/drivers/oprofile/buffer_sync.h | |||
@@ -9,13 +9,13 @@ | |||
9 | 9 | ||
10 | #ifndef OPROFILE_BUFFER_SYNC_H | 10 | #ifndef OPROFILE_BUFFER_SYNC_H |
11 | #define OPROFILE_BUFFER_SYNC_H | 11 | #define OPROFILE_BUFFER_SYNC_H |
12 | 12 | ||
13 | /* add the necessary profiling hooks */ | 13 | /* add the necessary profiling hooks */ |
14 | int sync_start(void); | 14 | int sync_start(void); |
15 | 15 | ||
16 | /* remove the hooks */ | 16 | /* remove the hooks */ |
17 | void sync_stop(void); | 17 | void sync_stop(void); |
18 | 18 | ||
19 | /* sync the given CPU's buffer */ | 19 | /* sync the given CPU's buffer */ |
20 | void sync_buffer(int cpu); | 20 | void sync_buffer(int cpu); |
21 | 21 | ||
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index 7ba39fe20a8a..01d38e78cde1 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/oprofile.h> | 22 | #include <linux/oprofile.h> |
23 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | 25 | ||
26 | #include "event_buffer.h" | 26 | #include "event_buffer.h" |
27 | #include "cpu_buffer.h" | 27 | #include "cpu_buffer.h" |
28 | #include "buffer_sync.h" | 28 | #include "buffer_sync.h" |
@@ -39,7 +39,7 @@ void free_cpu_buffers(void) | |||
39 | { | 39 | { |
40 | int i; | 40 | int i; |
41 | 41 | ||
42 | for_each_online_cpu(i) { | 42 | for_each_possible_cpu(i) { |
43 | vfree(per_cpu(cpu_buffer, i).buffer); | 43 | vfree(per_cpu(cpu_buffer, i).buffer); |
44 | per_cpu(cpu_buffer, i).buffer = NULL; | 44 | per_cpu(cpu_buffer, i).buffer = NULL; |
45 | } | 45 | } |
@@ -61,17 +61,17 @@ void oprofile_cpu_buffer_inc_smpl_lost(void) | |||
61 | int alloc_cpu_buffers(void) | 61 | int alloc_cpu_buffers(void) |
62 | { | 62 | { |
63 | int i; | 63 | int i; |
64 | 64 | ||
65 | unsigned long buffer_size = fs_cpu_buffer_size; | 65 | unsigned long buffer_size = fs_cpu_buffer_size; |
66 | 66 | ||
67 | for_each_online_cpu(i) { | 67 | for_each_possible_cpu(i) { |
68 | struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i); | 68 | struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i); |
69 | 69 | ||
70 | b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size, | 70 | b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size, |
71 | cpu_to_node(i)); | 71 | cpu_to_node(i)); |
72 | if (!b->buffer) | 72 | if (!b->buffer) |
73 | goto fail; | 73 | goto fail; |
74 | 74 | ||
75 | b->last_task = NULL; | 75 | b->last_task = NULL; |
76 | b->last_is_kernel = -1; | 76 | b->last_is_kernel = -1; |
77 | b->tracing = 0; | 77 | b->tracing = 0; |
@@ -125,7 +125,7 @@ void end_cpu_work(void) | |||
125 | } | 125 | } |
126 | 126 | ||
127 | /* Resets the cpu buffer to a sane state. */ | 127 | /* Resets the cpu buffer to a sane state. */ |
128 | void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf) | 128 | void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf) |
129 | { | 129 | { |
130 | /* reset these to invalid values; the next sample | 130 | /* reset these to invalid values; the next sample |
131 | * collected will populate the buffer with proper | 131 | * collected will populate the buffer with proper |
@@ -136,7 +136,7 @@ void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | /* compute number of available slots in cpu_buffer queue */ | 138 | /* compute number of available slots in cpu_buffer queue */ |
139 | static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b) | 139 | static unsigned long nr_available_slots(struct oprofile_cpu_buffer const *b) |
140 | { | 140 | { |
141 | unsigned long head = b->head_pos; | 141 | unsigned long head = b->head_pos; |
142 | unsigned long tail = b->tail_pos; | 142 | unsigned long tail = b->tail_pos; |
@@ -147,7 +147,7 @@ static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b) | |||
147 | return tail + (b->buffer_size - head) - 1; | 147 | return tail + (b->buffer_size - head) - 1; |
148 | } | 148 | } |
149 | 149 | ||
150 | static void increment_head(struct oprofile_cpu_buffer * b) | 150 | static void increment_head(struct oprofile_cpu_buffer *b) |
151 | { | 151 | { |
152 | unsigned long new_head = b->head_pos + 1; | 152 | unsigned long new_head = b->head_pos + 1; |
153 | 153 | ||
@@ -162,17 +162,17 @@ static void increment_head(struct oprofile_cpu_buffer * b) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | static inline void | 164 | static inline void |
165 | add_sample(struct oprofile_cpu_buffer * cpu_buf, | 165 | add_sample(struct oprofile_cpu_buffer *cpu_buf, |
166 | unsigned long pc, unsigned long event) | 166 | unsigned long pc, unsigned long event) |
167 | { | 167 | { |
168 | struct op_sample * entry = &cpu_buf->buffer[cpu_buf->head_pos]; | 168 | struct op_sample *entry = &cpu_buf->buffer[cpu_buf->head_pos]; |
169 | entry->eip = pc; | 169 | entry->eip = pc; |
170 | entry->event = event; | 170 | entry->event = event; |
171 | increment_head(cpu_buf); | 171 | increment_head(cpu_buf); |
172 | } | 172 | } |
173 | 173 | ||
174 | static inline void | 174 | static inline void |
175 | add_code(struct oprofile_cpu_buffer * buffer, unsigned long value) | 175 | add_code(struct oprofile_cpu_buffer *buffer, unsigned long value) |
176 | { | 176 | { |
177 | add_sample(buffer, ESCAPE_CODE, value); | 177 | add_sample(buffer, ESCAPE_CODE, value); |
178 | } | 178 | } |
@@ -186,10 +186,10 @@ add_code(struct oprofile_cpu_buffer * buffer, unsigned long value) | |||
186 | * pc. We tag this in the buffer by generating kernel enter/exit | 186 | * pc. We tag this in the buffer by generating kernel enter/exit |
187 | * events whenever is_kernel changes | 187 | * events whenever is_kernel changes |
188 | */ | 188 | */ |
189 | static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, | 189 | static int log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc, |
190 | int is_kernel, unsigned long event) | 190 | int is_kernel, unsigned long event) |
191 | { | 191 | { |
192 | struct task_struct * task; | 192 | struct task_struct *task; |
193 | 193 | ||
194 | cpu_buf->sample_received++; | 194 | cpu_buf->sample_received++; |
195 | 195 | ||
@@ -218,7 +218,7 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, | |||
218 | cpu_buf->last_task = task; | 218 | cpu_buf->last_task = task; |
219 | add_code(cpu_buf, (unsigned long)task); | 219 | add_code(cpu_buf, (unsigned long)task); |
220 | } | 220 | } |
221 | 221 | ||
222 | add_sample(cpu_buf, pc, event); | 222 | add_sample(cpu_buf, pc, event); |
223 | return 1; | 223 | return 1; |
224 | } | 224 | } |
@@ -235,7 +235,7 @@ static int oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf) | |||
235 | return 1; | 235 | return 1; |
236 | } | 236 | } |
237 | 237 | ||
238 | static void oprofile_end_trace(struct oprofile_cpu_buffer * cpu_buf) | 238 | static void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf) |
239 | { | 239 | { |
240 | cpu_buf->tracing = 0; | 240 | cpu_buf->tracing = 0; |
241 | } | 241 | } |
@@ -270,21 +270,23 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) | |||
270 | 270 | ||
271 | #ifdef CONFIG_OPROFILE_IBS | 271 | #ifdef CONFIG_OPROFILE_IBS |
272 | 272 | ||
273 | #define MAX_IBS_SAMPLE_SIZE 14 | 273 | #define MAX_IBS_SAMPLE_SIZE 14 |
274 | static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf, | 274 | |
275 | unsigned long pc, int is_kernel, unsigned int *ibs, int ibs_code) | 275 | void oprofile_add_ibs_sample(struct pt_regs *const regs, |
276 | unsigned int *const ibs_sample, int ibs_code) | ||
276 | { | 277 | { |
278 | int is_kernel = !user_mode(regs); | ||
279 | struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer); | ||
277 | struct task_struct *task; | 280 | struct task_struct *task; |
278 | 281 | ||
279 | cpu_buf->sample_received++; | 282 | cpu_buf->sample_received++; |
280 | 283 | ||
281 | if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) { | 284 | if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) { |
285 | /* we can't backtrace since we lost the source of this event */ | ||
282 | cpu_buf->sample_lost_overflow++; | 286 | cpu_buf->sample_lost_overflow++; |
283 | return 0; | 287 | return; |
284 | } | 288 | } |
285 | 289 | ||
286 | is_kernel = !!is_kernel; | ||
287 | |||
288 | /* notice a switch from user->kernel or vice versa */ | 290 | /* notice a switch from user->kernel or vice versa */ |
289 | if (cpu_buf->last_is_kernel != is_kernel) { | 291 | if (cpu_buf->last_is_kernel != is_kernel) { |
290 | cpu_buf->last_is_kernel = is_kernel; | 292 | cpu_buf->last_is_kernel = is_kernel; |
@@ -294,7 +296,6 @@ static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf, | |||
294 | /* notice a task switch */ | 296 | /* notice a task switch */ |
295 | if (!is_kernel) { | 297 | if (!is_kernel) { |
296 | task = current; | 298 | task = current; |
297 | |||
298 | if (cpu_buf->last_task != task) { | 299 | if (cpu_buf->last_task != task) { |
299 | cpu_buf->last_task = task; | 300 | cpu_buf->last_task = task; |
300 | add_code(cpu_buf, (unsigned long)task); | 301 | add_code(cpu_buf, (unsigned long)task); |
@@ -302,36 +303,17 @@ static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf, | |||
302 | } | 303 | } |
303 | 304 | ||
304 | add_code(cpu_buf, ibs_code); | 305 | add_code(cpu_buf, ibs_code); |
305 | add_sample(cpu_buf, ibs[0], ibs[1]); | 306 | add_sample(cpu_buf, ibs_sample[0], ibs_sample[1]); |
306 | add_sample(cpu_buf, ibs[2], ibs[3]); | 307 | add_sample(cpu_buf, ibs_sample[2], ibs_sample[3]); |
307 | add_sample(cpu_buf, ibs[4], ibs[5]); | 308 | add_sample(cpu_buf, ibs_sample[4], ibs_sample[5]); |
308 | 309 | ||
309 | if (ibs_code == IBS_OP_BEGIN) { | 310 | if (ibs_code == IBS_OP_BEGIN) { |
310 | add_sample(cpu_buf, ibs[6], ibs[7]); | 311 | add_sample(cpu_buf, ibs_sample[6], ibs_sample[7]); |
311 | add_sample(cpu_buf, ibs[8], ibs[9]); | 312 | add_sample(cpu_buf, ibs_sample[8], ibs_sample[9]); |
312 | add_sample(cpu_buf, ibs[10], ibs[11]); | 313 | add_sample(cpu_buf, ibs_sample[10], ibs_sample[11]); |
313 | } | ||
314 | |||
315 | return 1; | ||
316 | } | ||
317 | |||
318 | void oprofile_add_ibs_sample(struct pt_regs *const regs, | ||
319 | unsigned int * const ibs_sample, u8 code) | ||
320 | { | ||
321 | int is_kernel = !user_mode(regs); | ||
322 | unsigned long pc = profile_pc(regs); | ||
323 | |||
324 | struct oprofile_cpu_buffer *cpu_buf = | ||
325 | &per_cpu(cpu_buffer, smp_processor_id()); | ||
326 | |||
327 | if (!backtrace_depth) { | ||
328 | log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code); | ||
329 | return; | ||
330 | } | 314 | } |
331 | 315 | ||
332 | /* if log_sample() fails we can't backtrace since we lost the source | 316 | if (backtrace_depth) |
333 | * of this event */ | ||
334 | if (log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code)) | ||
335 | oprofile_ops.backtrace(regs, backtrace_depth); | 317 | oprofile_ops.backtrace(regs, backtrace_depth); |
336 | } | 318 | } |
337 | 319 | ||
@@ -376,11 +358,16 @@ void oprofile_add_trace(unsigned long pc) | |||
376 | */ | 358 | */ |
377 | static void wq_sync_buffer(struct work_struct *work) | 359 | static void wq_sync_buffer(struct work_struct *work) |
378 | { | 360 | { |
379 | struct oprofile_cpu_buffer * b = | 361 | struct oprofile_cpu_buffer *b = |
380 | container_of(work, struct oprofile_cpu_buffer, work.work); | 362 | container_of(work, struct oprofile_cpu_buffer, work.work); |
381 | if (b->cpu != smp_processor_id()) { | 363 | if (b->cpu != smp_processor_id()) { |
382 | printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n", | 364 | printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n", |
383 | smp_processor_id(), b->cpu); | 365 | smp_processor_id(), b->cpu); |
366 | |||
367 | if (!cpu_online(b->cpu)) { | ||
368 | cancel_delayed_work(&b->work); | ||
369 | return; | ||
370 | } | ||
384 | } | 371 | } |
385 | sync_buffer(b->cpu); | 372 | sync_buffer(b->cpu); |
386 | 373 | ||
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index 9c44d004da69..d3cc26264db5 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h | |||
@@ -15,9 +15,9 @@ | |||
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/cache.h> | 16 | #include <linux/cache.h> |
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | 18 | ||
19 | struct task_struct; | 19 | struct task_struct; |
20 | 20 | ||
21 | int alloc_cpu_buffers(void); | 21 | int alloc_cpu_buffers(void); |
22 | void free_cpu_buffers(void); | 22 | void free_cpu_buffers(void); |
23 | 23 | ||
@@ -31,15 +31,15 @@ struct op_sample { | |||
31 | unsigned long eip; | 31 | unsigned long eip; |
32 | unsigned long event; | 32 | unsigned long event; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | struct oprofile_cpu_buffer { | 35 | struct oprofile_cpu_buffer { |
36 | volatile unsigned long head_pos; | 36 | volatile unsigned long head_pos; |
37 | volatile unsigned long tail_pos; | 37 | volatile unsigned long tail_pos; |
38 | unsigned long buffer_size; | 38 | unsigned long buffer_size; |
39 | struct task_struct * last_task; | 39 | struct task_struct *last_task; |
40 | int last_is_kernel; | 40 | int last_is_kernel; |
41 | int tracing; | 41 | int tracing; |
42 | struct op_sample * buffer; | 42 | struct op_sample *buffer; |
43 | unsigned long sample_received; | 43 | unsigned long sample_received; |
44 | unsigned long sample_lost_overflow; | 44 | unsigned long sample_lost_overflow; |
45 | unsigned long backtrace_aborted; | 45 | unsigned long backtrace_aborted; |
@@ -50,7 +50,7 @@ struct oprofile_cpu_buffer { | |||
50 | 50 | ||
51 | DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); | 51 | DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); |
52 | 52 | ||
53 | void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf); | 53 | void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf); |
54 | 54 | ||
55 | /* transient events for the CPU buffer -> event buffer */ | 55 | /* transient events for the CPU buffer -> event buffer */ |
56 | #define CPU_IS_KERNEL 1 | 56 | #define CPU_IS_KERNEL 1 |
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c index 8d692a5c8e73..d962ba0dd87a 100644 --- a/drivers/oprofile/event_buffer.c +++ b/drivers/oprofile/event_buffer.c | |||
@@ -19,16 +19,16 @@ | |||
19 | #include <linux/dcookies.h> | 19 | #include <linux/dcookies.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | 22 | ||
23 | #include "oprof.h" | 23 | #include "oprof.h" |
24 | #include "event_buffer.h" | 24 | #include "event_buffer.h" |
25 | #include "oprofile_stats.h" | 25 | #include "oprofile_stats.h" |
26 | 26 | ||
27 | DEFINE_MUTEX(buffer_mutex); | 27 | DEFINE_MUTEX(buffer_mutex); |
28 | 28 | ||
29 | static unsigned long buffer_opened; | 29 | static unsigned long buffer_opened; |
30 | static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); | 30 | static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); |
31 | static unsigned long * event_buffer; | 31 | static unsigned long *event_buffer; |
32 | static unsigned long buffer_size; | 32 | static unsigned long buffer_size; |
33 | static unsigned long buffer_watershed; | 33 | static unsigned long buffer_watershed; |
34 | static size_t buffer_pos; | 34 | static size_t buffer_pos; |
@@ -66,7 +66,7 @@ void wake_up_buffer_waiter(void) | |||
66 | mutex_unlock(&buffer_mutex); | 66 | mutex_unlock(&buffer_mutex); |
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
70 | int alloc_event_buffer(void) | 70 | int alloc_event_buffer(void) |
71 | { | 71 | { |
72 | int err = -ENOMEM; | 72 | int err = -ENOMEM; |
@@ -76,13 +76,13 @@ int alloc_event_buffer(void) | |||
76 | buffer_size = fs_buffer_size; | 76 | buffer_size = fs_buffer_size; |
77 | buffer_watershed = fs_buffer_watershed; | 77 | buffer_watershed = fs_buffer_watershed; |
78 | spin_unlock_irqrestore(&oprofilefs_lock, flags); | 78 | spin_unlock_irqrestore(&oprofilefs_lock, flags); |
79 | 79 | ||
80 | if (buffer_watershed >= buffer_size) | 80 | if (buffer_watershed >= buffer_size) |
81 | return -EINVAL; | 81 | return -EINVAL; |
82 | 82 | ||
83 | event_buffer = vmalloc(sizeof(unsigned long) * buffer_size); | 83 | event_buffer = vmalloc(sizeof(unsigned long) * buffer_size); |
84 | if (!event_buffer) | 84 | if (!event_buffer) |
85 | goto out; | 85 | goto out; |
86 | 86 | ||
87 | err = 0; | 87 | err = 0; |
88 | out: | 88 | out: |
@@ -97,8 +97,8 @@ void free_event_buffer(void) | |||
97 | event_buffer = NULL; | 97 | event_buffer = NULL; |
98 | } | 98 | } |
99 | 99 | ||
100 | 100 | ||
101 | static int event_buffer_open(struct inode * inode, struct file * file) | 101 | static int event_buffer_open(struct inode *inode, struct file *file) |
102 | { | 102 | { |
103 | int err = -EPERM; | 103 | int err = -EPERM; |
104 | 104 | ||
@@ -116,14 +116,14 @@ static int event_buffer_open(struct inode * inode, struct file * file) | |||
116 | file->private_data = dcookie_register(); | 116 | file->private_data = dcookie_register(); |
117 | if (!file->private_data) | 117 | if (!file->private_data) |
118 | goto out; | 118 | goto out; |
119 | 119 | ||
120 | if ((err = oprofile_setup())) | 120 | if ((err = oprofile_setup())) |
121 | goto fail; | 121 | goto fail; |
122 | 122 | ||
123 | /* NB: the actual start happens from userspace | 123 | /* NB: the actual start happens from userspace |
124 | * echo 1 >/dev/oprofile/enable | 124 | * echo 1 >/dev/oprofile/enable |
125 | */ | 125 | */ |
126 | 126 | ||
127 | return 0; | 127 | return 0; |
128 | 128 | ||
129 | fail: | 129 | fail: |
@@ -134,7 +134,7 @@ out: | |||
134 | } | 134 | } |
135 | 135 | ||
136 | 136 | ||
137 | static int event_buffer_release(struct inode * inode, struct file * file) | 137 | static int event_buffer_release(struct inode *inode, struct file *file) |
138 | { | 138 | { |
139 | oprofile_stop(); | 139 | oprofile_stop(); |
140 | oprofile_shutdown(); | 140 | oprofile_shutdown(); |
@@ -146,8 +146,8 @@ static int event_buffer_release(struct inode * inode, struct file * file) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | 148 | ||
149 | static ssize_t event_buffer_read(struct file * file, char __user * buf, | 149 | static ssize_t event_buffer_read(struct file *file, char __user *buf, |
150 | size_t count, loff_t * offset) | 150 | size_t count, loff_t *offset) |
151 | { | 151 | { |
152 | int retval = -EINVAL; | 152 | int retval = -EINVAL; |
153 | size_t const max = buffer_size * sizeof(unsigned long); | 153 | size_t const max = buffer_size * sizeof(unsigned long); |
@@ -172,18 +172,18 @@ static ssize_t event_buffer_read(struct file * file, char __user * buf, | |||
172 | retval = -EFAULT; | 172 | retval = -EFAULT; |
173 | 173 | ||
174 | count = buffer_pos * sizeof(unsigned long); | 174 | count = buffer_pos * sizeof(unsigned long); |
175 | 175 | ||
176 | if (copy_to_user(buf, event_buffer, count)) | 176 | if (copy_to_user(buf, event_buffer, count)) |
177 | goto out; | 177 | goto out; |
178 | 178 | ||
179 | retval = count; | 179 | retval = count; |
180 | buffer_pos = 0; | 180 | buffer_pos = 0; |
181 | 181 | ||
182 | out: | 182 | out: |
183 | mutex_unlock(&buffer_mutex); | 183 | mutex_unlock(&buffer_mutex); |
184 | return retval; | 184 | return retval; |
185 | } | 185 | } |
186 | 186 | ||
187 | const struct file_operations event_buffer_fops = { | 187 | const struct file_operations event_buffer_fops = { |
188 | .open = event_buffer_open, | 188 | .open = event_buffer_open, |
189 | .release = event_buffer_release, | 189 | .release = event_buffer_release, |
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h index 84bf324c5771..4e70749f8d16 100644 --- a/drivers/oprofile/event_buffer.h +++ b/drivers/oprofile/event_buffer.h | |||
@@ -10,13 +10,13 @@ | |||
10 | #ifndef EVENT_BUFFER_H | 10 | #ifndef EVENT_BUFFER_H |
11 | #define EVENT_BUFFER_H | 11 | #define EVENT_BUFFER_H |
12 | 12 | ||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <asm/mutex.h> | 14 | #include <asm/mutex.h> |
15 | 15 | ||
16 | int alloc_event_buffer(void); | 16 | int alloc_event_buffer(void); |
17 | 17 | ||
18 | void free_event_buffer(void); | 18 | void free_event_buffer(void); |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * Add data to the event buffer. | 21 | * Add data to the event buffer. |
22 | * The data passed is free-form, but typically consists of | 22 | * The data passed is free-form, but typically consists of |
@@ -31,10 +31,10 @@ void wake_up_buffer_waiter(void); | |||
31 | #define NO_COOKIE 0UL | 31 | #define NO_COOKIE 0UL |
32 | 32 | ||
33 | extern const struct file_operations event_buffer_fops; | 33 | extern const struct file_operations event_buffer_fops; |
34 | 34 | ||
35 | /* mutex between sync_cpu_buffers() and the | 35 | /* mutex between sync_cpu_buffers() and the |
36 | * file reading code. | 36 | * file reading code. |
37 | */ | 37 | */ |
38 | extern struct mutex buffer_mutex; | 38 | extern struct mutex buffer_mutex; |
39 | 39 | ||
40 | #endif /* EVENT_BUFFER_H */ | 40 | #endif /* EVENT_BUFFER_H */ |
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index 2c645170f06e..cd375907f26f 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "cpu_buffer.h" | 19 | #include "cpu_buffer.h" |
20 | #include "buffer_sync.h" | 20 | #include "buffer_sync.h" |
21 | #include "oprofile_stats.h" | 21 | #include "oprofile_stats.h" |
22 | 22 | ||
23 | struct oprofile_operations oprofile_ops; | 23 | struct oprofile_operations oprofile_ops; |
24 | 24 | ||
25 | unsigned long oprofile_started; | 25 | unsigned long oprofile_started; |
@@ -36,7 +36,7 @@ static int timer = 0; | |||
36 | int oprofile_setup(void) | 36 | int oprofile_setup(void) |
37 | { | 37 | { |
38 | int err; | 38 | int err; |
39 | 39 | ||
40 | mutex_lock(&start_mutex); | 40 | mutex_lock(&start_mutex); |
41 | 41 | ||
42 | if ((err = alloc_cpu_buffers())) | 42 | if ((err = alloc_cpu_buffers())) |
@@ -44,10 +44,10 @@ int oprofile_setup(void) | |||
44 | 44 | ||
45 | if ((err = alloc_event_buffer())) | 45 | if ((err = alloc_event_buffer())) |
46 | goto out1; | 46 | goto out1; |
47 | 47 | ||
48 | if (oprofile_ops.setup && (err = oprofile_ops.setup())) | 48 | if (oprofile_ops.setup && (err = oprofile_ops.setup())) |
49 | goto out2; | 49 | goto out2; |
50 | 50 | ||
51 | /* Note even though this starts part of the | 51 | /* Note even though this starts part of the |
52 | * profiling overhead, it's necessary to prevent | 52 | * profiling overhead, it's necessary to prevent |
53 | * us missing task deaths and eventually oopsing | 53 | * us missing task deaths and eventually oopsing |
@@ -74,7 +74,7 @@ post_sync: | |||
74 | is_setup = 1; | 74 | is_setup = 1; |
75 | mutex_unlock(&start_mutex); | 75 | mutex_unlock(&start_mutex); |
76 | return 0; | 76 | return 0; |
77 | 77 | ||
78 | out3: | 78 | out3: |
79 | if (oprofile_ops.shutdown) | 79 | if (oprofile_ops.shutdown) |
80 | oprofile_ops.shutdown(); | 80 | oprofile_ops.shutdown(); |
@@ -92,17 +92,17 @@ out: | |||
92 | int oprofile_start(void) | 92 | int oprofile_start(void) |
93 | { | 93 | { |
94 | int err = -EINVAL; | 94 | int err = -EINVAL; |
95 | 95 | ||
96 | mutex_lock(&start_mutex); | 96 | mutex_lock(&start_mutex); |
97 | 97 | ||
98 | if (!is_setup) | 98 | if (!is_setup) |
99 | goto out; | 99 | goto out; |
100 | 100 | ||
101 | err = 0; | 101 | err = 0; |
102 | 102 | ||
103 | if (oprofile_started) | 103 | if (oprofile_started) |
104 | goto out; | 104 | goto out; |
105 | 105 | ||
106 | oprofile_reset_stats(); | 106 | oprofile_reset_stats(); |
107 | 107 | ||
108 | if ((err = oprofile_ops.start())) | 108 | if ((err = oprofile_ops.start())) |
@@ -114,7 +114,7 @@ out: | |||
114 | return err; | 114 | return err; |
115 | } | 115 | } |
116 | 116 | ||
117 | 117 | ||
118 | /* echo 0>/dev/oprofile/enable */ | 118 | /* echo 0>/dev/oprofile/enable */ |
119 | void oprofile_stop(void) | 119 | void oprofile_stop(void) |
120 | { | 120 | { |
@@ -204,13 +204,13 @@ static void __exit oprofile_exit(void) | |||
204 | oprofile_arch_exit(); | 204 | oprofile_arch_exit(); |
205 | } | 205 | } |
206 | 206 | ||
207 | 207 | ||
208 | module_init(oprofile_init); | 208 | module_init(oprofile_init); |
209 | module_exit(oprofile_exit); | 209 | module_exit(oprofile_exit); |
210 | 210 | ||
211 | module_param_named(timer, timer, int, 0644); | 211 | module_param_named(timer, timer, int, 0644); |
212 | MODULE_PARM_DESC(timer, "force use of timer interrupt"); | 212 | MODULE_PARM_DESC(timer, "force use of timer interrupt"); |
213 | 213 | ||
214 | MODULE_LICENSE("GPL"); | 214 | MODULE_LICENSE("GPL"); |
215 | MODULE_AUTHOR("John Levon <levon@movementarian.org>"); | 215 | MODULE_AUTHOR("John Levon <levon@movementarian.org>"); |
216 | MODULE_DESCRIPTION("OProfile system profiler"); | 216 | MODULE_DESCRIPTION("OProfile system profiler"); |
diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h index 18323650806e..5df0c21a608f 100644 --- a/drivers/oprofile/oprof.h +++ b/drivers/oprofile/oprof.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #define OPROF_H | 11 | #define OPROF_H |
12 | 12 | ||
13 | int oprofile_setup(void); | 13 | int oprofile_setup(void); |
14 | void oprofile_shutdown(void); | 14 | void oprofile_shutdown(void); |
15 | 15 | ||
16 | int oprofilefs_register(void); | 16 | int oprofilefs_register(void); |
17 | void oprofilefs_unregister(void); | 17 | void oprofilefs_unregister(void); |
@@ -20,20 +20,20 @@ int oprofile_start(void); | |||
20 | void oprofile_stop(void); | 20 | void oprofile_stop(void); |
21 | 21 | ||
22 | struct oprofile_operations; | 22 | struct oprofile_operations; |
23 | 23 | ||
24 | extern unsigned long fs_buffer_size; | 24 | extern unsigned long fs_buffer_size; |
25 | extern unsigned long fs_cpu_buffer_size; | 25 | extern unsigned long fs_cpu_buffer_size; |
26 | extern unsigned long fs_buffer_watershed; | 26 | extern unsigned long fs_buffer_watershed; |
27 | extern struct oprofile_operations oprofile_ops; | 27 | extern struct oprofile_operations oprofile_ops; |
28 | extern unsigned long oprofile_started; | 28 | extern unsigned long oprofile_started; |
29 | extern unsigned long backtrace_depth; | 29 | extern unsigned long backtrace_depth; |
30 | 30 | ||
31 | struct super_block; | 31 | struct super_block; |
32 | struct dentry; | 32 | struct dentry; |
33 | 33 | ||
34 | void oprofile_create_files(struct super_block * sb, struct dentry * root); | 34 | void oprofile_create_files(struct super_block *sb, struct dentry *root); |
35 | void oprofile_timer_init(struct oprofile_operations * ops); | 35 | void oprofile_timer_init(struct oprofile_operations *ops); |
36 | 36 | ||
37 | int oprofile_set_backtrace(unsigned long depth); | 37 | int oprofile_set_backtrace(unsigned long depth); |
38 | 38 | ||
39 | #endif /* OPROF_H */ | 39 | #endif /* OPROF_H */ |
diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index ef953ba5ab6b..cc106d503ace 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c | |||
@@ -13,18 +13,18 @@ | |||
13 | #include "event_buffer.h" | 13 | #include "event_buffer.h" |
14 | #include "oprofile_stats.h" | 14 | #include "oprofile_stats.h" |
15 | #include "oprof.h" | 15 | #include "oprof.h" |
16 | 16 | ||
17 | unsigned long fs_buffer_size = 131072; | 17 | unsigned long fs_buffer_size = 131072; |
18 | unsigned long fs_cpu_buffer_size = 8192; | 18 | unsigned long fs_cpu_buffer_size = 8192; |
19 | unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ | 19 | unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ |
20 | 20 | ||
21 | static ssize_t depth_read(struct file * file, char __user * buf, size_t count, loff_t * offset) | 21 | static ssize_t depth_read(struct file *file, char __user *buf, size_t count, loff_t *offset) |
22 | { | 22 | { |
23 | return oprofilefs_ulong_to_user(backtrace_depth, buf, count, offset); | 23 | return oprofilefs_ulong_to_user(backtrace_depth, buf, count, offset); |
24 | } | 24 | } |
25 | 25 | ||
26 | 26 | ||
27 | static ssize_t depth_write(struct file * file, char const __user * buf, size_t count, loff_t * offset) | 27 | static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) |
28 | { | 28 | { |
29 | unsigned long val; | 29 | unsigned long val; |
30 | int retval; | 30 | int retval; |
@@ -49,8 +49,8 @@ static const struct file_operations depth_fops = { | |||
49 | .write = depth_write | 49 | .write = depth_write |
50 | }; | 50 | }; |
51 | 51 | ||
52 | 52 | ||
53 | static ssize_t pointer_size_read(struct file * file, char __user * buf, size_t count, loff_t * offset) | 53 | static ssize_t pointer_size_read(struct file *file, char __user *buf, size_t count, loff_t *offset) |
54 | { | 54 | { |
55 | return oprofilefs_ulong_to_user(sizeof(void *), buf, count, offset); | 55 | return oprofilefs_ulong_to_user(sizeof(void *), buf, count, offset); |
56 | } | 56 | } |
@@ -61,24 +61,24 @@ static const struct file_operations pointer_size_fops = { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | 63 | ||
64 | static ssize_t cpu_type_read(struct file * file, char __user * buf, size_t count, loff_t * offset) | 64 | static ssize_t cpu_type_read(struct file *file, char __user *buf, size_t count, loff_t *offset) |
65 | { | 65 | { |
66 | return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset); | 66 | return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset); |
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
70 | static const struct file_operations cpu_type_fops = { | 70 | static const struct file_operations cpu_type_fops = { |
71 | .read = cpu_type_read, | 71 | .read = cpu_type_read, |
72 | }; | 72 | }; |
73 | 73 | ||
74 | 74 | ||
75 | static ssize_t enable_read(struct file * file, char __user * buf, size_t count, loff_t * offset) | 75 | static ssize_t enable_read(struct file *file, char __user *buf, size_t count, loff_t *offset) |
76 | { | 76 | { |
77 | return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset); | 77 | return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset); |
78 | } | 78 | } |
79 | 79 | ||
80 | 80 | ||
81 | static ssize_t enable_write(struct file * file, char const __user * buf, size_t count, loff_t * offset) | 81 | static ssize_t enable_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) |
82 | { | 82 | { |
83 | unsigned long val; | 83 | unsigned long val; |
84 | int retval; | 84 | int retval; |
@@ -89,7 +89,7 @@ static ssize_t enable_write(struct file * file, char const __user * buf, size_t | |||
89 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 89 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
90 | if (retval) | 90 | if (retval) |
91 | return retval; | 91 | return retval; |
92 | 92 | ||
93 | if (val) | 93 | if (val) |
94 | retval = oprofile_start(); | 94 | retval = oprofile_start(); |
95 | else | 95 | else |
@@ -100,14 +100,14 @@ static ssize_t enable_write(struct file * file, char const __user * buf, size_t | |||
100 | return count; | 100 | return count; |
101 | } | 101 | } |
102 | 102 | ||
103 | 103 | ||
104 | static const struct file_operations enable_fops = { | 104 | static const struct file_operations enable_fops = { |
105 | .read = enable_read, | 105 | .read = enable_read, |
106 | .write = enable_write, | 106 | .write = enable_write, |
107 | }; | 107 | }; |
108 | 108 | ||
109 | 109 | ||
110 | static ssize_t dump_write(struct file * file, char const __user * buf, size_t count, loff_t * offset) | 110 | static ssize_t dump_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) |
111 | { | 111 | { |
112 | wake_up_buffer_waiter(); | 112 | wake_up_buffer_waiter(); |
113 | return count; | 113 | return count; |
@@ -117,8 +117,8 @@ static ssize_t dump_write(struct file * file, char const __user * buf, size_t co | |||
117 | static const struct file_operations dump_fops = { | 117 | static const struct file_operations dump_fops = { |
118 | .write = dump_write, | 118 | .write = dump_write, |
119 | }; | 119 | }; |
120 | 120 | ||
121 | void oprofile_create_files(struct super_block * sb, struct dentry * root) | 121 | void oprofile_create_files(struct super_block *sb, struct dentry *root) |
122 | { | 122 | { |
123 | oprofilefs_create_file(sb, root, "enable", &enable_fops); | 123 | oprofilefs_create_file(sb, root, "enable", &enable_fops); |
124 | oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); | 124 | oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); |
@@ -126,7 +126,7 @@ void oprofile_create_files(struct super_block * sb, struct dentry * root) | |||
126 | oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); | 126 | oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); |
127 | oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); | 127 | oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); |
128 | oprofilefs_create_ulong(sb, root, "cpu_buffer_size", &fs_cpu_buffer_size); | 128 | oprofilefs_create_ulong(sb, root, "cpu_buffer_size", &fs_cpu_buffer_size); |
129 | oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops); | 129 | oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops); |
130 | oprofilefs_create_file(sb, root, "backtrace_depth", &depth_fops); | 130 | oprofilefs_create_file(sb, root, "backtrace_depth", &depth_fops); |
131 | oprofilefs_create_file(sb, root, "pointer_size", &pointer_size_fops); | 131 | oprofilefs_create_file(sb, root, "pointer_size", &pointer_size_fops); |
132 | oprofile_create_stats_files(sb, root); | 132 | oprofile_create_stats_files(sb, root); |
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c index f99b28e7b79a..e1f6ce03705e 100644 --- a/drivers/oprofile/oprofile_stats.c +++ b/drivers/oprofile/oprofile_stats.c | |||
@@ -11,17 +11,17 @@ | |||
11 | #include <linux/smp.h> | 11 | #include <linux/smp.h> |
12 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
13 | #include <linux/threads.h> | 13 | #include <linux/threads.h> |
14 | 14 | ||
15 | #include "oprofile_stats.h" | 15 | #include "oprofile_stats.h" |
16 | #include "cpu_buffer.h" | 16 | #include "cpu_buffer.h" |
17 | 17 | ||
18 | struct oprofile_stat_struct oprofile_stats; | 18 | struct oprofile_stat_struct oprofile_stats; |
19 | 19 | ||
20 | void oprofile_reset_stats(void) | 20 | void oprofile_reset_stats(void) |
21 | { | 21 | { |
22 | struct oprofile_cpu_buffer * cpu_buf; | 22 | struct oprofile_cpu_buffer *cpu_buf; |
23 | int i; | 23 | int i; |
24 | 24 | ||
25 | for_each_possible_cpu(i) { | 25 | for_each_possible_cpu(i) { |
26 | cpu_buf = &per_cpu(cpu_buffer, i); | 26 | cpu_buf = &per_cpu(cpu_buffer, i); |
27 | cpu_buf->sample_received = 0; | 27 | cpu_buf->sample_received = 0; |
@@ -29,18 +29,18 @@ void oprofile_reset_stats(void) | |||
29 | cpu_buf->backtrace_aborted = 0; | 29 | cpu_buf->backtrace_aborted = 0; |
30 | cpu_buf->sample_invalid_eip = 0; | 30 | cpu_buf->sample_invalid_eip = 0; |
31 | } | 31 | } |
32 | 32 | ||
33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); | 33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); |
34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); | 34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); |
35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); | 35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); |
36 | } | 36 | } |
37 | 37 | ||
38 | 38 | ||
39 | void oprofile_create_stats_files(struct super_block * sb, struct dentry * root) | 39 | void oprofile_create_stats_files(struct super_block *sb, struct dentry *root) |
40 | { | 40 | { |
41 | struct oprofile_cpu_buffer * cpu_buf; | 41 | struct oprofile_cpu_buffer *cpu_buf; |
42 | struct dentry * cpudir; | 42 | struct dentry *cpudir; |
43 | struct dentry * dir; | 43 | struct dentry *dir; |
44 | char buf[10]; | 44 | char buf[10]; |
45 | int i; | 45 | int i; |
46 | 46 | ||
@@ -52,7 +52,7 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root) | |||
52 | cpu_buf = &per_cpu(cpu_buffer, i); | 52 | cpu_buf = &per_cpu(cpu_buffer, i); |
53 | snprintf(buf, 10, "cpu%d", i); | 53 | snprintf(buf, 10, "cpu%d", i); |
54 | cpudir = oprofilefs_mkdir(sb, dir, buf); | 54 | cpudir = oprofilefs_mkdir(sb, dir, buf); |
55 | 55 | ||
56 | /* Strictly speaking access to these ulongs is racy, | 56 | /* Strictly speaking access to these ulongs is racy, |
57 | * but we can't simply lock them, and they are | 57 | * but we can't simply lock them, and they are |
58 | * informational only. | 58 | * informational only. |
@@ -66,7 +66,7 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root) | |||
66 | oprofilefs_create_ro_ulong(sb, cpudir, "sample_invalid_eip", | 66 | oprofilefs_create_ro_ulong(sb, cpudir, "sample_invalid_eip", |
67 | &cpu_buf->sample_invalid_eip); | 67 | &cpu_buf->sample_invalid_eip); |
68 | } | 68 | } |
69 | 69 | ||
70 | oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mm", | 70 | oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mm", |
71 | &oprofile_stats.sample_lost_no_mm); | 71 | &oprofile_stats.sample_lost_no_mm); |
72 | oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mapping", | 72 | oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mapping", |
diff --git a/drivers/oprofile/oprofile_stats.h b/drivers/oprofile/oprofile_stats.h index 6d755a633f15..3da0d08dc1f9 100644 --- a/drivers/oprofile/oprofile_stats.h +++ b/drivers/oprofile/oprofile_stats.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #define OPROFILE_STATS_H | 11 | #define OPROFILE_STATS_H |
12 | 12 | ||
13 | #include <asm/atomic.h> | 13 | #include <asm/atomic.h> |
14 | 14 | ||
15 | struct oprofile_stat_struct { | 15 | struct oprofile_stat_struct { |
16 | atomic_t sample_lost_no_mm; | 16 | atomic_t sample_lost_no_mm; |
17 | atomic_t sample_lost_no_mapping; | 17 | atomic_t sample_lost_no_mapping; |
@@ -20,14 +20,14 @@ struct oprofile_stat_struct { | |||
20 | }; | 20 | }; |
21 | 21 | ||
22 | extern struct oprofile_stat_struct oprofile_stats; | 22 | extern struct oprofile_stat_struct oprofile_stats; |
23 | 23 | ||
24 | /* reset all stats to zero */ | 24 | /* reset all stats to zero */ |
25 | void oprofile_reset_stats(void); | 25 | void oprofile_reset_stats(void); |
26 | 26 | ||
27 | struct super_block; | 27 | struct super_block; |
28 | struct dentry; | 28 | struct dentry; |
29 | 29 | ||
30 | /* create the stats/ dir */ | 30 | /* create the stats/ dir */ |
31 | void oprofile_create_stats_files(struct super_block * sb, struct dentry * root); | 31 | void oprofile_create_stats_files(struct super_block *sb, struct dentry *root); |
32 | 32 | ||
33 | #endif /* OPROFILE_STATS_H */ | 33 | #endif /* OPROFILE_STATS_H */ |
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index 8543cb26cf34..ddc4c59f02dc 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c | |||
@@ -23,9 +23,9 @@ | |||
23 | 23 | ||
24 | DEFINE_SPINLOCK(oprofilefs_lock); | 24 | DEFINE_SPINLOCK(oprofilefs_lock); |
25 | 25 | ||
26 | static struct inode * oprofilefs_get_inode(struct super_block * sb, int mode) | 26 | static struct inode *oprofilefs_get_inode(struct super_block *sb, int mode) |
27 | { | 27 | { |
28 | struct inode * inode = new_inode(sb); | 28 | struct inode *inode = new_inode(sb); |
29 | 29 | ||
30 | if (inode) { | 30 | if (inode) { |
31 | inode->i_mode = mode; | 31 | inode->i_mode = mode; |
@@ -44,7 +44,7 @@ static struct super_operations s_ops = { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | 46 | ||
47 | ssize_t oprofilefs_str_to_user(char const * str, char __user * buf, size_t count, loff_t * offset) | 47 | ssize_t oprofilefs_str_to_user(char const *str, char __user *buf, size_t count, loff_t *offset) |
48 | { | 48 | { |
49 | return simple_read_from_buffer(buf, count, offset, str, strlen(str)); | 49 | return simple_read_from_buffer(buf, count, offset, str, strlen(str)); |
50 | } | 50 | } |
@@ -52,7 +52,7 @@ ssize_t oprofilefs_str_to_user(char const * str, char __user * buf, size_t count | |||
52 | 52 | ||
53 | #define TMPBUFSIZE 50 | 53 | #define TMPBUFSIZE 50 |
54 | 54 | ||
55 | ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t count, loff_t * offset) | 55 | ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset) |
56 | { | 56 | { |
57 | char tmpbuf[TMPBUFSIZE]; | 57 | char tmpbuf[TMPBUFSIZE]; |
58 | size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val); | 58 | size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val); |
@@ -62,7 +62,7 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t co | |||
62 | } | 62 | } |
63 | 63 | ||
64 | 64 | ||
65 | int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count) | 65 | int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) |
66 | { | 66 | { |
67 | char tmpbuf[TMPBUFSIZE]; | 67 | char tmpbuf[TMPBUFSIZE]; |
68 | unsigned long flags; | 68 | unsigned long flags; |
@@ -85,16 +85,16 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz | |||
85 | } | 85 | } |
86 | 86 | ||
87 | 87 | ||
88 | static ssize_t ulong_read_file(struct file * file, char __user * buf, size_t count, loff_t * offset) | 88 | static ssize_t ulong_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset) |
89 | { | 89 | { |
90 | unsigned long * val = file->private_data; | 90 | unsigned long *val = file->private_data; |
91 | return oprofilefs_ulong_to_user(*val, buf, count, offset); | 91 | return oprofilefs_ulong_to_user(*val, buf, count, offset); |
92 | } | 92 | } |
93 | 93 | ||
94 | 94 | ||
95 | static ssize_t ulong_write_file(struct file * file, char const __user * buf, size_t count, loff_t * offset) | 95 | static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_t count, loff_t *offset) |
96 | { | 96 | { |
97 | unsigned long * value = file->private_data; | 97 | unsigned long *value = file->private_data; |
98 | int retval; | 98 | int retval; |
99 | 99 | ||
100 | if (*offset) | 100 | if (*offset) |
@@ -108,7 +108,7 @@ static ssize_t ulong_write_file(struct file * file, char const __user * buf, siz | |||
108 | } | 108 | } |
109 | 109 | ||
110 | 110 | ||
111 | static int default_open(struct inode * inode, struct file * filp) | 111 | static int default_open(struct inode *inode, struct file *filp) |
112 | { | 112 | { |
113 | if (inode->i_private) | 113 | if (inode->i_private) |
114 | filp->private_data = inode->i_private; | 114 | filp->private_data = inode->i_private; |
@@ -129,12 +129,12 @@ static const struct file_operations ulong_ro_fops = { | |||
129 | }; | 129 | }; |
130 | 130 | ||
131 | 131 | ||
132 | static struct dentry * __oprofilefs_create_file(struct super_block * sb, | 132 | static struct dentry *__oprofilefs_create_file(struct super_block *sb, |
133 | struct dentry * root, char const * name, const struct file_operations * fops, | 133 | struct dentry *root, char const *name, const struct file_operations *fops, |
134 | int perm) | 134 | int perm) |
135 | { | 135 | { |
136 | struct dentry * dentry; | 136 | struct dentry *dentry; |
137 | struct inode * inode; | 137 | struct inode *inode; |
138 | 138 | ||
139 | dentry = d_alloc_name(root, name); | 139 | dentry = d_alloc_name(root, name); |
140 | if (!dentry) | 140 | if (!dentry) |
@@ -150,10 +150,10 @@ static struct dentry * __oprofilefs_create_file(struct super_block * sb, | |||
150 | } | 150 | } |
151 | 151 | ||
152 | 152 | ||
153 | int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, | 153 | int oprofilefs_create_ulong(struct super_block *sb, struct dentry *root, |
154 | char const * name, unsigned long * val) | 154 | char const *name, unsigned long *val) |
155 | { | 155 | { |
156 | struct dentry * d = __oprofilefs_create_file(sb, root, name, | 156 | struct dentry *d = __oprofilefs_create_file(sb, root, name, |
157 | &ulong_fops, 0644); | 157 | &ulong_fops, 0644); |
158 | if (!d) | 158 | if (!d) |
159 | return -EFAULT; | 159 | return -EFAULT; |
@@ -163,10 +163,10 @@ int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, | |||
163 | } | 163 | } |
164 | 164 | ||
165 | 165 | ||
166 | int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root, | 166 | int oprofilefs_create_ro_ulong(struct super_block *sb, struct dentry *root, |
167 | char const * name, unsigned long * val) | 167 | char const *name, unsigned long *val) |
168 | { | 168 | { |
169 | struct dentry * d = __oprofilefs_create_file(sb, root, name, | 169 | struct dentry *d = __oprofilefs_create_file(sb, root, name, |
170 | &ulong_ro_fops, 0444); | 170 | &ulong_ro_fops, 0444); |
171 | if (!d) | 171 | if (!d) |
172 | return -EFAULT; | 172 | return -EFAULT; |
@@ -176,23 +176,23 @@ int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root, | |||
176 | } | 176 | } |
177 | 177 | ||
178 | 178 | ||
179 | static ssize_t atomic_read_file(struct file * file, char __user * buf, size_t count, loff_t * offset) | 179 | static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset) |
180 | { | 180 | { |
181 | atomic_t * val = file->private_data; | 181 | atomic_t *val = file->private_data; |
182 | return oprofilefs_ulong_to_user(atomic_read(val), buf, count, offset); | 182 | return oprofilefs_ulong_to_user(atomic_read(val), buf, count, offset); |
183 | } | 183 | } |
184 | 184 | ||
185 | 185 | ||
186 | static const struct file_operations atomic_ro_fops = { | 186 | static const struct file_operations atomic_ro_fops = { |
187 | .read = atomic_read_file, | 187 | .read = atomic_read_file, |
188 | .open = default_open, | 188 | .open = default_open, |
189 | }; | 189 | }; |
190 | |||
191 | 190 | ||
192 | int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, | 191 | |
193 | char const * name, atomic_t * val) | 192 | int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root, |
193 | char const *name, atomic_t *val) | ||
194 | { | 194 | { |
195 | struct dentry * d = __oprofilefs_create_file(sb, root, name, | 195 | struct dentry *d = __oprofilefs_create_file(sb, root, name, |
196 | &atomic_ro_fops, 0444); | 196 | &atomic_ro_fops, 0444); |
197 | if (!d) | 197 | if (!d) |
198 | return -EFAULT; | 198 | return -EFAULT; |
@@ -201,9 +201,9 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, | |||
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
204 | 204 | ||
205 | int oprofilefs_create_file(struct super_block * sb, struct dentry * root, | 205 | int oprofilefs_create_file(struct super_block *sb, struct dentry *root, |
206 | char const * name, const struct file_operations * fops) | 206 | char const *name, const struct file_operations *fops) |
207 | { | 207 | { |
208 | if (!__oprofilefs_create_file(sb, root, name, fops, 0644)) | 208 | if (!__oprofilefs_create_file(sb, root, name, fops, 0644)) |
209 | return -EFAULT; | 209 | return -EFAULT; |
@@ -211,8 +211,8 @@ int oprofilefs_create_file(struct super_block * sb, struct dentry * root, | |||
211 | } | 211 | } |
212 | 212 | ||
213 | 213 | ||
214 | int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, | 214 | int oprofilefs_create_file_perm(struct super_block *sb, struct dentry *root, |
215 | char const * name, const struct file_operations * fops, int perm) | 215 | char const *name, const struct file_operations *fops, int perm) |
216 | { | 216 | { |
217 | if (!__oprofilefs_create_file(sb, root, name, fops, perm)) | 217 | if (!__oprofilefs_create_file(sb, root, name, fops, perm)) |
218 | return -EFAULT; | 218 | return -EFAULT; |
@@ -220,11 +220,11 @@ int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, | |||
220 | } | 220 | } |
221 | 221 | ||
222 | 222 | ||
223 | struct dentry * oprofilefs_mkdir(struct super_block * sb, | 223 | struct dentry *oprofilefs_mkdir(struct super_block *sb, |
224 | struct dentry * root, char const * name) | 224 | struct dentry *root, char const *name) |
225 | { | 225 | { |
226 | struct dentry * dentry; | 226 | struct dentry *dentry; |
227 | struct inode * inode; | 227 | struct inode *inode; |
228 | 228 | ||
229 | dentry = d_alloc_name(root, name); | 229 | dentry = d_alloc_name(root, name); |
230 | if (!dentry) | 230 | if (!dentry) |
@@ -241,10 +241,10 @@ struct dentry * oprofilefs_mkdir(struct super_block * sb, | |||
241 | } | 241 | } |
242 | 242 | ||
243 | 243 | ||
244 | static int oprofilefs_fill_super(struct super_block * sb, void * data, int silent) | 244 | static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent) |
245 | { | 245 | { |
246 | struct inode * root_inode; | 246 | struct inode *root_inode; |
247 | struct dentry * root_dentry; | 247 | struct dentry *root_dentry; |
248 | 248 | ||
249 | sb->s_blocksize = PAGE_CACHE_SIZE; | 249 | sb->s_blocksize = PAGE_CACHE_SIZE; |
250 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 250 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 710a45f0d734..333f915568c7 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | static int timer_notify(struct pt_regs *regs) | 20 | static int timer_notify(struct pt_regs *regs) |
21 | { | 21 | { |
22 | oprofile_add_sample(regs, 0); | 22 | oprofile_add_sample(regs, 0); |
23 | return 0; | 23 | return 0; |
24 | } | 24 | } |
25 | 25 | ||
@@ -35,7 +35,7 @@ static void timer_stop(void) | |||
35 | } | 35 | } |
36 | 36 | ||
37 | 37 | ||
38 | void __init oprofile_timer_init(struct oprofile_operations * ops) | 38 | void __init oprofile_timer_init(struct oprofile_operations *ops) |
39 | { | 39 | { |
40 | ops->create_files = NULL; | 40 | ops->create_files = NULL; |
41 | ops->setup = NULL; | 41 | ops->setup = NULL; |