Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mempolicy: fix div-by-zero in alloc_pages_bulk_weighted_interleave
@ 2026-09-02  9:04 Liu Jing
  2026-09-02 13:57 ` Gregory Price
  0 siblings, 1 reply; 4+ messages in thread
From: Liu Jing @ 2026-09-02  9:04 UTC (permalink / raw)
  To: akpm
  Cc: david, ziy, matthew.brost, joshua.hahnjy, rakie.kim, byungchul,
	gourry, ying.huang, apopple, linux-mm, linux-kernel, Liu Jing

In alloc_pages_bulk_weighted_interleave(), if the iw_table contains
all-zero weights for every node in the policy nodemask, weight_total
sums to zero. The subsequent "rem_pages / weight_total" and
"rem_pages % weight_total" trigger a divide-by-zero panic.

The function already guards against !nnodes but not against a zero
weight_total. Add the missing check, freeing the locally allocated
weights buffer before returning.

Signed-off-by: Liu Jing <liujing@cmss.chinamobile.com>
---
 mm/mempolicy.c | 5 +++++
 1 file changed, 5 insertion(+), 0 deletion(-)

--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2697,6 +2697,11 @@
 	/* calculate total, detect system default usage */
 	for_each_node_mask(node, nodes)
 		weight_total += weights[node];
+
+	if (!weight_total) {
+		kfree(weights);
+		return total_allocated;
+	}
 
 	/*
 	 * Calculate rounds/partial rounds to minimize __alloc_pages_bulk calls.

--
2.43.0




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

* Re: [PATCH] mempolicy: fix div-by-zero in alloc_pages_bulk_weighted_interleave
  2026-09-02  9:04 [PATCH] mempolicy: fix div-by-zero in alloc_pages_bulk_weighted_interleave Liu Jing
@ 2026-09-02 13:57 ` Gregory Price
  2026-09-02 21:40   ` Andrew Morton
  0 siblings, 1 reply; 4+ messages in thread
From: Gregory Price @ 2026-09-02 13:57 UTC (permalink / raw)
  To: Liu Jing
  Cc: akpm, david, ziy, matthew.brost, joshua.hahnjy, rakie.kim,
	byungchul, ying.huang, apopple, linux-mm, linux-kernel

On Wed, Sep 02, 2026 at 05:04:12PM +0800, Liu Jing wrote:
> In alloc_pages_bulk_weighted_interleave(), if the iw_table contains
> all-zero weights for every node in the policy nodemask, weight_total
> sums to zero. The subsequent "rem_pages / weight_total" and
> "rem_pages % weight_total" trigger a divide-by-zero panic.
> 

weights can't be zero and we just fixed the rebind race

> The function already guards against !nnodes but not against a zero
> weight_total. Add the missing check, freeing the locally allocated
> weights buffer before returning.
> 
> Signed-off-by: Liu Jing <liujing@cmss.chinamobile.com>
> ---
>  mm/mempolicy.c | 5 +++++
>  1 file changed, 5 insertion(+), 0 deletion(-)
> 
> --- a/mm/mempolicy.c
> +++ b/mm/mempolicy.c
> @@ -2697,6 +2697,11 @@
>  	/* calculate total, detect system default usage */
>  	for_each_node_mask(node, nodes)
>  		weight_total += weights[node];
> +
> +	if (!weight_total) {
> +		kfree(weights);
> +		return total_allocated;
> +	}
>  
>  	/*
>  	 * Calculate rounds/partial rounds to minimize __alloc_pages_bulk calls.
> 
> --
> 2.43.0
> 
> 


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

* Re: [PATCH] mempolicy: fix div-by-zero in alloc_pages_bulk_weighted_interleave
  2026-09-02 13:57 ` Gregory Price
@ 2026-09-02 21:40   ` Andrew Morton
  2026-09-02 21:52     ` Gregory Price
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Morton @ 2026-09-02 21:40 UTC (permalink / raw)
  To: Gregory Price
  Cc: Liu Jing, david, ziy, matthew.brost, joshua.hahnjy, rakie.kim,
	byungchul, ying.huang, apopple, linux-mm, linux-kernel

On Wed, 2 Sep 2026 09:57:35 -0400 Gregory Price <gourry@gourry.net> wrote:

> On Wed, Sep 02, 2026 at 05:04:12PM +0800, Liu Jing wrote:
> > In alloc_pages_bulk_weighted_interleave(), if the iw_table contains
> > all-zero weights for every node in the policy nodemask, weight_total
> > sums to zero. The subsequent "rem_pages / weight_total" and
> > "rem_pages % weight_total" trigger a divide-by-zero panic.
> > 
> 
> weights can't be zero and we just fixed the rebind race

So if the caller passes in me->weight==0 then we consider that caller
to be buggy.

In which case a div-by-zero is a perfectly acceptable way of reporting
this bug, no code changes needed,


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

* Re: [PATCH] mempolicy: fix div-by-zero in alloc_pages_bulk_weighted_interleave
  2026-09-02 21:40   ` Andrew Morton
@ 2026-09-02 21:52     ` Gregory Price
  0 siblings, 0 replies; 4+ messages in thread
From: Gregory Price @ 2026-09-02 21:52 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Liu Jing, david, ziy, matthew.brost, joshua.hahnjy, rakie.kim,
	byungchul, ying.huang, apopple, linux-mm, linux-kernel

On Wed, Sep 02, 2026 at 02:40:39PM -0700, Andrew Morton wrote:
> On Wed, 2 Sep 2026 09:57:35 -0400 Gregory Price <gourry@gourry.net> wrote:
> 
> > On Wed, Sep 02, 2026 at 05:04:12PM +0800, Liu Jing wrote:
> > > In alloc_pages_bulk_weighted_interleave(), if the iw_table contains
> > > all-zero weights for every node in the policy nodemask, weight_total
> > > sums to zero. The subsequent "rem_pages / weight_total" and
> > > "rem_pages % weight_total" trigger a divide-by-zero panic.
> > > 
> > 
> > weights can't be zero and we just fixed the rebind race
> 
> So if the caller passes in me->weight==0 then we consider that caller
> to be buggy.
> 

basically weights cannot be 0 by construction:

What:           /sys/kernel/mm/mempolicy/weighted_interleave/nodeN
...
                The minimum weight for a node is always 1.

What:           /sys/kernel/mm/mempolicy/weighted_interleave/auto
...
                If they were not previously set or are onlined with missing
		bandwidth data, the weights will use a default weight of 1.


int mempolicy_set_node_perf(unsigned int node, struct access_coordinate *coords)
{       
...
        new_wi_state->mode_auto = true;
        for (i = 0; i < nr_node_ids; i++)
                new_wi_state->iw_table[i] = 1;


static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr,
                          const char *buf, size_t count)
{
...
                for (i = 0; i < nr_node_ids; i++)
                        new_wi_state->iw_table[i] = 1;


static ssize_t weighted_interleave_auto_store(struct kobject *kobj,
                struct kobj_attribute *attr, const char *buf, size_t count)
{
...
        for (i = 0; i < nr_node_ids; i++)
                new_wi_state->iw_table[i] = 1;


we default all weights to 1 and never let calculation drop below 1 for
exactly this div/0 reason.

The div/0 risk came solely from the torn nodemask read issue.

~Gregory


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

end of thread, other threads:[~2026-09-02 21:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02  9:04 [PATCH] mempolicy: fix div-by-zero in alloc_pages_bulk_weighted_interleave Liu Jing
2026-09-02 13:57 ` Gregory Price
2026-09-02 21:40   ` Andrew Morton
2026-09-02 21:52     ` Gregory Price

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox