Re: [PATCH] mm/mempolicy: Fix sleeping allocation in alloc_pages_bulk_weighted_interleave()
Andrew Morton <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.kernel.mm |
|---|---|
| Message-ID | <[email protected]> |
On Fri, 21 Aug 2026 17:04:07 +0000 Eric Dumazet <[email protected]> wrote: > syzbot reported a sleeping function called from invalid context splat > in bucket_table_alloc(). That was quick (7 minutes!). I was just looking at this. > When rhashtable_insert_slow() rehashes the table under rcu_read_lock(), > it calls bucket_table_alloc(..., GFP_ATOMIC | __GFP_NOWARN). > If the bucket table allocation uses vmalloc, __vmalloc_node_range_noprof() > invokes vm_area_alloc_pages() -> alloc_pages_bulk_mempolicy_noprof() with > the passed GFP_ATOMIC flags. > > If the current task has an MPOL_WEIGHTED_INTERLEAVE mempolicy, > alloc_pages_bulk_weighted_interleave() is called and currently hardcodes > GFP_KERNEL when allocating the temporary weights array, triggering > a might_alloc() splat in atomic/RCU contexts. 2 years ago. Why are we discovering this now? > Pass the gfp flags (masked with GFP_RECLAIM_MASK to strip page-allocator > zone modifiers like __GFP_HIGHMEM) received by > alloc_pages_bulk_weighted_interleave() to kmalloc() instead of > hardcoding GFP_KERNEL. Since the weights buffer is immediately > initialized in full, kmalloc() is sufficient. > > Fixes: fa3bea4e1f82 ("mm/mempolicy: introduce MPOL_WEIGHTED_INTERLEAVE for weighted interleaving") I'll add cc:stable > --- a/mm/mempolicy.c > +++ b/mm/mempolicy.c > @@ -2688,7 +2688,7 @@ static unsigned long alloc_pages_bulk_weighted_interleave(gfp_t gfp, > prev_node = node; > > /* create a local copy of node weights to operate on outside rcu */ > - weights = kzalloc(nr_node_ids, GFP_KERNEL); > + weights = kmalloc(nr_node_ids, gfp & GFP_RECLAIM_MASK); lgtm, thanks. I wonder if we *really* need the local copy of state->iw_table. Perhaps with appropriate care we can directly use state->iw_table in here. How much would it hurt to expand the rcu_read_lock() coverage? A local array of MAX_NUMNODES bytes isn't attractive - 1k of stack. A spinlock-protected static array would work, if super-rare slowpath. > if (!weights) > return total_allocated;