All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.