diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-03-23 13:22:06 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-06 03:30:25 -0400 |
commit | f4a2deb4860497f4332cf6a1acddab3dd628ddf0 (patch) | |
tree | 1655c7c000edce20d2c5b54cf12f99c23340371e | |
parent | af9522cf133e9be6da8525a46a9ed7e7659f0e1a (diff) |
perf_counter: remove the event config bitfields
Since the bitfields turned into a bit of a mess, remove them and rely on
good old masks.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Orig-LKML-Reference: <20090323172417.059499915@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/powerpc/kernel/perf_counter.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_counter.c | 8 | ||||
-rw-r--r-- | include/linux/perf_counter.h | 74 | ||||
-rw-r--r-- | kernel/perf_counter.c | 22 |
4 files changed, 70 insertions, 40 deletions
diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 6413d9c0313b..d05651584d43 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c | |||
@@ -602,13 +602,13 @@ hw_perf_counter_init(struct perf_counter *counter) | |||
602 | return NULL; | 602 | return NULL; |
603 | if ((s64)counter->hw_event.irq_period < 0) | 603 | if ((s64)counter->hw_event.irq_period < 0) |
604 | return NULL; | 604 | return NULL; |
605 | if (!counter->hw_event.raw_type) { | 605 | if (!perf_event_raw(&counter->hw_event)) { |
606 | ev = counter->hw_event.event_id; | 606 | ev = perf_event_id(&counter->hw_event); |
607 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) | 607 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) |
608 | return NULL; | 608 | return NULL; |
609 | ev = ppmu->generic_events[ev]; | 609 | ev = ppmu->generic_events[ev]; |
610 | } else { | 610 | } else { |
611 | ev = counter->hw_event.raw_event_id; | 611 | ev = perf_event_config(&counter->hw_event); |
612 | } | 612 | } |
613 | counter->hw.config_base = ev; | 613 | counter->hw.config_base = ev; |
614 | counter->hw.idx = 0; | 614 | counter->hw.idx = 0; |
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 902282d68b0c..3f95b0cdc550 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
@@ -217,15 +217,15 @@ static int __hw_perf_counter_init(struct perf_counter *counter) | |||
217 | /* | 217 | /* |
218 | * Raw event type provide the config in the event structure | 218 | * Raw event type provide the config in the event structure |
219 | */ | 219 | */ |
220 | if (hw_event->raw_type) { | 220 | if (perf_event_raw(hw_event)) { |
221 | hwc->config |= pmc_ops->raw_event(hw_event->raw_event_id); | 221 | hwc->config |= pmc_ops->raw_event(perf_event_config(hw_event)); |
222 | } else { | 222 | } else { |
223 | if (hw_event->event_id >= pmc_ops->max_events) | 223 | if (perf_event_id(hw_event) >= pmc_ops->max_events) |
224 | return -EINVAL; | 224 | return -EINVAL; |
225 | /* | 225 | /* |
226 | * The generic map: | 226 | * The generic map: |
227 | */ | 227 | */ |
228 | hwc->config |= pmc_ops->event_map(hw_event->event_id); | 228 | hwc->config |= pmc_ops->event_map(perf_event_id(hw_event)); |
229 | } | 229 | } |
230 | counter->wakeup_pending = 0; | 230 | counter->wakeup_pending = 0; |
231 | 231 | ||
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 98f5990be1e1..56099e52970d 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h | |||
@@ -82,32 +82,37 @@ enum perf_counter_record_type { | |||
82 | PERF_RECORD_GROUP = 2, | 82 | PERF_RECORD_GROUP = 2, |
83 | }; | 83 | }; |
84 | 84 | ||
85 | #define __PERF_COUNTER_MASK(name) \ | ||
86 | (((1ULL << PERF_COUNTER_##name##_BITS) - 1) << \ | ||
87 | PERF_COUNTER_##name##_SHIFT) | ||
88 | |||
89 | #define PERF_COUNTER_RAW_BITS 1 | ||
90 | #define PERF_COUNTER_RAW_SHIFT 63 | ||
91 | #define PERF_COUNTER_RAW_MASK __PERF_COUNTER_MASK(RAW) | ||
92 | |||
93 | #define PERF_COUNTER_CONFIG_BITS 63 | ||
94 | #define PERF_COUNTER_CONFIG_SHIFT 0 | ||
95 | #define PERF_COUNTER_CONFIG_MASK __PERF_COUNTER_MASK(CONFIG) | ||
96 | |||
97 | #define PERF_COUNTER_TYPE_BITS 7 | ||
98 | #define PERF_COUNTER_TYPE_SHIFT 56 | ||
99 | #define PERF_COUNTER_TYPE_MASK __PERF_COUNTER_MASK(TYPE) | ||
100 | |||
101 | #define PERF_COUNTER_EVENT_BITS 56 | ||
102 | #define PERF_COUNTER_EVENT_SHIFT 0 | ||
103 | #define PERF_COUNTER_EVENT_MASK __PERF_COUNTER_MASK(EVENT) | ||
104 | |||
85 | /* | 105 | /* |
86 | * Hardware event to monitor via a performance monitoring counter: | 106 | * Hardware event to monitor via a performance monitoring counter: |
87 | */ | 107 | */ |
88 | struct perf_counter_hw_event { | 108 | struct perf_counter_hw_event { |
89 | union { | 109 | /* |
90 | #ifndef __BIG_ENDIAN_BITFIELD | 110 | * The MSB of the config word signifies if the rest contains cpu |
91 | struct { | 111 | * specific (raw) counter configuration data, if unset, the next |
92 | __u64 event_id : 56, | 112 | * 7 bits are an event type and the rest of the bits are the event |
93 | type : 8; | 113 | * identifier. |
94 | }; | 114 | */ |
95 | struct { | 115 | __u64 config; |
96 | __u64 raw_event_id : 63, | ||
97 | raw_type : 1; | ||
98 | }; | ||
99 | #else | ||
100 | struct { | ||
101 | __u64 type : 8, | ||
102 | event_id : 56; | ||
103 | }; | ||
104 | struct { | ||
105 | __u64 raw_type : 1, | ||
106 | raw_event_id : 63; | ||
107 | }; | ||
108 | #endif /* __BIT_ENDIAN_BITFIELD */ | ||
109 | __u64 event_config; | ||
110 | }; | ||
111 | 116 | ||
112 | __u64 irq_period; | 117 | __u64 irq_period; |
113 | __u64 record_type; | 118 | __u64 record_type; |
@@ -157,6 +162,27 @@ struct perf_counter_hw_event { | |||
157 | 162 | ||
158 | struct task_struct; | 163 | struct task_struct; |
159 | 164 | ||
165 | static inline u64 perf_event_raw(struct perf_counter_hw_event *hw_event) | ||
166 | { | ||
167 | return hw_event->config & PERF_COUNTER_RAW_MASK; | ||
168 | } | ||
169 | |||
170 | static inline u64 perf_event_config(struct perf_counter_hw_event *hw_event) | ||
171 | { | ||
172 | return hw_event->config & PERF_COUNTER_CONFIG_MASK; | ||
173 | } | ||
174 | |||
175 | static inline u64 perf_event_type(struct perf_counter_hw_event *hw_event) | ||
176 | { | ||
177 | return (hw_event->config & PERF_COUNTER_TYPE_MASK) >> | ||
178 | PERF_COUNTER_TYPE_SHIFT; | ||
179 | } | ||
180 | |||
181 | static inline u64 perf_event_id(struct perf_counter_hw_event *hw_event) | ||
182 | { | ||
183 | return hw_event->config & PERF_COUNTER_EVENT_MASK; | ||
184 | } | ||
185 | |||
160 | /** | 186 | /** |
161 | * struct hw_perf_counter - performance counter hardware details: | 187 | * struct hw_perf_counter - performance counter hardware details: |
162 | */ | 188 | */ |
@@ -336,8 +362,8 @@ extern void perf_counter_output(struct perf_counter *counter, | |||
336 | */ | 362 | */ |
337 | static inline int is_software_counter(struct perf_counter *counter) | 363 | static inline int is_software_counter(struct perf_counter *counter) |
338 | { | 364 | { |
339 | return !counter->hw_event.raw_type && | 365 | return !perf_event_raw(&counter->hw_event) && |
340 | counter->hw_event.type != PERF_TYPE_HARDWARE; | 366 | perf_event_type(&counter->hw_event) != PERF_TYPE_HARDWARE; |
341 | } | 367 | } |
342 | 368 | ||
343 | extern void perf_swcounter_event(u32, u64, int, struct pt_regs *); | 369 | extern void perf_swcounter_event(u32, u64, int, struct pt_regs *); |
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f054b8c9bf96..ca14fc41ccdf 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -1379,7 +1379,7 @@ static void perf_counter_handle_group(struct perf_counter *counter) | |||
1379 | list_for_each_entry(sub, &leader->sibling_list, list_entry) { | 1379 | list_for_each_entry(sub, &leader->sibling_list, list_entry) { |
1380 | if (sub != counter) | 1380 | if (sub != counter) |
1381 | sub->hw_ops->read(sub); | 1381 | sub->hw_ops->read(sub); |
1382 | perf_counter_store_irq(counter, sub->hw_event.event_config); | 1382 | perf_counter_store_irq(counter, sub->hw_event.config); |
1383 | perf_counter_store_irq(counter, atomic64_read(&sub->count)); | 1383 | perf_counter_store_irq(counter, atomic64_read(&sub->count)); |
1384 | } | 1384 | } |
1385 | } | 1385 | } |
@@ -1489,13 +1489,13 @@ static int perf_swcounter_match(struct perf_counter *counter, | |||
1489 | if (counter->state != PERF_COUNTER_STATE_ACTIVE) | 1489 | if (counter->state != PERF_COUNTER_STATE_ACTIVE) |
1490 | return 0; | 1490 | return 0; |
1491 | 1491 | ||
1492 | if (counter->hw_event.raw_type) | 1492 | if (perf_event_raw(&counter->hw_event)) |
1493 | return 0; | 1493 | return 0; |
1494 | 1494 | ||
1495 | if (counter->hw_event.type != type) | 1495 | if (perf_event_type(&counter->hw_event) != type) |
1496 | return 0; | 1496 | return 0; |
1497 | 1497 | ||
1498 | if (counter->hw_event.event_id != event) | 1498 | if (perf_event_id(&counter->hw_event) != event) |
1499 | return 0; | 1499 | return 0; |
1500 | 1500 | ||
1501 | if (counter->hw_event.exclude_user && user_mode(regs)) | 1501 | if (counter->hw_event.exclude_user && user_mode(regs)) |
@@ -1757,13 +1757,13 @@ extern void ftrace_profile_disable(int); | |||
1757 | 1757 | ||
1758 | static void tp_perf_counter_destroy(struct perf_counter *counter) | 1758 | static void tp_perf_counter_destroy(struct perf_counter *counter) |
1759 | { | 1759 | { |
1760 | ftrace_profile_disable(counter->hw_event.event_id); | 1760 | ftrace_profile_disable(perf_event_id(&counter->hw_event)); |
1761 | } | 1761 | } |
1762 | 1762 | ||
1763 | static const struct hw_perf_counter_ops * | 1763 | static const struct hw_perf_counter_ops * |
1764 | tp_perf_counter_init(struct perf_counter *counter) | 1764 | tp_perf_counter_init(struct perf_counter *counter) |
1765 | { | 1765 | { |
1766 | int event_id = counter->hw_event.event_id; | 1766 | int event_id = perf_event_id(&counter->hw_event); |
1767 | int ret; | 1767 | int ret; |
1768 | 1768 | ||
1769 | ret = ftrace_profile_enable(event_id); | 1769 | ret = ftrace_profile_enable(event_id); |
@@ -1797,7 +1797,7 @@ sw_perf_counter_init(struct perf_counter *counter) | |||
1797 | * to be kernel events, and page faults are never hypervisor | 1797 | * to be kernel events, and page faults are never hypervisor |
1798 | * events. | 1798 | * events. |
1799 | */ | 1799 | */ |
1800 | switch (counter->hw_event.event_id) { | 1800 | switch (perf_event_id(&counter->hw_event)) { |
1801 | case PERF_COUNT_CPU_CLOCK: | 1801 | case PERF_COUNT_CPU_CLOCK: |
1802 | hw_ops = &perf_ops_cpu_clock; | 1802 | hw_ops = &perf_ops_cpu_clock; |
1803 | 1803 | ||
@@ -1882,9 +1882,12 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, | |||
1882 | 1882 | ||
1883 | hw_ops = NULL; | 1883 | hw_ops = NULL; |
1884 | 1884 | ||
1885 | if (hw_event->raw_type) | 1885 | if (perf_event_raw(hw_event)) { |
1886 | hw_ops = hw_perf_counter_init(counter); | 1886 | hw_ops = hw_perf_counter_init(counter); |
1887 | else switch (hw_event->type) { | 1887 | goto done; |
1888 | } | ||
1889 | |||
1890 | switch (perf_event_type(hw_event)) { | ||
1888 | case PERF_TYPE_HARDWARE: | 1891 | case PERF_TYPE_HARDWARE: |
1889 | hw_ops = hw_perf_counter_init(counter); | 1892 | hw_ops = hw_perf_counter_init(counter); |
1890 | break; | 1893 | break; |
@@ -1902,6 +1905,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, | |||
1902 | kfree(counter); | 1905 | kfree(counter); |
1903 | return NULL; | 1906 | return NULL; |
1904 | } | 1907 | } |
1908 | done: | ||
1905 | counter->hw_ops = hw_ops; | 1909 | counter->hw_ops = hw_ops; |
1906 | 1910 | ||
1907 | return counter; | 1911 | return counter; |