[PATCH] random: Fix crashes with sparse node ids
Michael Ellerman
mpe at ellerman.id.au
Sun Jul 31 13:27:17 AEST 2016
Linus Torvalds <torvalds at linux-foundation.org> writes:
> On Sat, Jul 30, 2016 at 7:23 AM, Michael Ellerman <mpe at ellerman.id.au> wrote:
>> #ifdef CONFIG_NUMA
>> - pool = kmalloc(num_nodes * sizeof(void *),
>> + pool = kmalloc(nr_node_ids * sizeof(void *),
>> GFP_KERNEL|__GFP_NOFAIL|__GFP_ZERO);
>> for_each_online_node(i) {
>> crng = kmalloc_node(sizeof(struct crng_state),
>
> Ugh. Can we please also just change that kmalloc to kcalloc()? Get rid
> of the odd multiplication and the unusual GFP mask bit crud?
>
> And instead of using "sizeof(void *)", just use the pool entry size,
> ie "sizeof(*pool)". Yes, we have other places where we depend on void
> pointers having the same size as others, but it's the RightThing(tm)
> to do anyway, and it makes more sense when you grep things ("Oh, we're
> allocating 'nr_node_id' copes of *pool entries" even without knowing
> what type is behind the "pool" pointer).
>
> IOW, can you confirm that you could just use
>
> pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL);
>
> instead? I'd much rather apply that patch.
Dropping NOFAIL means we need to handle allocation failures, which makes
the patch a bit bigger, and less of a pure fix.
Here's a separate patch to do those cleanups, which you can squash with
the first if you prefer.
I did test the allocation failure case for both the whole pool and
individual nodes.
cheers
>From 2f5ab5fa2b9e4997fe01053fc12f689fb2117f45 Mon Sep 17 00:00:00 2001
From: Michael Ellerman <mpe at ellerman.id.au>
Date: Sun, 31 Jul 2016 12:54:40 +1000
Subject: [PATCH] random: Clean up NUMA allocations
Use kcalloc(), rather than doing the multiply by hand. Use sizeof(*pool)
rather than assuming it's == sizeof(void *). kcalloc() zeroes by default
so we don't need __GFP_ZERO.
Drop the __GFP_NOFAILs, we can easily handle allocation failures, the
code is already written to cope with a NULL crng_node_pool, or a NULL
entry for a given node in the pool.
Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
---
drivers/char/random.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index ea03dfe2f21c..22c8ac173666 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1666,11 +1666,15 @@ static int rand_initialize(void)
crng_initialize(&primary_crng);
#ifdef CONFIG_NUMA
- pool = kmalloc(nr_node_ids * sizeof(void *),
- GFP_KERNEL|__GFP_NOFAIL|__GFP_ZERO);
+ pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL);
+ if (!pool)
+ return 0;
+
for_each_online_node(i) {
- crng = kmalloc_node(sizeof(struct crng_state),
- GFP_KERNEL | __GFP_NOFAIL, i);
+ crng = kmalloc_node(sizeof(struct crng_state), GFP_KERNEL, i);
+ if (!crng)
+ continue;
+
spin_lock_init(&crng->lock);
crng_initialize(crng);
pool[i] = crng;
--
2.7.4
More information about the Linuxppc-dev
mailing list