All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [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.