]> Git Repo - linux.git/commitdiff
workqueue: Control intensive warning threshold through cmdline
authorXuewen Yan <[email protected]>
Thu, 22 Feb 2024 07:28:08 +0000 (15:28 +0800)
committerTejun Heo <[email protected]>
Thu, 22 Feb 2024 17:50:45 +0000 (07:50 -1000)
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 <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
Documentation/admin-guide/kernel-parameters.txt
kernel/workqueue.c

index 6ee0f9a5da706a03a5716611b0cdd2463f696db6..c0e9abbf1d2f90072154f435e8cbf88444ef2964 100644 (file)
                        threshold repeatedly. They are likely good
                        candidates for using WQ_UNBOUND workqueues instead.
 
+       workqueue.cpu_intensive_warning_thresh=<uint>
+                       If CONFIG_WQ_CPU_INTENSIVE_REPORT is set, the kernel
+                       will report the work functions which violate the
+                       intensive_threshold_us repeatedly. In order to prevent
+                       spurious warnings, start printing only after a work
+                       function has violated this threshold number of times.
+
+                       The default is 4 times. 0 disables the warning.
+
        workqueue.power_efficient
                        Per-cpu workqueues are generally preferred because
                        they show better performance thanks to cache
index 65a27be8145239e82b5d213f0bce89fca831a880..38783e3a60bbfa627c34a308c5fb87b19615d533 100644 (file)
@@ -409,6 +409,10 @@ static const char *wq_affn_names[WQ_AFFN_NR_TYPES] = {
  */
 static unsigned long wq_cpu_intensive_thresh_us = ULONG_MAX;
 module_param_named(cpu_intensive_thresh_us, wq_cpu_intensive_thresh_us, ulong, 0644);
+#ifdef CONFIG_WQ_CPU_INTENSIVE_REPORT
+static unsigned int wq_cpu_intensive_warning_thresh = 4;
+module_param_named(cpu_intensive_warning_thresh, wq_cpu_intensive_warning_thresh, uint, 0644);
+#endif
 
 /* see the comment above the definition of WQ_POWER_EFFICIENT */
 static bool wq_power_efficient = IS_ENABLED(CONFIG_WQ_POWER_EFFICIENT_DEFAULT);
@@ -1327,11 +1331,13 @@ restart:
                u64 cnt;
 
                /*
-                * Start reporting from the fourth time and back off
+                * Start reporting from the warning_thresh and back off
                 * exponentially.
                 */
                cnt = atomic64_inc_return_relaxed(&ent->cnt);
-               if (cnt >= 4 && is_power_of_2(cnt))
+               if (wq_cpu_intensive_warning_thresh &&
+                   cnt >= wq_cpu_intensive_warning_thresh &&
+                   is_power_of_2(cnt + 1 - wq_cpu_intensive_warning_thresh))
                        printk_deferred(KERN_WARNING "workqueue: %ps hogged CPU for >%luus %llu times, consider switching to WQ_UNBOUND\n",
                                        ent->func, wq_cpu_intensive_thresh_us,
                                        atomic64_read(&ent->cnt));
@@ -1360,10 +1366,12 @@ restart:
 
        ent = &wci_ents[wci_nr_ents++];
        ent->func = func;
-       atomic64_set(&ent->cnt, 1);
+       atomic64_set(&ent->cnt, 0);
        hash_add_rcu(wci_hash, &ent->hash_node, (unsigned long)func);
 
        raw_spin_unlock(&wci_lock);
+
+       goto restart;
 }
 
 #else  /* CONFIG_WQ_CPU_INTENSIVE_REPORT */
This page took 0.112477 seconds and 4 git commands to generate.