Skip to content

Commit 08403e2

Browse files
committed
Merge tag 'smp-core-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull SMP core updates from Thomas Gleixner: - Replace get/put_online_cpus() in various places. The final removal will happen shortly before v5.15-rc1 when the rest of the patches have been merged. - Add debug code to help the analysis of CPU hotplug failures - A set of kernel doc updates * tag 'smp-core-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: mm: Replace deprecated CPU-hotplug functions. md/raid5: Replace deprecated CPU-hotplug functions. Documentation: Replace deprecated CPU-hotplug functions. smp: Fix all kernel-doc warnings cpu/hotplug: Add debug printks for hotplug callback failures cpu/hotplug: Use DEVICE_ATTR_*() macro cpu/hotplug: Eliminate all kernel-doc warnings cpu/hotplug: Fix kernel doc warnings for __cpuhp_setup_state_cpuslocked() cpu/hotplug: Fix comment typo smpboot: Replace deprecated CPU-hotplug functions.
2 parents e4c3562 + 7625ecc commit 08403e2

File tree

9 files changed

+80
-52
lines changed

9 files changed

+80
-52
lines changed

Documentation/core-api/cpu_hotplug.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ goes online (offline) and during initial setup (shutdown) of the driver. However
220220
each registration and removal function is also available with a ``_nocalls``
221221
suffix which does not invoke the provided callbacks if the invocation of the
222222
callbacks is not desired. During the manual setup (or teardown) the functions
223-
``get_online_cpus()`` and ``put_online_cpus()`` should be used to inhibit CPU
223+
``cpus_read_lock()`` and ``cpus_read_unlock()`` should be used to inhibit CPU
224224
hotplug operations.
225225

226226

Documentation/trace/ftrace.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2762,7 +2762,7 @@ listed in:
27622762
put_prev_task_idle
27632763
kmem_cache_create
27642764
pick_next_task_rt
2765-
get_online_cpus
2765+
cpus_read_lock
27662766
pick_next_task_fair
27672767
mutex_lock
27682768
[...]

drivers/md/raid5.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2437,7 +2437,7 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
24372437
conf->scribble_sectors >= new_sectors)
24382438
return 0;
24392439
mddev_suspend(conf->mddev);
2440-
get_online_cpus();
2440+
cpus_read_lock();
24412441

24422442
for_each_present_cpu(cpu) {
24432443
struct raid5_percpu *percpu;
@@ -2449,7 +2449,7 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
24492449
break;
24502450
}
24512451

2452-
put_online_cpus();
2452+
cpus_read_unlock();
24532453
mddev_resume(conf->mddev);
24542454
if (!err) {
24552455
conf->scribble_disks = new_disks;

include/linux/cpuhotplug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ static inline int cpuhp_state_remove_instance(enum cpuhp_state state,
399399

400400
/**
401401
* cpuhp_state_remove_instance_nocalls - Remove hotplug instance from state
402-
* without invoking the reatdown callback
402+
* without invoking the teardown callback
403403
* @state: The state from which the instance is removed
404404
* @node: The node for this individual state.
405405
*

kernel/cpu.c

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,19 @@
4141
#include "smpboot.h"
4242

4343
/**
44-
* cpuhp_cpu_state - Per cpu hotplug state storage
44+
* struct cpuhp_cpu_state - Per cpu hotplug state storage
4545
* @state: The current cpu state
4646
* @target: The target state
47+
* @fail: Current CPU hotplug callback state
4748
* @thread: Pointer to the hotplug thread
4849
* @should_run: Thread should execute
4950
* @rollback: Perform a rollback
5051
* @single: Single callback invocation
5152
* @bringup: Single callback bringup or teardown selector
53+
* @cpu: CPU number
54+
* @node: Remote CPU node; for multi-instance, do a
55+
* single entry callback for install/remove
56+
* @last: For multi-instance rollback, remember how far we got
5257
* @cb_state: The state for a single callback (install/uninstall)
5358
* @result: Result of the operation
5459
* @done_up: Signal completion to the issuer of the task for cpu-up
@@ -106,11 +111,12 @@ static inline void cpuhp_lock_release(bool bringup) { }
106111
#endif
107112

108113
/**
109-
* cpuhp_step - Hotplug state machine step
114+
* struct cpuhp_step - Hotplug state machine step
110115
* @name: Name of the step
111116
* @startup: Startup function of the step
112117
* @teardown: Teardown function of the step
113118
* @cant_stop: Bringup/teardown can't be stopped at this step
119+
* @multi_instance: State has multiple instances which get added afterwards
114120
*/
115121
struct cpuhp_step {
116122
const char *name;
@@ -124,7 +130,9 @@ struct cpuhp_step {
124130
int (*multi)(unsigned int cpu,
125131
struct hlist_node *node);
126132
} teardown;
133+
/* private: */
127134
struct hlist_head list;
135+
/* public: */
128136
bool cant_stop;
129137
bool multi_instance;
130138
};
@@ -143,14 +151,16 @@ static bool cpuhp_step_empty(bool bringup, struct cpuhp_step *step)
143151
}
144152

145153
/**
146-
* cpuhp_invoke_callback _ Invoke the callbacks for a given state
154+
* cpuhp_invoke_callback - Invoke the callbacks for a given state
147155
* @cpu: The cpu for which the callback should be invoked
148156
* @state: The state to do callbacks for
149157
* @bringup: True if the bringup callback should be invoked
150158
* @node: For multi-instance, do a single entry callback for install/remove
151159
* @lastp: For multi-instance rollback, remember how far we got
152160
*
153161
* Called from cpu hotplug and from the state register machinery.
162+
*
163+
* Return: %0 on success or a negative errno code
154164
*/
155165
static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
156166
bool bringup, struct hlist_node *node,
@@ -682,6 +692,10 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
682692

683693
ret = cpuhp_invoke_callback_range(true, cpu, st, target);
684694
if (ret) {
695+
pr_debug("CPU UP failed (%d) CPU %u state %s (%d)\n",
696+
ret, cpu, cpuhp_get_step(st->state)->name,
697+
st->state);
698+
685699
cpuhp_reset_state(st, prev_state);
686700
if (can_rollback_cpu(st))
687701
WARN_ON(cpuhp_invoke_callback_range(false, cpu, st,
@@ -1081,6 +1095,9 @@ static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
10811095

10821096
ret = cpuhp_invoke_callback_range(false, cpu, st, target);
10831097
if (ret) {
1098+
pr_debug("CPU DOWN failed (%d) CPU %u state %s (%d)\n",
1099+
ret, cpu, cpuhp_get_step(st->state)->name,
1100+
st->state);
10841101

10851102
cpuhp_reset_state(st, prev_state);
10861103

@@ -1183,6 +1200,8 @@ static int cpu_down(unsigned int cpu, enum cpuhp_state target)
11831200
* This function is meant to be used by device core cpu subsystem only.
11841201
*
11851202
* Other subsystems should use remove_cpu() instead.
1203+
*
1204+
* Return: %0 on success or a negative errno code
11861205
*/
11871206
int cpu_device_down(struct device *dev)
11881207
{
@@ -1395,6 +1414,8 @@ static int cpu_up(unsigned int cpu, enum cpuhp_state target)
13951414
* This function is meant to be used by device core cpu subsystem only.
13961415
*
13971416
* Other subsystems should use add_cpu() instead.
1417+
*
1418+
* Return: %0 on success or a negative errno code
13981419
*/
13991420
int cpu_device_up(struct device *dev)
14001421
{
@@ -1420,6 +1441,8 @@ EXPORT_SYMBOL_GPL(add_cpu);
14201441
* On some architectures like arm64, we can hibernate on any CPU, but on
14211442
* wake up the CPU we hibernated on might be offline as a side effect of
14221443
* using maxcpus= for example.
1444+
*
1445+
* Return: %0 on success or a negative errno code
14231446
*/
14241447
int bringup_hibernate_cpu(unsigned int sleep_cpu)
14251448
{
@@ -1976,6 +1999,7 @@ EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance);
19761999
/**
19772000
* __cpuhp_setup_state_cpuslocked - Setup the callbacks for an hotplug machine state
19782001
* @state: The state to setup
2002+
* @name: Name of the step
19792003
* @invoke: If true, the startup function is invoked for cpus where
19802004
* cpu state >= @state
19812005
* @startup: startup callback function
@@ -1984,9 +2008,9 @@ EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance);
19842008
* added afterwards.
19852009
*
19862010
* The caller needs to hold cpus read locked while calling this function.
1987-
* Returns:
2011+
* Return:
19882012
* On success:
1989-
* Positive state number if @state is CPUHP_AP_ONLINE_DYN
2013+
* Positive state number if @state is CPUHP_AP_ONLINE_DYN;
19902014
* 0 for all other states
19912015
* On failure: proper (negative) error code
19922016
*/
@@ -2232,18 +2256,17 @@ int cpuhp_smt_enable(void)
22322256
#endif
22332257

22342258
#if defined(CONFIG_SYSFS) && defined(CONFIG_HOTPLUG_CPU)
2235-
static ssize_t show_cpuhp_state(struct device *dev,
2236-
struct device_attribute *attr, char *buf)
2259+
static ssize_t state_show(struct device *dev,
2260+
struct device_attribute *attr, char *buf)
22372261
{
22382262
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
22392263

22402264
return sprintf(buf, "%d\n", st->state);
22412265
}
2242-
static DEVICE_ATTR(state, 0444, show_cpuhp_state, NULL);
2266+
static DEVICE_ATTR_RO(state);
22432267

2244-
static ssize_t write_cpuhp_target(struct device *dev,
2245-
struct device_attribute *attr,
2246-
const char *buf, size_t count)
2268+
static ssize_t target_store(struct device *dev, struct device_attribute *attr,
2269+
const char *buf, size_t count)
22472270
{
22482271
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
22492272
struct cpuhp_step *sp;
@@ -2281,19 +2304,17 @@ static ssize_t write_cpuhp_target(struct device *dev,
22812304
return ret ? ret : count;
22822305
}
22832306

2284-
static ssize_t show_cpuhp_target(struct device *dev,
2285-
struct device_attribute *attr, char *buf)
2307+
static ssize_t target_show(struct device *dev,
2308+
struct device_attribute *attr, char *buf)
22862309
{
22872310
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
22882311

22892312
return sprintf(buf, "%d\n", st->target);
22902313
}
2291-
static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target);
2292-
2314+
static DEVICE_ATTR_RW(target);
22932315

2294-
static ssize_t write_cpuhp_fail(struct device *dev,
2295-
struct device_attribute *attr,
2296-
const char *buf, size_t count)
2316+
static ssize_t fail_store(struct device *dev, struct device_attribute *attr,
2317+
const char *buf, size_t count)
22972318
{
22982319
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
22992320
struct cpuhp_step *sp;
@@ -2342,15 +2363,15 @@ static ssize_t write_cpuhp_fail(struct device *dev,
23422363
return count;
23432364
}
23442365

2345-
static ssize_t show_cpuhp_fail(struct device *dev,
2346-
struct device_attribute *attr, char *buf)
2366+
static ssize_t fail_show(struct device *dev,
2367+
struct device_attribute *attr, char *buf)
23472368
{
23482369
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
23492370

23502371
return sprintf(buf, "%d\n", st->fail);
23512372
}
23522373

2353-
static DEVICE_ATTR(fail, 0644, show_cpuhp_fail, write_cpuhp_fail);
2374+
static DEVICE_ATTR_RW(fail);
23542375

23552376
static struct attribute *cpuhp_cpu_attrs[] = {
23562377
&dev_attr_state.attr,
@@ -2365,7 +2386,7 @@ static const struct attribute_group cpuhp_cpu_attr_group = {
23652386
NULL
23662387
};
23672388

2368-
static ssize_t show_cpuhp_states(struct device *dev,
2389+
static ssize_t states_show(struct device *dev,
23692390
struct device_attribute *attr, char *buf)
23702391
{
23712392
ssize_t cur, res = 0;
@@ -2384,7 +2405,7 @@ static ssize_t show_cpuhp_states(struct device *dev,
23842405
mutex_unlock(&cpuhp_state_mutex);
23852406
return res;
23862407
}
2387-
static DEVICE_ATTR(states, 0444, show_cpuhp_states, NULL);
2408+
static DEVICE_ATTR_RO(states);
23882409

23892410
static struct attribute *cpuhp_cpu_root_attrs[] = {
23902411
&dev_attr_states.attr,
@@ -2457,28 +2478,27 @@ static const char *smt_states[] = {
24572478
[CPU_SMT_NOT_IMPLEMENTED] = "notimplemented",
24582479
};
24592480

2460-
static ssize_t
2461-
show_smt_control(struct device *dev, struct device_attribute *attr, char *buf)
2481+
static ssize_t control_show(struct device *dev,
2482+
struct device_attribute *attr, char *buf)
24622483
{
24632484
const char *state = smt_states[cpu_smt_control];
24642485

24652486
return snprintf(buf, PAGE_SIZE - 2, "%s\n", state);
24662487
}
24672488

2468-
static ssize_t
2469-
store_smt_control(struct device *dev, struct device_attribute *attr,
2470-
const char *buf, size_t count)
2489+
static ssize_t control_store(struct device *dev, struct device_attribute *attr,
2490+
const char *buf, size_t count)
24712491
{
24722492
return __store_smt_control(dev, attr, buf, count);
24732493
}
2474-
static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control);
2494+
static DEVICE_ATTR_RW(control);
24752495

2476-
static ssize_t
2477-
show_smt_active(struct device *dev, struct device_attribute *attr, char *buf)
2496+
static ssize_t active_show(struct device *dev,
2497+
struct device_attribute *attr, char *buf)
24782498
{
24792499
return snprintf(buf, PAGE_SIZE - 2, "%d\n", sched_smt_active());
24802500
}
2481-
static DEVICE_ATTR(active, 0444, show_smt_active, NULL);
2501+
static DEVICE_ATTR_RO(active);
24822502

24832503
static struct attribute *cpuhp_smt_attrs[] = {
24842504
&dev_attr_control.attr,

kernel/smp.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info,
764764
EXPORT_SYMBOL(smp_call_function_single);
765765

766766
/**
767-
* smp_call_function_single_async(): Run an asynchronous function on a
767+
* smp_call_function_single_async() - Run an asynchronous function on a
768768
* specific CPU.
769769
* @cpu: The CPU to run on.
770770
* @csd: Pre-allocated and setup data structure
@@ -783,6 +783,8 @@ EXPORT_SYMBOL(smp_call_function_single);
783783
*
784784
* NOTE: Be careful, there is unfortunately no current debugging facility to
785785
* validate the correctness of this serialization.
786+
*
787+
* Return: %0 on success or negative errno value on error
786788
*/
787789
int smp_call_function_single_async(int cpu, struct __call_single_data *csd)
788790
{
@@ -974,7 +976,7 @@ static void smp_call_function_many_cond(const struct cpumask *mask,
974976
* @mask: The set of cpus to run on (only runs on online subset).
975977
* @func: The function to run. This must be fast and non-blocking.
976978
* @info: An arbitrary pointer to pass to the function.
977-
* @flags: Bitmask that controls the operation. If %SCF_WAIT is set, wait
979+
* @wait: Bitmask that controls the operation. If %SCF_WAIT is set, wait
978980
* (atomically) until function has completed on other CPUs. If
979981
* %SCF_RUN_LOCAL is set, the function will also be run locally
980982
* if the local CPU is set in the @cpumask.
@@ -1180,7 +1182,13 @@ void wake_up_all_idle_cpus(void)
11801182
EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
11811183

11821184
/**
1183-
* smp_call_on_cpu - Call a function on a specific cpu
1185+
* struct smp_call_on_cpu_struct - Call a function on a specific CPU
1186+
* @work: &work_struct
1187+
* @done: &completion to signal
1188+
* @func: function to call
1189+
* @data: function's data argument
1190+
* @ret: return value from @func
1191+
* @cpu: target CPU (%-1 for any CPU)
11841192
*
11851193
* Used to call a function on a specific cpu and wait for it to return.
11861194
* Optionally make sure the call is done on a specified physical cpu via vcpu

kernel/smpboot.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread)
291291
unsigned int cpu;
292292
int ret = 0;
293293

294-
get_online_cpus();
294+
cpus_read_lock();
295295
mutex_lock(&smpboot_threads_lock);
296296
for_each_online_cpu(cpu) {
297297
ret = __smpboot_create_thread(plug_thread, cpu);
@@ -304,7 +304,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread)
304304
list_add(&plug_thread->list, &hotplug_threads);
305305
out:
306306
mutex_unlock(&smpboot_threads_lock);
307-
put_online_cpus();
307+
cpus_read_unlock();
308308
return ret;
309309
}
310310
EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread);
@@ -317,12 +317,12 @@ EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread);
317317
*/
318318
void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread)
319319
{
320-
get_online_cpus();
320+
cpus_read_lock();
321321
mutex_lock(&smpboot_threads_lock);
322322
list_del(&plug_thread->list);
323323
smpboot_destroy_threads(plug_thread);
324324
mutex_unlock(&smpboot_threads_lock);
325-
put_online_cpus();
325+
cpus_read_unlock();
326326
}
327327
EXPORT_SYMBOL_GPL(smpboot_unregister_percpu_thread);
328328

mm/swap_slots.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ void disable_swap_slots_cache_lock(void)
7070
swap_slot_cache_enabled = false;
7171
if (swap_slot_cache_initialized) {
7272
/* serialize with cpu hotplug operations */
73-
get_online_cpus();
73+
cpus_read_lock();
7474
__drain_swap_slots_cache(SLOTS_CACHE|SLOTS_CACHE_RET);
75-
put_online_cpus();
75+
cpus_read_unlock();
7676
}
7777
}
7878

0 commit comments

Comments
 (0)