Skip to content

Commit 017ea3f

Browse files
DispatchCodegregkh
authored andcommitted
workqueue: Add system_percpu_wq and system_dfl_wq
[ Upstream commit 128ea9f ] Currently, if a user enqueue a work item using schedule_delayed_work() the used wq is "system_wq" (per-cpu wq) while queue_delayed_work() use WORK_CPU_UNBOUND (used when a cpu is not specified). The same applies to schedule_work() that is using system_wq and queue_work(), that makes use again of WORK_CPU_UNBOUND. This lack of consistentcy cannot be addressed without refactoring the API. system_wq is a per-CPU worqueue, yet nothing in its name tells about that CPU affinity constraint, which is very often not required by users. Make it clear by adding a system_percpu_wq. system_unbound_wq should be the default workqueue so as not to enforce locality constraints for random work whenever it's not required. Adding system_dfl_wq to encourage its use when unbound work should be used. Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Signed-off-by: Tejun Heo <tj@kernel.org> Stable-dep-of: 50fd6dd ("tracing/user_events: Fix use-after-free in user_event_mm_dup()") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e0d8c1d commit 017ea3f

2 files changed

Lines changed: 15 additions & 7 deletions

File tree

include/linux/workqueue.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ enum {
410410
/*
411411
* System-wide workqueues which are always present.
412412
*
413-
* system_wq is the one used by schedule[_delayed]_work[_on]().
413+
* system_percpu_wq is the one used by schedule[_delayed]_work[_on]().
414414
* Multi-CPU multi-threaded. There are users which expect relatively
415415
* short queue flush time. Don't queue works which can run for too
416416
* long.
@@ -421,7 +421,7 @@ enum {
421421
* system_long_wq is similar to system_wq but may host long running
422422
* works. Queue flushing might take relatively long.
423423
*
424-
* system_unbound_wq is unbound workqueue. Workers are not bound to
424+
* system_dfl_wq is unbound workqueue. Workers are not bound to
425425
* any specific CPU, not concurrency managed, and all queued works are
426426
* executed immediately as long as max_active limit is not reached and
427427
* resources are available.
@@ -435,10 +435,12 @@ enum {
435435
* system_power_efficient_wq is identical to system_wq if
436436
* 'wq_power_efficient' is disabled. See WQ_POWER_EFFICIENT for more info.
437437
*/
438-
extern struct workqueue_struct *system_wq;
438+
extern struct workqueue_struct *system_wq; /* use system_percpu_wq, this will be removed */
439+
extern struct workqueue_struct *system_percpu_wq;
439440
extern struct workqueue_struct *system_highpri_wq;
440441
extern struct workqueue_struct *system_long_wq;
441442
extern struct workqueue_struct *system_unbound_wq;
443+
extern struct workqueue_struct *system_dfl_wq;
442444
extern struct workqueue_struct *system_freezable_wq;
443445
extern struct workqueue_struct *system_power_efficient_wq;
444446
extern struct workqueue_struct *system_freezable_power_efficient_wq;

kernel/workqueue.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,12 +425,16 @@ static struct kthread_worker *pwq_release_worker;
425425

426426
struct workqueue_struct *system_wq __read_mostly;
427427
EXPORT_SYMBOL(system_wq);
428+
struct workqueue_struct *system_percpu_wq __read_mostly;
429+
EXPORT_SYMBOL(system_percpu_wq);
428430
struct workqueue_struct *system_highpri_wq __read_mostly;
429431
EXPORT_SYMBOL_GPL(system_highpri_wq);
430432
struct workqueue_struct *system_long_wq __read_mostly;
431433
EXPORT_SYMBOL_GPL(system_long_wq);
432434
struct workqueue_struct *system_unbound_wq __read_mostly;
433435
EXPORT_SYMBOL_GPL(system_unbound_wq);
436+
struct workqueue_struct *system_dfl_wq __read_mostly;
437+
EXPORT_SYMBOL_GPL(system_dfl_wq);
434438
struct workqueue_struct *system_freezable_wq __read_mostly;
435439
EXPORT_SYMBOL_GPL(system_freezable_wq);
436440
struct workqueue_struct *system_power_efficient_wq __read_mostly;
@@ -6696,19 +6700,21 @@ void __init workqueue_init_early(void)
66966700
}
66976701

66986702
system_wq = alloc_workqueue("events", 0, 0);
6703+
system_percpu_wq = alloc_workqueue("events", 0, 0);
66996704
system_highpri_wq = alloc_workqueue("events_highpri", WQ_HIGHPRI, 0);
67006705
system_long_wq = alloc_workqueue("events_long", 0, 0);
6701-
system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
6702-
WQ_MAX_ACTIVE);
6706+
system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, WQ_MAX_ACTIVE);
6707+
system_dfl_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, WQ_MAX_ACTIVE);
67036708
system_freezable_wq = alloc_workqueue("events_freezable",
67046709
WQ_FREEZABLE, 0);
67056710
system_power_efficient_wq = alloc_workqueue("events_power_efficient",
67066711
WQ_POWER_EFFICIENT, 0);
67076712
system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient",
67086713
WQ_FREEZABLE | WQ_POWER_EFFICIENT,
67096714
0);
6710-
BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq ||
6711-
!system_unbound_wq || !system_freezable_wq ||
6715+
BUG_ON(!system_wq || !system_percpu_wq || !system_highpri_wq ||
6716+
!system_long_wq || !system_unbound_wq || !system_dfl_wq ||
6717+
!system_freezable_wq ||
67126718
!system_power_efficient_wq ||
67136719
!system_freezable_power_efficient_wq);
67146720
}

0 commit comments

Comments
 (0)