cpu/hotplug: Replace anon union
Some compilers are unhappy with the anon union in the state array. Replace
it with a named union.
While at it align the state array initializers proper and add the missing
name tags.
Fixes: cf392d10b6
"cpu/hotplug: Add multi instance support"
Reported-by: Ingo Molnar <mingo@kernel.org>
Reported-by: Fenguang Wu <fengguang.wu@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: rt@linutronix.de
This commit is contained in:
parent
01b4115906
commit
3c1627e999
145
kernel/cpu.c
145
kernel/cpu.c
|
@ -73,15 +73,15 @@ static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state);
|
||||||
struct cpuhp_step {
|
struct cpuhp_step {
|
||||||
const char *name;
|
const char *name;
|
||||||
union {
|
union {
|
||||||
int (*startup)(unsigned int cpu);
|
int (*single)(unsigned int cpu);
|
||||||
int (*startup_multi)(unsigned int cpu,
|
int (*multi)(unsigned int cpu,
|
||||||
struct hlist_node *node);
|
struct hlist_node *node);
|
||||||
};
|
} startup;
|
||||||
union {
|
union {
|
||||||
int (*teardown)(unsigned int cpu);
|
int (*single)(unsigned int cpu);
|
||||||
int (*teardown_multi)(unsigned int cpu,
|
int (*multi)(unsigned int cpu,
|
||||||
struct hlist_node *node);
|
struct hlist_node *node);
|
||||||
};
|
} teardown;
|
||||||
struct hlist_head list;
|
struct hlist_head list;
|
||||||
bool skip_onerr;
|
bool skip_onerr;
|
||||||
bool cant_stop;
|
bool cant_stop;
|
||||||
|
@ -127,7 +127,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
|
||||||
int ret, cnt;
|
int ret, cnt;
|
||||||
|
|
||||||
if (!step->multi_instance) {
|
if (!step->multi_instance) {
|
||||||
cb = bringup ? step->startup : step->teardown;
|
cb = bringup ? step->startup.single : step->teardown.single;
|
||||||
if (!cb)
|
if (!cb)
|
||||||
return 0;
|
return 0;
|
||||||
trace_cpuhp_enter(cpu, st->target, state, cb);
|
trace_cpuhp_enter(cpu, st->target, state, cb);
|
||||||
|
@ -135,7 +135,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
|
||||||
trace_cpuhp_exit(cpu, st->state, state, ret);
|
trace_cpuhp_exit(cpu, st->state, state, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cbm = bringup ? step->startup_multi : step->teardown_multi;
|
cbm = bringup ? step->startup.multi : step->teardown.multi;
|
||||||
if (!cbm)
|
if (!cbm)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
/* Rollback the instances if one failed */
|
/* Rollback the instances if one failed */
|
||||||
cbm = !bringup ? step->startup_multi : step->teardown_multi;
|
cbm = !bringup ? step->startup.multi : step->teardown.multi;
|
||||||
if (!cbm)
|
if (!cbm)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1256,40 +1256,40 @@ core_initcall(cpu_hotplug_pm_sync_init);
|
||||||
static struct cpuhp_step cpuhp_bp_states[] = {
|
static struct cpuhp_step cpuhp_bp_states[] = {
|
||||||
[CPUHP_OFFLINE] = {
|
[CPUHP_OFFLINE] = {
|
||||||
.name = "offline",
|
.name = "offline",
|
||||||
.startup = NULL,
|
.startup.single = NULL,
|
||||||
.teardown = NULL,
|
.teardown.single = NULL,
|
||||||
},
|
},
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
[CPUHP_CREATE_THREADS]= {
|
[CPUHP_CREATE_THREADS]= {
|
||||||
.name = "threads:create",
|
.name = "threads:create",
|
||||||
.startup = smpboot_create_threads,
|
.startup.single = smpboot_create_threads,
|
||||||
.teardown = NULL,
|
.teardown.single = NULL,
|
||||||
.cant_stop = true,
|
.cant_stop = true,
|
||||||
},
|
},
|
||||||
[CPUHP_PERF_PREPARE] = {
|
[CPUHP_PERF_PREPARE] = {
|
||||||
.name = "perf prepare",
|
.name = "perf:prepare",
|
||||||
.startup = perf_event_init_cpu,
|
.startup.single = perf_event_init_cpu,
|
||||||
.teardown = perf_event_exit_cpu,
|
.teardown.single = perf_event_exit_cpu,
|
||||||
},
|
},
|
||||||
[CPUHP_WORKQUEUE_PREP] = {
|
[CPUHP_WORKQUEUE_PREP] = {
|
||||||
.name = "workqueue prepare",
|
.name = "workqueue:prepare",
|
||||||
.startup = workqueue_prepare_cpu,
|
.startup.single = workqueue_prepare_cpu,
|
||||||
.teardown = NULL,
|
.teardown.single = NULL,
|
||||||
},
|
},
|
||||||
[CPUHP_HRTIMERS_PREPARE] = {
|
[CPUHP_HRTIMERS_PREPARE] = {
|
||||||
.name = "hrtimers prepare",
|
.name = "hrtimers:prepare",
|
||||||
.startup = hrtimers_prepare_cpu,
|
.startup.single = hrtimers_prepare_cpu,
|
||||||
.teardown = hrtimers_dead_cpu,
|
.teardown.single = hrtimers_dead_cpu,
|
||||||
},
|
},
|
||||||
[CPUHP_SMPCFD_PREPARE] = {
|
[CPUHP_SMPCFD_PREPARE] = {
|
||||||
.name = "SMPCFD prepare",
|
.name = "SMPCFD:prepare",
|
||||||
.startup = smpcfd_prepare_cpu,
|
.startup.single = smpcfd_prepare_cpu,
|
||||||
.teardown = smpcfd_dead_cpu,
|
.teardown.single = smpcfd_dead_cpu,
|
||||||
},
|
},
|
||||||
[CPUHP_RCUTREE_PREP] = {
|
[CPUHP_RCUTREE_PREP] = {
|
||||||
.name = "RCU-tree prepare",
|
.name = "RCU-tree:prepare",
|
||||||
.startup = rcutree_prepare_cpu,
|
.startup.single = rcutree_prepare_cpu,
|
||||||
.teardown = rcutree_dead_cpu,
|
.teardown.single = rcutree_dead_cpu,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* Preparatory and dead notifiers. Will be replaced once the notifiers
|
* Preparatory and dead notifiers. Will be replaced once the notifiers
|
||||||
|
@ -1297,8 +1297,8 @@ static struct cpuhp_step cpuhp_bp_states[] = {
|
||||||
*/
|
*/
|
||||||
[CPUHP_NOTIFY_PREPARE] = {
|
[CPUHP_NOTIFY_PREPARE] = {
|
||||||
.name = "notify:prepare",
|
.name = "notify:prepare",
|
||||||
.startup = notify_prepare,
|
.startup.single = notify_prepare,
|
||||||
.teardown = notify_dead,
|
.teardown.single = notify_dead,
|
||||||
.skip_onerr = true,
|
.skip_onerr = true,
|
||||||
.cant_stop = true,
|
.cant_stop = true,
|
||||||
},
|
},
|
||||||
|
@ -1308,20 +1308,21 @@ static struct cpuhp_step cpuhp_bp_states[] = {
|
||||||
* otherwise a RCU stall occurs.
|
* otherwise a RCU stall occurs.
|
||||||
*/
|
*/
|
||||||
[CPUHP_TIMERS_DEAD] = {
|
[CPUHP_TIMERS_DEAD] = {
|
||||||
.name = "timers dead",
|
.name = "timers:dead",
|
||||||
.startup = NULL,
|
.startup.single = NULL,
|
||||||
.teardown = timers_dead_cpu,
|
.teardown.single = timers_dead_cpu,
|
||||||
},
|
},
|
||||||
/* Kicks the plugged cpu into life */
|
/* Kicks the plugged cpu into life */
|
||||||
[CPUHP_BRINGUP_CPU] = {
|
[CPUHP_BRINGUP_CPU] = {
|
||||||
.name = "cpu:bringup",
|
.name = "cpu:bringup",
|
||||||
.startup = bringup_cpu,
|
.startup.single = bringup_cpu,
|
||||||
.teardown = NULL,
|
.teardown.single = NULL,
|
||||||
.cant_stop = true,
|
.cant_stop = true,
|
||||||
},
|
},
|
||||||
[CPUHP_AP_SMPCFD_DYING] = {
|
[CPUHP_AP_SMPCFD_DYING] = {
|
||||||
.startup = NULL,
|
.name = "SMPCFD:dying",
|
||||||
.teardown = smpcfd_dying_cpu,
|
.startup.single = NULL,
|
||||||
|
.teardown.single = smpcfd_dying_cpu,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* Handled on controll processor until the plugged processor manages
|
* Handled on controll processor until the plugged processor manages
|
||||||
|
@ -1329,8 +1330,8 @@ static struct cpuhp_step cpuhp_bp_states[] = {
|
||||||
*/
|
*/
|
||||||
[CPUHP_TEARDOWN_CPU] = {
|
[CPUHP_TEARDOWN_CPU] = {
|
||||||
.name = "cpu:teardown",
|
.name = "cpu:teardown",
|
||||||
.startup = NULL,
|
.startup.single = NULL,
|
||||||
.teardown = takedown_cpu,
|
.teardown.single = takedown_cpu,
|
||||||
.cant_stop = true,
|
.cant_stop = true,
|
||||||
},
|
},
|
||||||
#else
|
#else
|
||||||
|
@ -1356,22 +1357,23 @@ static struct cpuhp_step cpuhp_ap_states[] = {
|
||||||
/* First state is scheduler control. Interrupts are disabled */
|
/* First state is scheduler control. Interrupts are disabled */
|
||||||
[CPUHP_AP_SCHED_STARTING] = {
|
[CPUHP_AP_SCHED_STARTING] = {
|
||||||
.name = "sched:starting",
|
.name = "sched:starting",
|
||||||
.startup = sched_cpu_starting,
|
.startup.single = sched_cpu_starting,
|
||||||
.teardown = sched_cpu_dying,
|
.teardown.single = sched_cpu_dying,
|
||||||
},
|
},
|
||||||
[CPUHP_AP_RCUTREE_DYING] = {
|
[CPUHP_AP_RCUTREE_DYING] = {
|
||||||
.startup = NULL,
|
.name = "RCU-tree:dying",
|
||||||
.teardown = rcutree_dying_cpu,
|
.startup.single = NULL,
|
||||||
|
.teardown.single = rcutree_dying_cpu,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* Low level startup/teardown notifiers. Run with interrupts
|
* Low level startup.single/teardown notifiers. Run with interrupts
|
||||||
* disabled. Will be removed once the notifiers are converted to
|
* disabled. Will be removed once the notifiers are converted to
|
||||||
* states.
|
* states.
|
||||||
*/
|
*/
|
||||||
[CPUHP_AP_NOTIFY_STARTING] = {
|
[CPUHP_AP_NOTIFY_STARTING] = {
|
||||||
.name = "notify:starting",
|
.name = "notify:starting",
|
||||||
.startup = notify_starting,
|
.startup.single = notify_starting,
|
||||||
.teardown = notify_dying,
|
.teardown.single = notify_dying,
|
||||||
.skip_onerr = true,
|
.skip_onerr = true,
|
||||||
.cant_stop = true,
|
.cant_stop = true,
|
||||||
},
|
},
|
||||||
|
@ -1383,23 +1385,23 @@ static struct cpuhp_step cpuhp_ap_states[] = {
|
||||||
/* Handle smpboot threads park/unpark */
|
/* Handle smpboot threads park/unpark */
|
||||||
[CPUHP_AP_SMPBOOT_THREADS] = {
|
[CPUHP_AP_SMPBOOT_THREADS] = {
|
||||||
.name = "smpboot:threads",
|
.name = "smpboot:threads",
|
||||||
.startup = smpboot_unpark_threads,
|
.startup.single = smpboot_unpark_threads,
|
||||||
.teardown = NULL,
|
.teardown.single = NULL,
|
||||||
},
|
},
|
||||||
[CPUHP_AP_PERF_ONLINE] = {
|
[CPUHP_AP_PERF_ONLINE] = {
|
||||||
.name = "perf online",
|
.name = "perf:online",
|
||||||
.startup = perf_event_init_cpu,
|
.startup.single = perf_event_init_cpu,
|
||||||
.teardown = perf_event_exit_cpu,
|
.teardown.single = perf_event_exit_cpu,
|
||||||
},
|
},
|
||||||
[CPUHP_AP_WORKQUEUE_ONLINE] = {
|
[CPUHP_AP_WORKQUEUE_ONLINE] = {
|
||||||
.name = "workqueue online",
|
.name = "workqueue:online",
|
||||||
.startup = workqueue_online_cpu,
|
.startup.single = workqueue_online_cpu,
|
||||||
.teardown = workqueue_offline_cpu,
|
.teardown.single = workqueue_offline_cpu,
|
||||||
},
|
},
|
||||||
[CPUHP_AP_RCUTREE_ONLINE] = {
|
[CPUHP_AP_RCUTREE_ONLINE] = {
|
||||||
.name = "RCU-tree online",
|
.name = "RCU-tree:online",
|
||||||
.startup = rcutree_online_cpu,
|
.startup.single = rcutree_online_cpu,
|
||||||
.teardown = rcutree_offline_cpu,
|
.teardown.single = rcutree_offline_cpu,
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1408,8 +1410,8 @@ static struct cpuhp_step cpuhp_ap_states[] = {
|
||||||
*/
|
*/
|
||||||
[CPUHP_AP_NOTIFY_ONLINE] = {
|
[CPUHP_AP_NOTIFY_ONLINE] = {
|
||||||
.name = "notify:online",
|
.name = "notify:online",
|
||||||
.startup = notify_online,
|
.startup.single = notify_online,
|
||||||
.teardown = notify_down_prepare,
|
.teardown.single = notify_down_prepare,
|
||||||
.skip_onerr = true,
|
.skip_onerr = true,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
@ -1421,16 +1423,16 @@ static struct cpuhp_step cpuhp_ap_states[] = {
|
||||||
/* Last state is scheduler control setting the cpu active */
|
/* Last state is scheduler control setting the cpu active */
|
||||||
[CPUHP_AP_ACTIVE] = {
|
[CPUHP_AP_ACTIVE] = {
|
||||||
.name = "sched:active",
|
.name = "sched:active",
|
||||||
.startup = sched_cpu_activate,
|
.startup.single = sched_cpu_activate,
|
||||||
.teardown = sched_cpu_deactivate,
|
.teardown.single = sched_cpu_deactivate,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* CPU is fully up and running. */
|
/* CPU is fully up and running. */
|
||||||
[CPUHP_ONLINE] = {
|
[CPUHP_ONLINE] = {
|
||||||
.name = "online",
|
.name = "online",
|
||||||
.startup = NULL,
|
.startup.single = NULL,
|
||||||
.teardown = NULL,
|
.teardown.single = NULL,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1453,8 +1455,8 @@ static void cpuhp_store_callbacks(enum cpuhp_state state,
|
||||||
|
|
||||||
mutex_lock(&cpuhp_state_mutex);
|
mutex_lock(&cpuhp_state_mutex);
|
||||||
sp = cpuhp_get_step(state);
|
sp = cpuhp_get_step(state);
|
||||||
sp->startup = startup;
|
sp->startup.single = startup;
|
||||||
sp->teardown = teardown;
|
sp->teardown.single = teardown;
|
||||||
sp->name = name;
|
sp->name = name;
|
||||||
sp->multi_instance = multi_instance;
|
sp->multi_instance = multi_instance;
|
||||||
INIT_HLIST_HEAD(&sp->list);
|
INIT_HLIST_HEAD(&sp->list);
|
||||||
|
@ -1463,7 +1465,7 @@ static void cpuhp_store_callbacks(enum cpuhp_state state,
|
||||||
|
|
||||||
static void *cpuhp_get_teardown_cb(enum cpuhp_state state)
|
static void *cpuhp_get_teardown_cb(enum cpuhp_state state)
|
||||||
{
|
{
|
||||||
return cpuhp_get_step(state)->teardown;
|
return cpuhp_get_step(state)->teardown.single;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1476,7 +1478,8 @@ static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup,
|
||||||
struct cpuhp_step *sp = cpuhp_get_step(state);
|
struct cpuhp_step *sp = cpuhp_get_step(state);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((bringup && !sp->startup) || (!bringup && !sp->teardown))
|
if ((bringup && !sp->startup.single) ||
|
||||||
|
(!bringup && !sp->teardown.single))
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
* The non AP bound callbacks can fail on bringup. On teardown
|
* The non AP bound callbacks can fail on bringup. On teardown
|
||||||
|
@ -1554,7 +1557,7 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
|
||||||
|
|
||||||
get_online_cpus();
|
get_online_cpus();
|
||||||
|
|
||||||
if (!invoke || !sp->startup_multi)
|
if (!invoke || !sp->startup.multi)
|
||||||
goto add_node;
|
goto add_node;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1570,7 +1573,7 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
|
||||||
|
|
||||||
ret = cpuhp_issue_call(cpu, state, true, node);
|
ret = cpuhp_issue_call(cpu, state, true, node);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (sp->teardown_multi)
|
if (sp->teardown.multi)
|
||||||
cpuhp_rollback_install(cpu, state, node);
|
cpuhp_rollback_install(cpu, state, node);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue