diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 15:54:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 15:54:49 -0400 |
commit | 5d70f79b5ef6ea2de4f72a37b2d96e2601e40a22 (patch) | |
tree | a0d6de0930ba83ecf4629c2e2e261f5eaa2d8f33 /arch/sh/oprofile/common.c | |
parent | 888a6f77e0418b049f83d37547c209b904d30af4 (diff) | |
parent | 750ed158bf6c782d2813da1bca2c824365a0b777 (diff) |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (163 commits)
tracing: Fix compile issue for trace_sched_wakeup.c
[S390] hardirq: remove pointless header file includes
[IA64] Move local_softirq_pending() definition
perf, powerpc: Fix power_pmu_event_init to not use event->ctx
ftrace: Remove recursion between recordmcount and scripts/mod/empty
jump_label: Add COND_STMT(), reducer wrappery
perf: Optimize sw events
perf: Use jump_labels to optimize the scheduler hooks
jump_label: Add atomic_t interface
jump_label: Use more consistent naming
perf, hw_breakpoint: Fix crash in hw_breakpoint creation
perf: Find task before event alloc
perf: Fix task refcount bugs
perf: Fix group moving
irq_work: Add generic hardirq context callbacks
perf_events: Fix transaction recovery in group_sched_in()
perf_events: Fix bogus AMD64 generic TLB events
perf_events: Fix bogus context time tracking
tracing: Remove parent recording in latency tracer graph options
tracing: Use one prologue for the preempt irqs off tracer function tracers
...
Diffstat (limited to 'arch/sh/oprofile/common.c')
-rw-r--r-- | arch/sh/oprofile/common.c | 115 |
1 files changed, 23 insertions, 92 deletions
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c index ac604937f3ee..e10d89376f9b 100644 --- a/arch/sh/oprofile/common.c +++ b/arch/sh/oprofile/common.c | |||
@@ -17,114 +17,45 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/perf_event.h> | ||
20 | #include <asm/processor.h> | 21 | #include <asm/processor.h> |
21 | #include "op_impl.h" | ||
22 | |||
23 | static struct op_sh_model *model; | ||
24 | |||
25 | static struct op_counter_config ctr[20]; | ||
26 | 22 | ||
23 | #ifdef CONFIG_HW_PERF_EVENTS | ||
27 | extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth); | 24 | extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth); |
28 | 25 | ||
29 | static int op_sh_setup(void) | 26 | char *op_name_from_perf_id(void) |
30 | { | ||
31 | /* Pre-compute the values to stuff in the hardware registers. */ | ||
32 | model->reg_setup(ctr); | ||
33 | |||
34 | /* Configure the registers on all cpus. */ | ||
35 | on_each_cpu(model->cpu_setup, NULL, 1); | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static int op_sh_create_files(struct super_block *sb, struct dentry *root) | ||
41 | { | 27 | { |
42 | int i, ret = 0; | 28 | const char *pmu; |
29 | char buf[20]; | ||
30 | int size; | ||
43 | 31 | ||
44 | for (i = 0; i < model->num_counters; i++) { | 32 | pmu = perf_pmu_name(); |
45 | struct dentry *dir; | 33 | if (!pmu) |
46 | char buf[4]; | 34 | return NULL; |
47 | 35 | ||
48 | snprintf(buf, sizeof(buf), "%d", i); | 36 | size = snprintf(buf, sizeof(buf), "sh/%s", pmu); |
49 | dir = oprofilefs_mkdir(sb, root, buf); | 37 | if (size > -1 && size < sizeof(buf)) |
38 | return buf; | ||
50 | 39 | ||
51 | ret |= oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); | 40 | return NULL; |
52 | ret |= oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); | ||
53 | ret |= oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); | ||
54 | ret |= oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); | ||
55 | |||
56 | if (model->create_files) | ||
57 | ret |= model->create_files(sb, dir); | ||
58 | else | ||
59 | ret |= oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); | ||
60 | |||
61 | /* Dummy entries */ | ||
62 | ret |= oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); | ||
63 | } | ||
64 | |||
65 | return ret; | ||
66 | } | 41 | } |
67 | 42 | ||
68 | static int op_sh_start(void) | 43 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
69 | { | 44 | { |
70 | /* Enable performance monitoring for all counters. */ | 45 | ops->backtrace = sh_backtrace; |
71 | on_each_cpu(model->cpu_start, NULL, 1); | ||
72 | 46 | ||
73 | return 0; | 47 | return oprofile_perf_init(ops); |
74 | } | 48 | } |
75 | 49 | ||
76 | static void op_sh_stop(void) | 50 | void __exit oprofile_arch_exit(void) |
77 | { | 51 | { |
78 | /* Disable performance monitoring for all counters. */ | 52 | oprofile_perf_exit(); |
79 | on_each_cpu(model->cpu_stop, NULL, 1); | ||
80 | } | 53 | } |
81 | 54 | #else | |
82 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 55 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
83 | { | 56 | { |
84 | struct op_sh_model *lmodel = NULL; | 57 | pr_info("oprofile: hardware counters not available\n"); |
85 | int ret; | 58 | return -ENODEV; |
86 | |||
87 | /* | ||
88 | * Always assign the backtrace op. If the counter initialization | ||
89 | * fails, we fall back to the timer which will still make use of | ||
90 | * this. | ||
91 | */ | ||
92 | ops->backtrace = sh_backtrace; | ||
93 | |||
94 | /* | ||
95 | * XXX | ||
96 | * | ||
97 | * All of the SH7750/SH-4A counters have been converted to perf, | ||
98 | * this infrastructure hook is left for other users until they've | ||
99 | * had a chance to convert over, at which point all of this | ||
100 | * will be deleted. | ||
101 | */ | ||
102 | |||
103 | if (!lmodel) | ||
104 | return -ENODEV; | ||
105 | if (!(current_cpu_data.flags & CPU_HAS_PERF_COUNTER)) | ||
106 | return -ENODEV; | ||
107 | |||
108 | ret = lmodel->init(); | ||
109 | if (unlikely(ret != 0)) | ||
110 | return ret; | ||
111 | |||
112 | model = lmodel; | ||
113 | |||
114 | ops->setup = op_sh_setup; | ||
115 | ops->create_files = op_sh_create_files; | ||
116 | ops->start = op_sh_start; | ||
117 | ops->stop = op_sh_stop; | ||
118 | ops->cpu_type = lmodel->cpu_type; | ||
119 | |||
120 | printk(KERN_INFO "oprofile: using %s performance monitoring.\n", | ||
121 | lmodel->cpu_type); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | void oprofile_arch_exit(void) | ||
127 | { | ||
128 | if (model && model->exit) | ||
129 | model->exit(); | ||
130 | } | 59 | } |
60 | void __exit oprofile_arch_exit(void) {} | ||
61 | #endif /* CONFIG_HW_PERF_EVENTS */ | ||