52
52
#include <linux/sched/debug.h>
53
53
#include <linux/nmi.h>
54
54
#include <linux/kvm_para.h>
55
+ #include <linux/delay.h>
55
56
56
57
#include "workqueue_internal.h"
57
58
@@ -338,8 +339,10 @@ static cpumask_var_t *wq_numa_possible_cpumask;
338
339
* Per-cpu work items which run for longer than the following threshold are
339
340
* automatically considered CPU intensive and excluded from concurrency
340
341
* management to prevent them from noticeably delaying other per-cpu work items.
342
+ * ULONG_MAX indicates that the user hasn't overridden it with a boot parameter.
343
+ * The actual value is initialized in wq_cpu_intensive_thresh_init().
341
344
*/
342
- static unsigned long wq_cpu_intensive_thresh_us = 10000 ;
345
+ static unsigned long wq_cpu_intensive_thresh_us = ULONG_MAX ;
343
346
module_param_named (cpu_intensive_thresh_us , wq_cpu_intensive_thresh_us , ulong , 0644 );
344
347
345
348
static bool wq_disable_numa ;
@@ -6516,6 +6519,42 @@ void __init workqueue_init_early(void)
6516
6519
!system_freezable_power_efficient_wq );
6517
6520
}
6518
6521
6522
+ static void __init wq_cpu_intensive_thresh_init (void )
6523
+ {
6524
+ unsigned long thresh ;
6525
+ unsigned long bogo ;
6526
+
6527
+ /* if the user set it to a specific value, keep it */
6528
+ if (wq_cpu_intensive_thresh_us != ULONG_MAX )
6529
+ return ;
6530
+
6531
+ /*
6532
+ * The default of 10ms is derived from the fact that most modern (as of
6533
+ * 2023) processors can do a lot in 10ms and that it's just below what
6534
+ * most consider human-perceivable. However, the kernel also runs on a
6535
+ * lot slower CPUs including microcontrollers where the threshold is way
6536
+ * too low.
6537
+ *
6538
+ * Let's scale up the threshold upto 1 second if BogoMips is below 4000.
6539
+ * This is by no means accurate but it doesn't have to be. The mechanism
6540
+ * is still useful even when the threshold is fully scaled up. Also, as
6541
+ * the reports would usually be applicable to everyone, some machines
6542
+ * operating on longer thresholds won't significantly diminish their
6543
+ * usefulness.
6544
+ */
6545
+ thresh = 10 * USEC_PER_MSEC ;
6546
+
6547
+ /* see init/calibrate.c for lpj -> BogoMIPS calculation */
6548
+ bogo = max_t (unsigned long , loops_per_jiffy / 500000 * HZ , 1 );
6549
+ if (bogo < 4000 )
6550
+ thresh = min_t (unsigned long , thresh * 4000 / bogo , USEC_PER_SEC );
6551
+
6552
+ pr_debug ("wq_cpu_intensive_thresh: lpj=%lu BogoMIPS=%lu thresh_us=%lu\n" ,
6553
+ loops_per_jiffy , bogo , thresh );
6554
+
6555
+ wq_cpu_intensive_thresh_us = thresh ;
6556
+ }
6557
+
6519
6558
/**
6520
6559
* workqueue_init - bring workqueue subsystem fully online
6521
6560
*
@@ -6531,6 +6570,8 @@ void __init workqueue_init(void)
6531
6570
struct worker_pool * pool ;
6532
6571
int cpu , bkt ;
6533
6572
6573
+ wq_cpu_intensive_thresh_init ();
6574
+
6534
6575
/*
6535
6576
* It'd be simpler to initialize NUMA in workqueue_init_early() but
6536
6577
* CPU to node mapping may not be available that early on some
0 commit comments