Skip to content

Commit ccdec92

Browse files
Xuewen Yanhtejun
authored andcommitted
workqueue: Control intensive warning threshold through cmdline
When CONFIG_WQ_CPU_INTENSIVE_REPORT is set, the kernel will report the work functions which violate the intensive_threshold_us repeatedly. And now, only when the violate times exceed 4 and is a power of 2, the kernel warning could be triggered. However, sometimes, even if a long work execution time occurs only once, it may cause other work to be delayed for a long time. This may also cause some problems sometimes. In order to freely control the threshold of warninging, a boot argument is added so that the user can control the warning threshold to be printed. At the same time, keep the exponential backoff to prevent reporting too much. By default, the warning threshold is 4. tj: Updated kernel-parameters.txt description. Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent bccdc1f commit ccdec92

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7219,6 +7219,15 @@
72197219
threshold repeatedly. They are likely good
72207220
candidates for using WQ_UNBOUND workqueues instead.
72217221

7222+
workqueue.cpu_intensive_warning_thresh=<uint>
7223+
If CONFIG_WQ_CPU_INTENSIVE_REPORT is set, the kernel
7224+
will report the work functions which violate the
7225+
intensive_threshold_us repeatedly. In order to prevent
7226+
spurious warnings, start printing only after a work
7227+
function has violated this threshold number of times.
7228+
7229+
The default is 4 times. 0 disables the warning.
7230+
72227231
workqueue.power_efficient
72237232
Per-cpu workqueues are generally preferred because
72247233
they show better performance thanks to cache

kernel/workqueue.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ static const char *wq_affn_names[WQ_AFFN_NR_TYPES] = {
409409
*/
410410
static unsigned long wq_cpu_intensive_thresh_us = ULONG_MAX;
411411
module_param_named(cpu_intensive_thresh_us, wq_cpu_intensive_thresh_us, ulong, 0644);
412+
#ifdef CONFIG_WQ_CPU_INTENSIVE_REPORT
413+
static unsigned int wq_cpu_intensive_warning_thresh = 4;
414+
module_param_named(cpu_intensive_warning_thresh, wq_cpu_intensive_warning_thresh, uint, 0644);
415+
#endif
412416

413417
/* see the comment above the definition of WQ_POWER_EFFICIENT */
414418
static bool wq_power_efficient = IS_ENABLED(CONFIG_WQ_POWER_EFFICIENT_DEFAULT);
@@ -1327,11 +1331,13 @@ static void wq_cpu_intensive_report(work_func_t func)
13271331
u64 cnt;
13281332

13291333
/*
1330-
* Start reporting from the fourth time and back off
1334+
* Start reporting from the warning_thresh and back off
13311335
* exponentially.
13321336
*/
13331337
cnt = atomic64_inc_return_relaxed(&ent->cnt);
1334-
if (cnt >= 4 && is_power_of_2(cnt))
1338+
if (wq_cpu_intensive_warning_thresh &&
1339+
cnt >= wq_cpu_intensive_warning_thresh &&
1340+
is_power_of_2(cnt + 1 - wq_cpu_intensive_warning_thresh))
13351341
printk_deferred(KERN_WARNING "workqueue: %ps hogged CPU for >%luus %llu times, consider switching to WQ_UNBOUND\n",
13361342
ent->func, wq_cpu_intensive_thresh_us,
13371343
atomic64_read(&ent->cnt));
@@ -1360,10 +1366,12 @@ static void wq_cpu_intensive_report(work_func_t func)
13601366

13611367
ent = &wci_ents[wci_nr_ents++];
13621368
ent->func = func;
1363-
atomic64_set(&ent->cnt, 1);
1369+
atomic64_set(&ent->cnt, 0);
13641370
hash_add_rcu(wci_hash, &ent->hash_node, (unsigned long)func);
13651371

13661372
raw_spin_unlock(&wci_lock);
1373+
1374+
goto restart;
13671375
}
13681376

13691377
#else /* CONFIG_WQ_CPU_INTENSIVE_REPORT */

0 commit comments

Comments
 (0)