aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2011-02-16 05:22:34 -0500
committerIngo Molnar <mingo@elte.hu>2011-02-16 07:30:55 -0500
commit163ec4354a5135c6c38c3f4a9b46a31900ebdf48 (patch)
tree59063e726453ace397c66d95cab09ac43265be41
parent4979d2729af22f6ce8faa325fc60a85a2c2daa02 (diff)
perf: Optimize throttling code
By pre-computing the maximum number of samples per tick we can avoid a multiplication and a conditional since MAX_INTERRUPTS > max_samples_per_tick. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/perf_event.h4
-rw-r--r--kernel/perf_event.c43
-rw-r--r--kernel/sysctl.c2
3 files changed, 29 insertions, 20 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 38c8b2554842..8ceb5a6fd9c9 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1110,6 +1110,10 @@ extern int sysctl_perf_event_paranoid;
1110extern int sysctl_perf_event_mlock; 1110extern int sysctl_perf_event_mlock;
1111extern int sysctl_perf_event_sample_rate; 1111extern int sysctl_perf_event_sample_rate;
1112 1112
1113extern int perf_proc_update_handler(struct ctl_table *table, int write,
1114 void __user *buffer, size_t *lenp,
1115 loff_t *ppos);
1116
1113static inline bool perf_paranoid_tracepoint_raw(void) 1117static inline bool perf_paranoid_tracepoint_raw(void)
1114{ 1118{
1115 return sysctl_perf_event_paranoid > -1; 1119 return sysctl_perf_event_paranoid > -1;
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 65dcdc76d709..e03be08d0ddf 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -150,7 +150,24 @@ int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */
150/* 150/*
151 * max perf event sample rate 151 * max perf event sample rate
152 */ 152 */
153int sysctl_perf_event_sample_rate __read_mostly = 100000; 153#define DEFAULT_MAX_SAMPLE_RATE 100000
154int sysctl_perf_event_sample_rate __read_mostly = DEFAULT_MAX_SAMPLE_RATE;
155static int max_samples_per_tick __read_mostly =
156 DIV_ROUND_UP(DEFAULT_MAX_SAMPLE_RATE, HZ);
157
158int perf_proc_update_handler(struct ctl_table *table, int write,
159 void __user *buffer, size_t *lenp,
160 loff_t *ppos)
161{
162 int ret = proc_dointvec(table, write, buffer, lenp, ppos);
163
164 if (ret || !write)
165 return ret;
166
167 max_samples_per_tick = DIV_ROUND_UP(sysctl_perf_event_sample_rate, HZ);
168
169 return 0;
170}
154 171
155static atomic64_t perf_event_id; 172static atomic64_t perf_event_id;
156 173
@@ -4941,26 +4958,14 @@ static int __perf_event_overflow(struct perf_event *event, int nmi,
4941 if (unlikely(!is_sampling_event(event))) 4958 if (unlikely(!is_sampling_event(event)))
4942 return 0; 4959 return 0;
4943 4960
4944 if (!throttle) { 4961 if (unlikely(hwc->interrupts >= max_samples_per_tick)) {
4945 hwc->interrupts++; 4962 if (throttle) {
4946 } else { 4963 hwc->interrupts = MAX_INTERRUPTS;
4947 if (hwc->interrupts != MAX_INTERRUPTS) { 4964 perf_log_throttle(event, 0);
4948 hwc->interrupts++;
4949 if (HZ * hwc->interrupts >
4950 (u64)sysctl_perf_event_sample_rate) {
4951 hwc->interrupts = MAX_INTERRUPTS;
4952 perf_log_throttle(event, 0);
4953 ret = 1;
4954 }
4955 } else {
4956 /*
4957 * Keep re-disabling events even though on the previous
4958 * pass we disabled it - just in case we raced with a
4959 * sched-in and the event got enabled again:
4960 */
4961 ret = 1; 4965 ret = 1;
4962 } 4966 }
4963 } 4967 } else
4968 hwc->interrupts++;
4964 4969
4965 if (event->attr.freq) { 4970 if (event->attr.freq) {
4966 u64 now = perf_clock(); 4971 u64 now = perf_clock();
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 0f1bd83db985..daef911cbadb 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -948,7 +948,7 @@ static struct ctl_table kern_table[] = {
948 .data = &sysctl_perf_event_sample_rate, 948 .data = &sysctl_perf_event_sample_rate,
949 .maxlen = sizeof(sysctl_perf_event_sample_rate), 949 .maxlen = sizeof(sysctl_perf_event_sample_rate),
950 .mode = 0644, 950 .mode = 0644,
951 .proc_handler = proc_dointvec, 951 .proc_handler = perf_proc_update_handler,
952 }, 952 },
953#endif 953#endif
954#ifdef CONFIG_KMEMCHECK 954#ifdef CONFIG_KMEMCHECK