All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] sched/psi: Fix trigger time arithmetic
@ 2026-07-17 10:28 Guopeng Zhang
  2026-07-17 10:28 ` [PATCH 1/2] sched/psi: Fix long-window growth interpolation Guopeng Zhang
  2026-07-17 10:28 ` [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit Guopeng Zhang
  0 siblings, 2 replies; 7+ messages in thread
From: Guopeng Zhang @ 2026-07-17 10:28 UTC (permalink / raw)
  To: Johannes Weiner, Suren Baghdasaryan, Peter Zijlstra
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, Andrew Morton, linux-kernel

From: Guopeng Zhang <zhangguopeng@kylinos.cn>

PSI trigger time handling has two integer-width bugs. Long windows can
be truncated during growth interpolation, and the multiplication used
for the interpolation can overflow before the division. Separately,
the microsecond-to-nanosecond conversion can wrap on 32-bit systems
before the result is stored in a u64.

Fix the two issues independently.

Guopeng Zhang (2):
  sched/psi: Fix long-window growth interpolation
  sched/psi: Fix overflow in trigger time conversion on 32-bit

 kernel/sched/psi.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)


base-commit: 1a1757b76427f6201bfe0bf1bea9f7574f332a93
-- 
2.43.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] sched/psi: Fix long-window growth interpolation
  2026-07-17 10:28 [PATCH 0/2] sched/psi: Fix trigger time arithmetic Guopeng Zhang
@ 2026-07-17 10:28 ` Guopeng Zhang
  2026-07-27  3:17   ` Suren Baghdasaryan
  2026-07-28  8:49   ` Tao Cui
  2026-07-17 10:28 ` [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit Guopeng Zhang
  1 sibling, 2 replies; 7+ messages in thread
From: Guopeng Zhang @ 2026-07-17 10:28 UTC (permalink / raw)
  To: Johannes Weiner, Suren Baghdasaryan, Peter Zijlstra
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, Andrew Morton, linux-kernel

From: Guopeng Zhang <zhangguopeng@kylinos.cn>

PSI trigger windows are stored in nanoseconds and can be up to 10
seconds, but window_update() stores the remaining interval in a u32.
For example, after 2 seconds have elapsed in a 10-second window, the
remaining 8,000,000,000 ns is truncated to 3,705,032,704 ns.

Making remaining a u64 avoids the truncation, but the multiplication
can still overflow before the division. Both win->prev_growth and
remaining can be close to 10,000,000,000, so their product can exceed
U64_MAX.

Store the remaining interval in a u64 and use
mul_u64_u64_div_u64() to calculate the interpolation without
overflowing the intermediate product.

Fixes: 0e94682b73bf ("psi: introduce psi monitor")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
---
 kernel/sched/psi.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
index 4e152410653d..8e4df8b17c25 100644
--- a/kernel/sched/psi.c
+++ b/kernel/sched/psi.c
@@ -137,6 +137,7 @@
  * sampling of the aggregate task states would be.
  */
 #include <linux/sched/clock.h>
+#include <linux/math64.h>
 #include <linux/workqueue.h>
 #include <linux/psi.h>
 #include "sched.h"
@@ -451,10 +452,11 @@ static u64 window_update(struct psi_window *win, u64 now, u64 value)
 	if (elapsed > win->size)
 		window_reset(win, now, value, growth);
 	else {
-		u32 remaining;
+		u64 remaining;
 
 		remaining = win->size - elapsed;
-		growth += div64_u64(win->prev_growth * remaining, win->size);
+		growth += mul_u64_u64_div_u64(win->prev_growth, remaining,
+					      win->size);
 	}
 
 	return growth;
-- 
2.43.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit
  2026-07-17 10:28 [PATCH 0/2] sched/psi: Fix trigger time arithmetic Guopeng Zhang
  2026-07-17 10:28 ` [PATCH 1/2] sched/psi: Fix long-window growth interpolation Guopeng Zhang
@ 2026-07-17 10:28 ` Guopeng Zhang
  2026-07-27  3:24   ` Suren Baghdasaryan
  2026-07-28  8:52   ` Tao Cui
  1 sibling, 2 replies; 7+ messages in thread
From: Guopeng Zhang @ 2026-07-17 10:28 UTC (permalink / raw)
  To: Johannes Weiner, Suren Baghdasaryan, Peter Zijlstra
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, Andrew Morton, linux-kernel

From: Guopeng Zhang <zhangguopeng@kylinos.cn>

threshold_us and window_us are u32, while NSEC_PER_USEC is 1000L. On
32-bit architectures, multiplication by NSEC_PER_USEC is evaluated
using 32-bit unsigned arithmetic and can wrap before the result is
assigned to the u64 trigger fields.

For a valid 4,000,000 us threshold and 6,000,000 us window, the
threshold is stored as 4,000,000,000 ns, while the window wraps to
1,705,032,704 ns. The stored window is therefore shorter than the
threshold, so the trigger no longer monitors the requested 4-second
threshold over a 6-second window.

Cast both values to u64 before the multiplication so that the
conversion to nanoseconds is performed using 64-bit arithmetic.

Fixes: 0e94682b73bf ("psi: introduce psi monitor")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
---
 kernel/sched/psi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
index 8e4df8b17c25..f0a5976f49dc 100644
--- a/kernel/sched/psi.c
+++ b/kernel/sched/psi.c
@@ -1391,8 +1391,8 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, char *buf,
 
 	t->group = group;
 	t->state = state;
-	t->threshold = threshold_us * NSEC_PER_USEC;
-	t->win.size = window_us * NSEC_PER_USEC;
+	t->threshold = (u64)threshold_us * NSEC_PER_USEC;
+	t->win.size = (u64)window_us * NSEC_PER_USEC;
 	window_reset(&t->win, sched_clock(),
 			group->total[PSI_POLL][t->state], 0);
 
-- 
2.43.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] sched/psi: Fix long-window growth interpolation
  2026-07-17 10:28 ` [PATCH 1/2] sched/psi: Fix long-window growth interpolation Guopeng Zhang
@ 2026-07-27  3:17   ` Suren Baghdasaryan
  2026-07-28  8:49   ` Tao Cui
  1 sibling, 0 replies; 7+ messages in thread
From: Suren Baghdasaryan @ 2026-07-27  3:17 UTC (permalink / raw)
  To: Guopeng Zhang
  Cc: Johannes Weiner, Peter Zijlstra, Ingo Molnar, Juri Lelli,
	Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
	Mel Gorman, Valentin Schneider, K Prateek Nayak, Andrew Morton,
	linux-kernel

On Fri, Jul 17, 2026 at 3:29 AM Guopeng Zhang <guopeng.zhang@linux.dev> wrote:
>
> From: Guopeng Zhang <zhangguopeng@kylinos.cn>
>
> PSI trigger windows are stored in nanoseconds and can be up to 10
> seconds, but window_update() stores the remaining interval in a u32.
> For example, after 2 seconds have elapsed in a 10-second window, the
> remaining 8,000,000,000 ns is truncated to 3,705,032,704 ns.
>
> Making remaining a u64 avoids the truncation, but the multiplication
> can still overflow before the division. Both win->prev_growth and
> remaining can be close to 10,000,000,000, so their product can exceed
> U64_MAX.
>
> Store the remaining interval in a u64 and use
> mul_u64_u64_div_u64() to calculate the interpolation without
> overflowing the intermediate product.
>
> Fixes: 0e94682b73bf ("psi: introduce psi monitor")
> Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>

Sorry for the delay in reviewing these fixes. The fix looks correct to me.

Acked-by: Suren Baghdasaryan <surenb@google.com>

> ---
>  kernel/sched/psi.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
> index 4e152410653d..8e4df8b17c25 100644
> --- a/kernel/sched/psi.c
> +++ b/kernel/sched/psi.c
> @@ -137,6 +137,7 @@
>   * sampling of the aggregate task states would be.
>   */
>  #include <linux/sched/clock.h>
> +#include <linux/math64.h>
>  #include <linux/workqueue.h>
>  #include <linux/psi.h>
>  #include "sched.h"
> @@ -451,10 +452,11 @@ static u64 window_update(struct psi_window *win, u64 now, u64 value)
>         if (elapsed > win->size)
>                 window_reset(win, now, value, growth);
>         else {
> -               u32 remaining;
> +               u64 remaining;
>
>                 remaining = win->size - elapsed;
> -               growth += div64_u64(win->prev_growth * remaining, win->size);
> +               growth += mul_u64_u64_div_u64(win->prev_growth, remaining,
> +                                             win->size);
>         }
>
>         return growth;
> --
> 2.43.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit
  2026-07-17 10:28 ` [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit Guopeng Zhang
@ 2026-07-27  3:24   ` Suren Baghdasaryan
  2026-07-28  8:52   ` Tao Cui
  1 sibling, 0 replies; 7+ messages in thread
From: Suren Baghdasaryan @ 2026-07-27  3:24 UTC (permalink / raw)
  To: Guopeng Zhang
  Cc: Johannes Weiner, Peter Zijlstra, Ingo Molnar, Juri Lelli,
	Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
	Mel Gorman, Valentin Schneider, K Prateek Nayak, Andrew Morton,
	linux-kernel

On Fri, Jul 17, 2026 at 3:29 AM Guopeng Zhang <guopeng.zhang@linux.dev> wrote:
>
> From: Guopeng Zhang <zhangguopeng@kylinos.cn>
>
> threshold_us and window_us are u32, while NSEC_PER_USEC is 1000L. On
> 32-bit architectures, multiplication by NSEC_PER_USEC is evaluated
> using 32-bit unsigned arithmetic and can wrap before the result is
> assigned to the u64 trigger fields.
>
> For a valid 4,000,000 us threshold and 6,000,000 us window, the
> threshold is stored as 4,000,000,000 ns, while the window wraps to
> 1,705,032,704 ns. The stored window is therefore shorter than the
> threshold, so the trigger no longer monitors the requested 4-second
> threshold over a 6-second window.
>
> Cast both values to u64 before the multiplication so that the
> conversion to nanoseconds is performed using 64-bit arithmetic.
>
> Fixes: 0e94682b73bf ("psi: introduce psi monitor")
> Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>

Acked-by: Suren Baghdasaryan <surenb@google.com>

> ---
>  kernel/sched/psi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
> index 8e4df8b17c25..f0a5976f49dc 100644
> --- a/kernel/sched/psi.c
> +++ b/kernel/sched/psi.c
> @@ -1391,8 +1391,8 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, char *buf,
>
>         t->group = group;
>         t->state = state;
> -       t->threshold = threshold_us * NSEC_PER_USEC;
> -       t->win.size = window_us * NSEC_PER_USEC;
> +       t->threshold = (u64)threshold_us * NSEC_PER_USEC;
> +       t->win.size = (u64)window_us * NSEC_PER_USEC;
>         window_reset(&t->win, sched_clock(),
>                         group->total[PSI_POLL][t->state], 0);
>
> --
> 2.43.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] sched/psi: Fix long-window growth interpolation
  2026-07-17 10:28 ` [PATCH 1/2] sched/psi: Fix long-window growth interpolation Guopeng Zhang
  2026-07-27  3:17   ` Suren Baghdasaryan
@ 2026-07-28  8:49   ` Tao Cui
  1 sibling, 0 replies; 7+ messages in thread
From: Tao Cui @ 2026-07-28  8:49 UTC (permalink / raw)
  To: guopeng.zhang
  Cc: akpm, bsegall, dietmar.eggemann, hannes, juri.lelli,
	kprateek.nayak, linux-kernel, mgorman, mingo, peterz, rostedt,
	surenb, vincent.guittot, vschneid, cui.tao, Tao Cui

From: Tao Cui <cuitao@kylinos.cn>

On Fri, Jul 17, 2026 at 3:29 AM Guopeng Zhang <guopeng.zhang@linux.dev> wrote:
>
> From: Guopeng Zhang <zhangguopeng@kylinos.cn>
>
> PSI trigger windows are stored in nanoseconds and can be up to 10
> seconds, but window_update() stores the remaining interval in a u32.
> For example, after 2 seconds have elapsed in a 10-second window, the
> remaining 8,000,000,000 ns is truncated to 3,705,032,704 ns.
>
> Making remaining a u64 avoids the truncation, but the multiplication
> can still overflow before the division. Both win->prev_growth and
> remaining can be close to 10,000,000,000, so their product can exceed
> U64_MAX.
>
> Store the remaining interval in a u64 and use
> mul_u64_u64_div_u64() to calculate the interpolation without
> overflowing the intermediate product.
>
> Fixes: 0e94682b73bf ("psi: introduce psi monitor")
> Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>

Acked-by: Tao Cui <cuitao@kylinos.cn>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit
  2026-07-17 10:28 ` [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit Guopeng Zhang
  2026-07-27  3:24   ` Suren Baghdasaryan
@ 2026-07-28  8:52   ` Tao Cui
  1 sibling, 0 replies; 7+ messages in thread
From: Tao Cui @ 2026-07-28  8:52 UTC (permalink / raw)
  To: guopeng.zhang
  Cc: akpm, bsegall, dietmar.eggemann, hannes, juri.lelli,
	kprateek.nayak, linux-kernel, mgorman, mingo, peterz, rostedt,
	surenb, vincent.guittot, vschneid, cui.tao, Tao Cui

From: Tao Cui <cuitao@kylinos.cn>

On Fri, Jul 17, 2026 at 3:29 AM Guopeng Zhang <guopeng.zhang@linux.dev> wrote:
>
> From: Guopeng Zhang <zhangguopeng@kylinos.cn>
>
> threshold_us and window_us are u32, while NSEC_PER_USEC is 1000L. On
> 32-bit architectures, multiplication by NSEC_PER_USEC is evaluated
> using 32-bit unsigned arithmetic and can wrap before the result is
> assigned to the u64 trigger fields.
>
> For a valid 4,000,000 us threshold and 6,000,000 us window, the
> threshold is stored as 4,000,000,000 ns, while the window wraps to
> 1,705,032,704 ns. The stored window is therefore shorter than the
> threshold, so the trigger no longer monitors the requested 4-second
> threshold over a 6-second window.
>
> Cast both values to u64 before the multiplication so that the
> conversion to nanoseconds is performed using 64-bit arithmetic.
>
> Fixes: 0e94682b73bf ("psi: introduce psi monitor")
> Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>

Acked-by: Tao Cui <cuitao@kylinos.cn>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-07-28  8:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-17 10:28 [PATCH 0/2] sched/psi: Fix trigger time arithmetic Guopeng Zhang
2026-07-17 10:28 ` [PATCH 1/2] sched/psi: Fix long-window growth interpolation Guopeng Zhang
2026-07-27  3:17   ` Suren Baghdasaryan
2026-07-28  8:49   ` Tao Cui
2026-07-17 10:28 ` [PATCH 2/2] sched/psi: Fix overflow in trigger time conversion on 32-bit Guopeng Zhang
2026-07-27  3:24   ` Suren Baghdasaryan
2026-07-28  8:52   ` Tao Cui

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.