* [PATCH] random: use offstack cpumask when necessary
@ 2025-06-10 9:27 Arnd Bergmann
2025-06-10 17:33 ` Jason A. Donenfeld
2025-06-11 4:06 ` kernel test robot
0 siblings, 2 replies; 3+ messages in thread
From: Arnd Bergmann @ 2025-06-10 9:27 UTC (permalink / raw)
To: Theodore Ts'o, Jason A. Donenfeld
Cc: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Eric Biggers,
Joel Granados, Christophe Leroy, Paul E. McKenney, linux-kernel
From: Arnd Bergmann <arnd@arndb.de>
The entropy generation function keeps a local cpu mask on the stack, which
can trigger warnings in configurations with a large number of CPUs:
drivers/char/random.c:1292:20: error: stack frame size (1288) exceeds limit (1280) in 'try_to_generate_entropy' [-Werror,-Wframe-larger-than]
Use the cpumask interface to dynamically allocate it in those configurations.
Fixes: 1c21fe00eda7 ("random: spread out jitter callback to different CPUs")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/char/random.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index b8b24b6ed3fe..04800b75cf73 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1296,6 +1296,7 @@ static void __cold try_to_generate_entropy(void)
struct entropy_timer_state *stack = PTR_ALIGN((void *)stack_bytes, SMP_CACHE_BYTES);
unsigned int i, num_different = 0;
unsigned long last = random_get_entropy();
+ cpumask_var_t timer_cpus;
int cpu = -1;
for (i = 0; i < NUM_TRIAL_SAMPLES - 1; ++i) {
@@ -1310,13 +1311,15 @@ static void __cold try_to_generate_entropy(void)
atomic_set(&stack->samples, 0);
timer_setup_on_stack(&stack->timer, entropy_timer, 0);
+ if (!alloc_cpumask_var(&timer_cpus, GFP_KERNEL))
+ goto out;;
+
while (!crng_ready() && !signal_pending(current)) {
/*
* Check !timer_pending() and then ensure that any previous callback has finished
* executing by checking timer_delete_sync_try(), before queueing the next one.
*/
if (!timer_pending(&stack->timer) && timer_delete_sync_try(&stack->timer) >= 0) {
- struct cpumask timer_cpus;
unsigned int num_cpus;
/*
@@ -1326,19 +1329,19 @@ static void __cold try_to_generate_entropy(void)
preempt_disable();
/* Only schedule callbacks on timer CPUs that are online. */
- cpumask_and(&timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask);
- num_cpus = cpumask_weight(&timer_cpus);
+ cpumask_and(timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask);
+ num_cpus = cpumask_weight(timer_cpus);
/* In very bizarre case of misconfiguration, fallback to all online. */
if (unlikely(num_cpus == 0)) {
- timer_cpus = *cpu_online_mask;
- num_cpus = cpumask_weight(&timer_cpus);
+ *timer_cpus = *cpu_online_mask;
+ num_cpus = cpumask_weight(timer_cpus);
}
/* Basic CPU round-robin, which avoids the current CPU. */
do {
- cpu = cpumask_next(cpu, &timer_cpus);
+ cpu = cpumask_next(cpu, timer_cpus);
if (cpu >= nr_cpu_ids)
- cpu = cpumask_first(&timer_cpus);
+ cpu = cpumask_first(timer_cpus);
} while (cpu == smp_processor_id() && num_cpus > 1);
/* Expiring the timer at `jiffies` means it's the next tick. */
@@ -1354,6 +1357,8 @@ static void __cold try_to_generate_entropy(void)
}
mix_pool_bytes(&stack->entropy, sizeof(stack->entropy));
+ free_cpumask_var(timer_cpus);
+out:
timer_delete_sync(&stack->timer);
timer_destroy_on_stack(&stack->timer);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] random: use offstack cpumask when necessary
2025-06-10 9:27 [PATCH] random: use offstack cpumask when necessary Arnd Bergmann
@ 2025-06-10 17:33 ` Jason A. Donenfeld
2025-06-11 4:06 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: Jason A. Donenfeld @ 2025-06-10 17:33 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Theodore Ts'o, Arnd Bergmann, Thomas Gleixner, Ingo Molnar,
Eric Biggers, Joel Granados, Christophe Leroy, Paul E. McKenney,
linux-kernel
Hi Arnd,
On Tue, Jun 10, 2025 at 11:27:08AM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> The entropy generation function keeps a local cpu mask on the stack, which
> can trigger warnings in configurations with a large number of CPUs:
>
> drivers/char/random.c:1292:20: error: stack frame size (1288) exceeds limit (1280) in 'try_to_generate_entropy' [-Werror,-Wframe-larger-than]
>
> Use the cpumask interface to dynamically allocate it in those configurations.
Thanks. I hadn't seen this interface before. Applied with one nit fixed:
> + goto out;;
Double semi-colon changed to single semi-colon.
Jason
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] random: use offstack cpumask when necessary
2025-06-10 9:27 [PATCH] random: use offstack cpumask when necessary Arnd Bergmann
2025-06-10 17:33 ` Jason A. Donenfeld
@ 2025-06-11 4:06 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2025-06-11 4:06 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: oe-kbuild-all
Hi Arnd,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master]
[also build test WARNING on v6.16-rc1 next-20250610]
[cannot apply to crng-random/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Arnd-Bergmann/random-use-offstack-cpumask-when-necessary/20250610-173051
base: linus/master
patch link: https://lore.kernel.org/r/20250610092712.2641547-1-arnd%40kernel.org
patch subject: [PATCH] random: use offstack cpumask when necessary
config: hexagon-randconfig-r051-20250611 (https://download.01.org/0day-ci/archive/20250611/202506111146.aZm5lzhz-lkp@intel.com/config)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project f819f46284f2a79790038e1f6649172789734ae8)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202506111146.aZm5lzhz-lkp@intel.com/
cocci warnings: (new ones prefixed by >>)
>> drivers/char/random.c:1315:11-12: Unneeded semicolon
vim +1315 drivers/char/random.c
1287
1288 /*
1289 * If we have an actual cycle counter, see if we can generate enough entropy
1290 * with timing noise.
1291 */
1292 static void __cold try_to_generate_entropy(void)
1293 {
1294 enum { NUM_TRIAL_SAMPLES = 8192, MAX_SAMPLES_PER_BIT = HZ / 15 };
1295 u8 stack_bytes[sizeof(struct entropy_timer_state) + SMP_CACHE_BYTES - 1];
1296 struct entropy_timer_state *stack = PTR_ALIGN((void *)stack_bytes, SMP_CACHE_BYTES);
1297 unsigned int i, num_different = 0;
1298 unsigned long last = random_get_entropy();
1299 cpumask_var_t timer_cpus;
1300 int cpu = -1;
1301
1302 for (i = 0; i < NUM_TRIAL_SAMPLES - 1; ++i) {
1303 stack->entropy = random_get_entropy();
1304 if (stack->entropy != last)
1305 ++num_different;
1306 last = stack->entropy;
1307 }
1308 stack->samples_per_bit = DIV_ROUND_UP(NUM_TRIAL_SAMPLES, num_different + 1);
1309 if (stack->samples_per_bit > MAX_SAMPLES_PER_BIT)
1310 return;
1311
1312 atomic_set(&stack->samples, 0);
1313 timer_setup_on_stack(&stack->timer, entropy_timer, 0);
1314 if (!alloc_cpumask_var(&timer_cpus, GFP_KERNEL))
> 1315 goto out;;
1316
1317 while (!crng_ready() && !signal_pending(current)) {
1318 /*
1319 * Check !timer_pending() and then ensure that any previous callback has finished
1320 * executing by checking timer_delete_sync_try(), before queueing the next one.
1321 */
1322 if (!timer_pending(&stack->timer) && timer_delete_sync_try(&stack->timer) >= 0) {
1323 unsigned int num_cpus;
1324
1325 /*
1326 * Preemption must be disabled here, both to read the current CPU number
1327 * and to avoid scheduling a timer on a dead CPU.
1328 */
1329 preempt_disable();
1330
1331 /* Only schedule callbacks on timer CPUs that are online. */
1332 cpumask_and(timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask);
1333 num_cpus = cpumask_weight(timer_cpus);
1334 /* In very bizarre case of misconfiguration, fallback to all online. */
1335 if (unlikely(num_cpus == 0)) {
1336 *timer_cpus = *cpu_online_mask;
1337 num_cpus = cpumask_weight(timer_cpus);
1338 }
1339
1340 /* Basic CPU round-robin, which avoids the current CPU. */
1341 do {
1342 cpu = cpumask_next(cpu, timer_cpus);
1343 if (cpu >= nr_cpu_ids)
1344 cpu = cpumask_first(timer_cpus);
1345 } while (cpu == smp_processor_id() && num_cpus > 1);
1346
1347 /* Expiring the timer at `jiffies` means it's the next tick. */
1348 stack->timer.expires = jiffies;
1349
1350 add_timer_on(&stack->timer, cpu);
1351
1352 preempt_enable();
1353 }
1354 mix_pool_bytes(&stack->entropy, sizeof(stack->entropy));
1355 schedule();
1356 stack->entropy = random_get_entropy();
1357 }
1358 mix_pool_bytes(&stack->entropy, sizeof(stack->entropy));
1359
1360 free_cpumask_var(timer_cpus);
1361 out:
1362 timer_delete_sync(&stack->timer);
1363 timer_destroy_on_stack(&stack->timer);
1364 }
1365
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-06-11 4:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-10 9:27 [PATCH] random: use offstack cpumask when necessary Arnd Bergmann
2025-06-10 17:33 ` Jason A. Donenfeld
2025-06-11 4:06 ` kernel test robot
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.