* [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle
@ 2017-03-06 7:14 Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 1/4] " Tan Xiaojun
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Tan Xiaojun @ 2017-03-06 7:14 UTC (permalink / raw
To: alexander.levin, peterz, wangnan0, guohanjun; +Cc: linuxarm, linux-kernel
These four patches are needed for stable 4.1. They fix function of dynamic
interrupt throttle.
Kan Liang (1):
perf/core: Fix implicitly enable dynamic interrupt throttle
Peter Zijlstra (2):
perf/core: Fix dynamic interrupt throttle
perf/core: Make sysctl_perf_cpu_time_max_percent conform to
documentation
Tan Xiaojun (1):
perf/core: Fix the perf_cpu_time_max_percent check
kernel/events/core.c | 97 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 60 insertions(+), 37 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH -stable 4.1 1/4] perf/core: Fix dynamic interrupt throttle
2017-03-06 7:14 [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle Tan Xiaojun
@ 2017-03-06 7:14 ` Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 2/4] perf/core: Fix implicitly enable " Tan Xiaojun
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Tan Xiaojun @ 2017-03-06 7:14 UTC (permalink / raw
To: alexander.levin, peterz, wangnan0, guohanjun; +Cc: linuxarm, linux-kernel
From: Peter Zijlstra <peterz@infradead.org>
There were two problems with the dynamic interrupt throttle mechanism,
both triggered by the same action.
When you (or perf_fuzzer) write a huge value into
/proc/sys/kernel/perf_event_max_sample_rate the computed
perf_sample_allowed_ns becomes 0. This effectively disables the whole
dynamic throttle.
This is fixed by ensuring update_perf_cpu_limits() never sets the
value to 0. However, we allow disabling of the dynamic throttle by
writing 100 to /proc/sys/kernel/perf_cpu_time_max_percent. This will
generate a warning in dmesg.
The second problem is that by setting the max_sample_rate to a huge
number, the adaptive process can take a few tries, since it halfs the
limit each time. Change that to directly compute a new value based on
the observed duration.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Tan Xiaojun <tanxiaojun@huawei.com>
---
kernel/events/core.c | 87 ++++++++++++++++++++++++++++++----------------------
1 file changed, 51 insertions(+), 36 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 6da64f0..3089a004 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -198,8 +198,11 @@ void update_perf_cpu_limits(void)
u64 tmp = perf_sample_period_ns;
tmp *= sysctl_perf_cpu_time_max_percent;
- do_div(tmp, 100);
- ACCESS_ONCE(perf_sample_allowed_ns) = tmp;
+ tmp = div_u64(tmp, 100);
+ if (!tmp)
+ tmp = 1;
+
+ WRITE_ONCE(perf_sample_allowed_ns, tmp);
}
static int perf_rotate_context(struct perf_cpu_context *cpuctx);
@@ -231,7 +234,13 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
if (ret || !write)
return ret;
- update_perf_cpu_limits();
+ if (sysctl_perf_cpu_time_max_percent == 100) {
+ printk(KERN_WARNING
+ "perf: Dynamic interrupt throttling disabled, can hang your system!\n");
+ WRITE_ONCE(perf_sample_allowed_ns, 0);
+ } else {
+ update_perf_cpu_limits();
+ }
return 0;
}
@@ -245,62 +254,68 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
#define NR_ACCUMULATED_SAMPLES 128
static DEFINE_PER_CPU(u64, running_sample_length);
+static u64 __report_avg;
+static u64 __report_allowed;
+
static void perf_duration_warn(struct irq_work *w)
{
- u64 allowed_ns = ACCESS_ONCE(perf_sample_allowed_ns);
- u64 avg_local_sample_len;
- u64 local_samples_len;
-
- local_samples_len = __this_cpu_read(running_sample_length);
- avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES;
-
printk_ratelimited(KERN_WARNING
- "perf interrupt took too long (%lld > %lld), lowering "
- "kernel.perf_event_max_sample_rate to %d\n",
- avg_local_sample_len, allowed_ns >> 1,
- sysctl_perf_event_sample_rate);
+ "perf: interrupt took too long (%lld > %lld), lowering "
+ "kernel.perf_event_max_sample_rate to %d\n",
+ __report_avg, __report_allowed,
+ sysctl_perf_event_sample_rate);
}
static DEFINE_IRQ_WORK(perf_duration_work, perf_duration_warn);
void perf_sample_event_took(u64 sample_len_ns)
{
- u64 allowed_ns = ACCESS_ONCE(perf_sample_allowed_ns);
- u64 avg_local_sample_len;
- u64 local_samples_len;
+ u64 max_len = READ_ONCE(perf_sample_allowed_ns);
+ u64 running_len;
+ u64 avg_len;
+ u32 max;
- if (allowed_ns == 0)
+ if (max_len == 0)
return;
- /* decay the counter by 1 average sample */
- local_samples_len = __this_cpu_read(running_sample_length);
- local_samples_len -= local_samples_len/NR_ACCUMULATED_SAMPLES;
- local_samples_len += sample_len_ns;
- __this_cpu_write(running_sample_length, local_samples_len);
+ /* Decay the counter by 1 average sample. */
+ running_len = __this_cpu_read(running_sample_length);
+ running_len -= running_len/NR_ACCUMULATED_SAMPLES;
+ running_len += sample_len_ns;
+ __this_cpu_write(running_sample_length, running_len);
/*
- * note: this will be biased artifically low until we have
- * seen NR_ACCUMULATED_SAMPLES. Doing it this way keeps us
+ * Note: this will be biased artifically low until we have
+ * seen NR_ACCUMULATED_SAMPLES. Doing it this way keeps us
* from having to maintain a count.
*/
- avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES;
-
- if (avg_local_sample_len <= allowed_ns)
+ avg_len = running_len/NR_ACCUMULATED_SAMPLES;
+ if (avg_len <= max_len)
return;
- if (max_samples_per_tick <= 1)
- return;
+ __report_avg = avg_len;
+ __report_allowed = max_len;
- max_samples_per_tick = DIV_ROUND_UP(max_samples_per_tick, 2);
- sysctl_perf_event_sample_rate = max_samples_per_tick * HZ;
- perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
+ /*
+ * Compute a throttle threshold 25% below the current duration.
+ */
+ avg_len += avg_len / 4;
+ max = (TICK_NSEC / 100) * sysctl_perf_cpu_time_max_percent;
+ if (avg_len < max)
+ max /= (u32)avg_len;
+ else
+ max = 1;
- update_perf_cpu_limits();
+ WRITE_ONCE(perf_sample_allowed_ns, avg_len);
+ WRITE_ONCE(max_samples_per_tick, max);
+
+ sysctl_perf_event_sample_rate = max * HZ;
+ perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
if (!irq_work_queue(&perf_duration_work)) {
- early_printk("perf interrupt took too long (%lld > %lld), lowering "
+ early_printk("perf: interrupt took too long (%lld > %lld), lowering "
"kernel.perf_event_max_sample_rate to %d\n",
- avg_local_sample_len, allowed_ns >> 1,
+ __report_avg, __report_allowed,
sysctl_perf_event_sample_rate);
}
}
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH -stable 4.1 2/4] perf/core: Fix implicitly enable dynamic interrupt throttle
2017-03-06 7:14 [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 1/4] " Tan Xiaojun
@ 2017-03-06 7:14 ` Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 3/4] perf/core: Make sysctl_perf_cpu_time_max_percent conform to documentation Tan Xiaojun
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Tan Xiaojun @ 2017-03-06 7:14 UTC (permalink / raw
To: alexander.levin, peterz, wangnan0, guohanjun; +Cc: linuxarm, linux-kernel
From: Kan Liang <kan.liang@intel.com>
This patch fixes an issue which was introduced by commit:
91a612eea9a3 ("perf/core: Fix dynamic interrupt throttle")
... which commit unconditionally sets the perf_sample_allowed_ns value
to !0. But that could trigger a bug in the following corner case:
The user can disable the dynamic interrupt throttle mechanism by setting
perf_cpu_time_max_percent to 0. Then they change perf_event_max_sample_rate.
For this case, the mechanism will be enabled implicitly, because
perf_sample_allowed_ns becomes !0 - which is not what we want.
This patch only updates perf_sample_allowed_ns when the dynamic
interrupt throttle mechanism is enabled.
Signed-off-by: Kan Liang <kan.liang@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: acme@kernel.org
Link: http://lkml.kernel.org/r/1462260366-3160-1-git-send-email-kan.liang@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Tan Xiaojun <tanxiaojun@huawei.com>
---
kernel/events/core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 3089a004..f96ad76 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -216,6 +216,13 @@ int perf_proc_update_handler(struct ctl_table *table, int write,
if (ret || !write)
return ret;
+ /*
+ * If throttling is disabled don't allow the write:
+ */
+ if (sysctl_perf_cpu_time_max_percent == 100 ||
+ sysctl_perf_cpu_time_max_percent == 0)
+ return -EINVAL;
+
max_samples_per_tick = DIV_ROUND_UP(sysctl_perf_event_sample_rate, HZ);
perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
update_perf_cpu_limits();
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH -stable 4.1 3/4] perf/core: Make sysctl_perf_cpu_time_max_percent conform to documentation
2017-03-06 7:14 [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 1/4] " Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 2/4] perf/core: Fix implicitly enable " Tan Xiaojun
@ 2017-03-06 7:14 ` Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 4/4] perf/core: Fix the perf_cpu_time_max_percent check Tan Xiaojun
2017-03-06 22:19 ` [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle alexander.levin
4 siblings, 0 replies; 6+ messages in thread
From: Tan Xiaojun @ 2017-03-06 7:14 UTC (permalink / raw
To: alexander.levin, peterz, wangnan0, guohanjun; +Cc: linuxarm, linux-kernel
From: Peter Zijlstra <peterz@infradead.org>
Markus reported that 0 should also disable the throttling we per
Documentation/sysctl/kernel.txt.
Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Fixes: 91a612eea9a3 ("perf/core: Fix dynamic interrupt throttle")
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Tan Xiaojun <tanxiaojun@huawei.com>
---
kernel/events/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f96ad76..350c45a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -241,7 +241,8 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
if (ret || !write)
return ret;
- if (sysctl_perf_cpu_time_max_percent == 100) {
+ if (sysctl_perf_cpu_time_max_percent == 100 ||
+ sysctl_perf_cpu_time_max_percent == 0) {
printk(KERN_WARNING
"perf: Dynamic interrupt throttling disabled, can hang your system!\n");
WRITE_ONCE(perf_sample_allowed_ns, 0);
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH -stable 4.1 4/4] perf/core: Fix the perf_cpu_time_max_percent check
2017-03-06 7:14 [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle Tan Xiaojun
` (2 preceding siblings ...)
2017-03-06 7:14 ` [PATCH -stable 4.1 3/4] perf/core: Make sysctl_perf_cpu_time_max_percent conform to documentation Tan Xiaojun
@ 2017-03-06 7:14 ` Tan Xiaojun
2017-03-06 22:19 ` [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle alexander.levin
4 siblings, 0 replies; 6+ messages in thread
From: Tan Xiaojun @ 2017-03-06 7:14 UTC (permalink / raw
To: alexander.levin, peterz, wangnan0, guohanjun; +Cc: linuxarm, linux-kernel
Use "proc_dointvec_minmax" instead of "proc_dointvec" to check the input
value from user-space.
If not, we can set a big value and some vars will overflow like
"sysctl_perf_event_sample_rate" which will cause a lot of unexpected
problems.
Signed-off-by: Tan Xiaojun <tanxiaojun@huawei.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: <acme@kernel.org>
Cc: <alexander.shishkin@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1487829879-56237-1-git-send-email-tanxiaojun@huawei.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
kernel/events/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 350c45a..5b50b06 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -236,7 +236,7 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
- int ret = proc_dointvec(table, write, buffer, lenp, ppos);
+ int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (ret || !write)
return ret;
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle
2017-03-06 7:14 [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle Tan Xiaojun
` (3 preceding siblings ...)
2017-03-06 7:14 ` [PATCH -stable 4.1 4/4] perf/core: Fix the perf_cpu_time_max_percent check Tan Xiaojun
@ 2017-03-06 22:19 ` alexander.levin
4 siblings, 0 replies; 6+ messages in thread
From: alexander.levin @ 2017-03-06 22:19 UTC (permalink / raw
To: Tan Xiaojun
Cc: peterz@infradead.org, wangnan0@huawei.com, guohanjun@huawei.com,
linuxarm@huawei.com, linux-kernel@vger.kernel.org
On Mon, Mar 06, 2017 at 03:14:21PM +0800, Tan Xiaojun wrote:
> These four patches are needed for stable 4.1. They fix function of dynamic
> interrupt throttle.
>
> Kan Liang (1):
> perf/core: Fix implicitly enable dynamic interrupt throttle
>
> Peter Zijlstra (2):
> perf/core: Fix dynamic interrupt throttle
> perf/core: Make sysctl_perf_cpu_time_max_percent conform to
> documentation
>
> Tan Xiaojun (1):
> perf/core: Fix the perf_cpu_time_max_percent check
>
> kernel/events/core.c | 97 ++++++++++++++++++++++++++++++++--------------------
> 1 file changed, 60 insertions(+), 37 deletions(-)
>
> --
> 1.9.1
>
Applied, thanks!
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-03-07 1:31 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-06 7:14 [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 1/4] " Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 2/4] perf/core: Fix implicitly enable " Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 3/4] perf/core: Make sysctl_perf_cpu_time_max_percent conform to documentation Tan Xiaojun
2017-03-06 7:14 ` [PATCH -stable 4.1 4/4] perf/core: Fix the perf_cpu_time_max_percent check Tan Xiaojun
2017-03-06 22:19 ` [PATCH -stable 4.1 0/4] perf/core: Fix dynamic interrupt throttle alexander.levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.