+16
-9
kernel/cpu.c
+16
-9
kernel/cpu.c
···
249
249
return ret;
250
250
}
251
251
252
+
/*
253
+
* The former STARTING/DYING states, ran with IRQs disabled and must not fail.
254
+
*/
255
+
static bool cpuhp_is_atomic_state(enum cpuhp_state state)
256
+
{
257
+
return CPUHP_AP_IDLE_DEAD <= state && state < CPUHP_AP_ONLINE;
258
+
}
259
+
252
260
#ifdef CONFIG_SMP
253
261
static bool cpuhp_is_ap_state(enum cpuhp_state state)
254
262
{
···
277
269
{
278
270
struct completion *done = bringup ? &st->done_up : &st->done_down;
279
271
complete(done);
280
-
}
281
-
282
-
/*
283
-
* The former STARTING/DYING states, ran with IRQs disabled and must not fail.
284
-
*/
285
-
static bool cpuhp_is_atomic_state(enum cpuhp_state state)
286
-
{
287
-
return CPUHP_AP_IDLE_DEAD <= state && state < CPUHP_AP_ONLINE;
288
272
}
289
273
290
274
/* Synchronization state management */
···
2364
2364
else
2365
2365
ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL);
2366
2366
#else
2367
-
ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL);
2367
+
if (cpuhp_is_atomic_state(state)) {
2368
+
guard(irqsave)();
2369
+
ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL);
2370
+
/* STARTING/DYING must not fail! */
2371
+
WARN_ON_ONCE(ret);
2372
+
} else {
2373
+
ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL);
2374
+
}
2368
2375
#endif
2369
2376
BUG_ON(ret && !bringup);
2370
2377
return ret;