diff options
| author | Marco Crivellari <marco.crivellari@suse.com> | 2026-05-29 15:06:40 +0200 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-05-29 07:56:48 -1000 |
| commit | 21c05ca88a548ca1353cbef189c97d4f03b90692 (patch) | |
| tree | 244946cf5e312e22d6cec6b1624a98403c8fd2c6 /kernel/workqueue.c | |
| parent | 64d8eae3f89583821f599c0aa398dd2e69b31a89 (diff) | |
workqueue: Add warnings and ensure one among WQ_PERCPU or WQ_UNBOUND is present
Currently there are no checks in order to enforce the use of one between
WQ_PERCPU or WQ_UNBOUND.
So act as following:
- if neither of them is present, set WQ_PERCPU
- if both are present, remove WQ_PERCPU
Along with this change, WARN_ONCE(), so that the code still uses both or
neither of them, can be changed.
Link: https://lore.kernel.org/all/20250221112003.1dSuoGyc@linutronix.de/
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/workqueue.c')
| -rw-r--r-- | kernel/workqueue.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 088cd9b70fca..34c7c61c69aa 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5802,7 +5802,7 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, /* see the comment above the definition of WQ_POWER_EFFICIENT */ if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient) - flags |= WQ_UNBOUND; + flags = (flags & ~WQ_PERCPU) | WQ_UNBOUND; /* allocate wq and format name */ if (flags & WQ_UNBOUND) @@ -5826,6 +5826,23 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, pr_warn_once("workqueue: name exceeds WQ_NAME_LEN. Truncating to: %s\n", wq->name); + /* + * One among WQ_PERCPU and WQ_UNBOUND must be set, but not both. + * - If neither is set, default to WQ_PERCPU + * - If both are set, default to WQ_UNBOUND + * + * This code can be removed after workqueue are unbound by default + */ + if (unlikely(!(flags & (WQ_UNBOUND | WQ_PERCPU)))) { + WARN_ONCE(1, "workqueue: %s is using neither WQ_PERCPU or WQ_UNBOUND. " + "Setting WQ_PERCPU.\n", wq->name); + flags |= WQ_PERCPU; + } else if (unlikely((flags & WQ_PERCPU) && (flags & WQ_UNBOUND))) { + WARN_ONCE(1, "workqueue: %s uses both WQ_PERCPU and WQ_UNBOUND. " + "Dropped WQ_PERCPU, keeping WQ_UNBOUND.\n", wq->name); + flags &= ~WQ_PERCPU; + } + if (flags & WQ_BH) { /* * BH workqueues always share a single execution context per CPU |
