Skip to content

Commit 7ee681b

Browse files
KAGA-KOKOIngo Molnar
authored andcommitted
workqueue: Convert to state machine callbacks
Get rid of the prio ordering of the separate notifiers and use a proper state callback pair. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Anna-Maria Gleixner <[email protected]> Reviewed-by: Sebastian Andrzej Siewior <[email protected]> Acked-by: Tejun Heo <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Lai Jiangshan <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Nicolas Iooss <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rasmus Villemoes <[email protected]> Cc: Rusty Russell <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent c6a84da commit 7ee681b

File tree

5 files changed

+61
-74
lines changed

5 files changed

+61
-74
lines changed

include/linux/cpu.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,6 @@ extern ssize_t arch_cpu_release(const char *, size_t);
5555
#endif
5656
struct notifier_block;
5757

58-
/*
59-
* CPU notifier priorities.
60-
*/
61-
enum {
62-
/* bring up workqueues before normal notifiers and down after */
63-
CPU_PRI_WORKQUEUE_UP = 5,
64-
CPU_PRI_WORKQUEUE_DOWN = -5,
65-
};
66-
6758
#define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */
6859
#define CPU_UP_PREPARE 0x0003 /* CPU (unsigned)v coming up */
6960
#define CPU_UP_CANCELED 0x0004 /* CPU (unsigned)v NOT coming up */

include/linux/cpuhotplug.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ enum cpuhp_state {
1212
CPUHP_PERF_BFIN,
1313
CPUHP_PERF_POWER,
1414
CPUHP_PERF_SUPERH,
15+
CPUHP_WORKQUEUE_PREP,
1516
CPUHP_NOTIFY_PREPARE,
1617
CPUHP_BRINGUP_CPU,
1718
CPUHP_AP_IDLE_DEAD,
@@ -49,6 +50,7 @@ enum cpuhp_state {
4950
CPUHP_AP_PERF_S390_SF_ONLINE,
5051
CPUHP_AP_PERF_ARM_CCI_ONLINE,
5152
CPUHP_AP_PERF_ARM_CCN_ONLINE,
53+
CPUHP_AP_WORKQUEUE_ONLINE,
5254
CPUHP_AP_NOTIFY_ONLINE,
5355
CPUHP_AP_ONLINE_DYN,
5456
CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30,

include/linux/workqueue.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,4 +625,10 @@ void wq_watchdog_touch(int cpu);
625625
static inline void wq_watchdog_touch(int cpu) { }
626626
#endif /* CONFIG_WQ_WATCHDOG */
627627

628+
#ifdef CONFIG_SMP
629+
int workqueue_prepare_cpu(unsigned int cpu);
630+
int workqueue_online_cpu(unsigned int cpu);
631+
int workqueue_offline_cpu(unsigned int cpu);
632+
#endif
633+
628634
#endif

kernel/cpu.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
11851185
.startup = perf_event_init_cpu,
11861186
.teardown = perf_event_exit_cpu,
11871187
},
1188+
[CPUHP_WORKQUEUE_PREP] = {
1189+
.name = "workqueue prepare",
1190+
.startup = workqueue_prepare_cpu,
1191+
.teardown = NULL,
1192+
},
11881193
/*
11891194
* Preparatory and dead notifiers. Will be replaced once the notifiers
11901195
* are converted to states.
@@ -1267,6 +1272,11 @@ static struct cpuhp_step cpuhp_ap_states[] = {
12671272
.startup = perf_event_init_cpu,
12681273
.teardown = perf_event_exit_cpu,
12691274
},
1275+
[CPUHP_AP_WORKQUEUE_ONLINE] = {
1276+
.name = "workqueue online",
1277+
.startup = workqueue_online_cpu,
1278+
.teardown = workqueue_offline_cpu,
1279+
},
12701280

12711281
/*
12721282
* Online/down_prepare notifiers. Will be removed once the notifiers

kernel/workqueue.c

Lines changed: 43 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4611,84 +4611,65 @@ static void restore_unbound_workers_cpumask(struct worker_pool *pool, int cpu)
46114611
pool->attrs->cpumask) < 0);
46124612
}
46134613

4614-
/*
4615-
* Workqueues should be brought up before normal priority CPU notifiers.
4616-
* This will be registered high priority CPU notifier.
4617-
*/
4618-
static int workqueue_cpu_up_callback(struct notifier_block *nfb,
4619-
unsigned long action,
4620-
void *hcpu)
4614+
int workqueue_prepare_cpu(unsigned int cpu)
4615+
{
4616+
struct worker_pool *pool;
4617+
4618+
for_each_cpu_worker_pool(pool, cpu) {
4619+
if (pool->nr_workers)
4620+
continue;
4621+
if (!create_worker(pool))
4622+
return -ENOMEM;
4623+
}
4624+
return 0;
4625+
}
4626+
4627+
int workqueue_online_cpu(unsigned int cpu)
46214628
{
4622-
int cpu = (unsigned long)hcpu;
46234629
struct worker_pool *pool;
46244630
struct workqueue_struct *wq;
46254631
int pi;
46264632

4627-
switch (action & ~CPU_TASKS_FROZEN) {
4628-
case CPU_UP_PREPARE:
4629-
for_each_cpu_worker_pool(pool, cpu) {
4630-
if (pool->nr_workers)
4631-
continue;
4632-
if (!create_worker(pool))
4633-
return NOTIFY_BAD;
4634-
}
4635-
break;
4636-
4637-
case CPU_DOWN_FAILED:
4638-
case CPU_ONLINE:
4639-
mutex_lock(&wq_pool_mutex);
4633+
mutex_lock(&wq_pool_mutex);
46404634

4641-
for_each_pool(pool, pi) {
4642-
mutex_lock(&pool->attach_mutex);
4635+
for_each_pool(pool, pi) {
4636+
mutex_lock(&pool->attach_mutex);
46434637

4644-
if (pool->cpu == cpu)
4645-
rebind_workers(pool);
4646-
else if (pool->cpu < 0)
4647-
restore_unbound_workers_cpumask(pool, cpu);
4638+
if (pool->cpu == cpu)
4639+
rebind_workers(pool);
4640+
else if (pool->cpu < 0)
4641+
restore_unbound_workers_cpumask(pool, cpu);
46484642

4649-
mutex_unlock(&pool->attach_mutex);
4650-
}
4643+
mutex_unlock(&pool->attach_mutex);
4644+
}
46514645

4652-
/* update NUMA affinity of unbound workqueues */
4653-
list_for_each_entry(wq, &workqueues, list)
4654-
wq_update_unbound_numa(wq, cpu, true);
4646+
/* update NUMA affinity of unbound workqueues */
4647+
list_for_each_entry(wq, &workqueues, list)
4648+
wq_update_unbound_numa(wq, cpu, true);
46554649

4656-
mutex_unlock(&wq_pool_mutex);
4657-
break;
4658-
}
4659-
return NOTIFY_OK;
4650+
mutex_unlock(&wq_pool_mutex);
4651+
return 0;
46604652
}
46614653

4662-
/*
4663-
* Workqueues should be brought down after normal priority CPU notifiers.
4664-
* This will be registered as low priority CPU notifier.
4665-
*/
4666-
static int workqueue_cpu_down_callback(struct notifier_block *nfb,
4667-
unsigned long action,
4668-
void *hcpu)
4654+
int workqueue_offline_cpu(unsigned int cpu)
46694655
{
4670-
int cpu = (unsigned long)hcpu;
46714656
struct work_struct unbind_work;
46724657
struct workqueue_struct *wq;
46734658

4674-
switch (action & ~CPU_TASKS_FROZEN) {
4675-
case CPU_DOWN_PREPARE:
4676-
/* unbinding per-cpu workers should happen on the local CPU */
4677-
INIT_WORK_ONSTACK(&unbind_work, wq_unbind_fn);
4678-
queue_work_on(cpu, system_highpri_wq, &unbind_work);
4679-
4680-
/* update NUMA affinity of unbound workqueues */
4681-
mutex_lock(&wq_pool_mutex);
4682-
list_for_each_entry(wq, &workqueues, list)
4683-
wq_update_unbound_numa(wq, cpu, false);
4684-
mutex_unlock(&wq_pool_mutex);
4685-
4686-
/* wait for per-cpu unbinding to finish */
4687-
flush_work(&unbind_work);
4688-
destroy_work_on_stack(&unbind_work);
4689-
break;
4690-
}
4691-
return NOTIFY_OK;
4659+
/* unbinding per-cpu workers should happen on the local CPU */
4660+
INIT_WORK_ONSTACK(&unbind_work, wq_unbind_fn);
4661+
queue_work_on(cpu, system_highpri_wq, &unbind_work);
4662+
4663+
/* update NUMA affinity of unbound workqueues */
4664+
mutex_lock(&wq_pool_mutex);
4665+
list_for_each_entry(wq, &workqueues, list)
4666+
wq_update_unbound_numa(wq, cpu, false);
4667+
mutex_unlock(&wq_pool_mutex);
4668+
4669+
/* wait for per-cpu unbinding to finish */
4670+
flush_work(&unbind_work);
4671+
destroy_work_on_stack(&unbind_work);
4672+
return 0;
46924673
}
46934674

46944675
#ifdef CONFIG_SMP
@@ -5490,9 +5471,6 @@ static int __init init_workqueues(void)
54905471

54915472
pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
54925473

5493-
cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP);
5494-
hotcpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN);
5495-
54965474
wq_numa_init();
54975475

54985476
/* initialize CPU pools */

0 commit comments

Comments
 (0)