2020-03-23 13:52:04

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 00/17] Convert cpu_up/down to device_online/offline

=============
Changes in v4
=============

* Split arm and arm64 patches so that the change to use reboot_cpu goes
into its own separate patch (Russell)
* Collected new Acked-by
* Rebased on top of v5.6-rc6
* Trimmed the CC list on the cover letter as lists were rejecting it


git clone git://linux-arm.org/linux-qy.git -b cpu-hp-cleanup-v4


Older post can be found here
----------------------------

https://lore.kernel.org/lkml/[email protected]/


=============
Test Coverage
=============

All tests ran with LOCKDEP enabled.

Platform: Juno-r2: arm64
------------------------

* Overnight rcutorture
* Overnight locktorture
* kexec -f Image --command="$(cat /proc/cmdline) reboot=s[0-5]"
* Hibernate to disk (using suspend option)
* Userspace hotplug via sysfs
* PSCI firemware checker

Notes:

* Couldn't convince Juno to hibernate using [reboot] or [shutdown]
options.

Platform: qemu (8 vCPUs) and VM (2 vCPUs): x86_64
-------------------------------------------------

* Overnight rcutorture
* Overnight locktorture
* Userspace hotplug via sysfs
* echo mmiotrace > /sys/kernel/debug/tracing/current_tracer &&
echo nop > /sys/kernel/debug/tracing/current_tracer
* Ran with CONFIG_DEBUG_HOTPLUG_CPU0 and CONFIG_BOOTPARAM_HOTPLUG_CPU0

Notes:

* qemu failed to bring cpu0 after offlining. Same behavior observed on
vanilla v5.6-rc6. Worked fine on the VM.

* mmiotrace successfully brought down all cpus when enabled,
then back online again when disabled. Including when cpu0 was
offline.

* My xen shenanigans are too 'humble' too create environment to test
the change in xen yet..


=====================
Original Cover Letter
=====================

Using cpu_up/down directly to bring cpus online/offline loses synchronization
with sysfs and could suffer from a race similar to what is described in
commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and serialization
during LPM").

cpu_up/down seem to be more of a internal implementation detail for the cpu
subsystem to use to boot up cpus, perform suspend/resume and low level hotplug
operations. Users outside of the cpu subsystem would be better using the device
core API to bring a cpu online/offline which is the interface used to hotplug
memory and other system devices.

Several users have already migrated to use the device core API, this series
converts the remaining users and hides cpu_up/down from internal users at the
end.

I noticed this problem while working on a hack to disable offlining
a particular CPU but noticed that setting the offline_disabled attribute in the
device struct isn't enough because users can easily bypass the device core.
While my hack isn't a valid use case but it did highlight the inconsistency in
the way cpus are being onlined/offlined and this attempt hopefully improves on
this.

The first patch introduces new API to {add,remove}_cpu() using device_{online,
offline}() with correct locks held and export it.

The following 10 patches fix arch users.

The remaining 6 patches fix generic code users. Particularly creating a new
special exported API for the device core to use instead of cpu_up/down.

The last patch removes cpu_up/down from cpu.h and unexport the functions.

In some cases where the use of cpu_up/down seemed legitimate, I encapsulated
the logic in a higher level - special purposed function; and converted the code
to use that instead.


CC: Thomas Gleixner <[email protected]>
CC: Tony Luck <[email protected]>
CC: Fenghua Yu <[email protected]>
CC: Russell King <[email protected]>
CC: Catalin Marinas <[email protected]>
CC: Michael Ellerman <[email protected]>
CC: "David S. Miller" <[email protected]>
CC: Helge Deller <[email protected]>
CC: Juergen Gross <[email protected]>
CC: Mark Rutland <[email protected]>
CC: Lorenzo Pieralisi <[email protected]>
CC: "Paul E. McKenney" <[email protected]>
CC: Greg Kroah-Hartman <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]

Qais Yousef (17):
cpu: Add new {add,remove}_cpu() functions
smp: Create a new function to shutdown nonboot cpus
ia64: Replace cpu_down with smp_shutdown_nonboot_cpus()
arm: Don't use disable_nonboot_cpus()
arm: Use reboot_cpu instead of hardcoding it to 0
arm64: Don't use disable_nonboot_cpus()
arm64: Use reboot_cpu instead of hardconding it to 0
arm64: hibernate.c: Create a new function to handle cpu_up(sleep_cpu)
x86: Replace cpu_up/down with add/remove_cpu
powerpc: Replace cpu_up/down with add/remove_cpu
sparc: Replace cpu_up/down with add/remove_cpu
parisc: Replace cpu_up/down with add/remove_cpu
driver: xen: Replace cpu_up/down with device_online/offline
firmware: psci: Replace cpu_up/down with add/remove_cpu
torture: Replace cpu_up/down with add/remove_cpu
smp: Create a new function to bringup nonboot cpus online
cpu: Hide cpu_up/down

arch/arm/kernel/reboot.c | 4 +-
arch/arm64/kernel/hibernate.c | 13 +--
arch/arm64/kernel/process.c | 4 +-
arch/ia64/kernel/process.c | 8 +-
arch/parisc/kernel/processor.c | 2 +-
arch/powerpc/kexec/core_64.c | 2 +-
arch/sparc/kernel/ds.c | 4 +-
arch/x86/kernel/topology.c | 22 ++---
arch/x86/mm/mmio-mod.c | 4 +-
arch/x86/xen/smp.c | 2 +-
drivers/base/cpu.c | 4 +-
drivers/firmware/psci/psci_checker.c | 4 +-
drivers/xen/cpu_hotplug.c | 2 +-
include/linux/cpu.h | 10 +-
kernel/cpu.c | 134 ++++++++++++++++++++++++++-
kernel/smp.c | 9 +-
kernel/torture.c | 9 +-
17 files changed, 172 insertions(+), 65 deletions(-)

--
2.17.1


2020-03-23 13:52:07

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 02/17] smp: Create a new function to shutdown nonboot cpus

This function will be used later in machine_shutdown() for some archs.

disable_nonboot_cpus() is not safe to use when doing machine_down(),
because it relies on freeze_secondary_cpus() which in turn is
a suspend/resume related freeze and could abort if the logic detects any
pending activities that can prevent finishing the offlining process.

Signed-off-by: Qais Yousef <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: Josh Poimboeuf <[email protected]>
CC: "Peter Zijlstra (Intel)" <[email protected]>
CC: Jiri Kosina <[email protected]>
CC: Nicholas Piggin <[email protected]>
CC: Daniel Lezcano <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: Eiichi Tsukata <[email protected]>
CC: Zhenzhong Duan <[email protected]>
CC: Nadav Amit <[email protected]>
CC: Greg Kroah-Hartman <[email protected]>
CC: "Rafael J. Wysocki" <[email protected]>
CC: Tony Luck <[email protected]>
CC: Fenghua Yu <[email protected]>
CC: Russell King <[email protected]>
CC: Catalin Marinas <[email protected]>
CC: Will Deacon <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
---
include/linux/cpu.h | 2 ++
kernel/cpu.c | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index cf8cf38dca43..64a246e9c8db 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -120,6 +120,7 @@ extern void cpu_hotplug_enable(void);
void clear_tasks_mm_cpumask(int cpu);
int cpu_down(unsigned int cpu);
int remove_cpu(unsigned int cpu);
+extern void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);

#else /* CONFIG_HOTPLUG_CPU */

@@ -131,6 +132,7 @@ static inline int cpus_read_trylock(void) { return true; }
static inline void lockdep_assert_cpus_held(void) { }
static inline void cpu_hotplug_disable(void) { }
static inline void cpu_hotplug_enable(void) { }
+static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { }
#endif /* !CONFIG_HOTPLUG_CPU */

/* Wrappers which go away once all code is converted */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 069802f7010f..03c727195b65 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1069,6 +1069,48 @@ int remove_cpu(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(remove_cpu);

+void smp_shutdown_nonboot_cpus(unsigned int primary_cpu)
+{
+ unsigned int cpu;
+ int error;
+
+ cpu_maps_update_begin();
+
+ /*
+ * Make certain the cpu I'm about to reboot on is online.
+ *
+ * This is inline to what migrate_to_reboot_cpu() already do.
+ */
+ if (!cpu_online(primary_cpu))
+ primary_cpu = cpumask_first(cpu_online_mask);
+
+ for_each_online_cpu(cpu) {
+ if (cpu == primary_cpu)
+ continue;
+
+ error = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
+ if (error) {
+ pr_err("Failed to offline CPU%d - error=%d",
+ cpu, error);
+ break;
+ }
+ }
+
+ /*
+ * Ensure all but the reboot CPU are offline.
+ */
+ BUG_ON(num_online_cpus() > 1);
+
+ /*
+ * Make sure the CPUs won't be enabled by someone else after this
+ * point. Kexec will reboot to a new kernel shortly resetting
+ * everything along the way.
+ */
+ cpu_hotplug_disabled++;
+
+ cpu_maps_update_done();
+}
+
#else
#define takedown_cpu NULL
#endif /*CONFIG_HOTPLUG_CPU*/
--
2.17.1

2020-03-23 13:52:18

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 05/17] arm: Use reboot_cpu instead of hardcoding it to 0

Use `reboot_cpu` variable instead of hardcoding 0 as the reboot cpu in
machine_shutdown().

Signed-off-by: Qais Yousef <[email protected]>
CC: Russell King <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/arm/kernel/reboot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 58ad1a70f770..0ce388f15422 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -92,7 +92,7 @@ void soft_restart(unsigned long addr)
*/
void machine_shutdown(void)
{
- smp_shutdown_nonboot_cpus(0);
+ smp_shutdown_nonboot_cpus(reboot_cpu);
}

/*
--
2.17.1

2020-03-23 13:52:25

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 08/17] arm64: hibernate.c: Create a new function to handle cpu_up(sleep_cpu)

In preparation to make cpu_up/down private - move the user in arm64
hibernate.c to use a new generic function that provides what arm64
needs.

Acked-by: Catalin Marinas <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: Catalin Marinas <[email protected]>
CC: Will Deacon <[email protected]>
CC: Steve Capper <[email protected]>
CC: Richard Fontana <[email protected]>
CC: James Morse <[email protected]>
CC: Mark Rutland <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: Josh Poimboeuf <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: "Peter Zijlstra (Intel)" <[email protected]>
CC: Nicholas Piggin <[email protected]>
CC: Daniel Lezcano <[email protected]>
CC: Jiri Kosina <[email protected]>
CC: Pavankumar Kondeti <[email protected]>
CC: Zhenzhong Duan <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/arm64/kernel/hibernate.c | 13 +++++--------
include/linux/cpu.h | 1 +
kernel/cpu.c | 24 ++++++++++++++++++++++++
3 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 590963c9c609..5b73e92c99e3 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -166,14 +166,11 @@ int arch_hibernation_header_restore(void *addr)
sleep_cpu = -EINVAL;
return -EINVAL;
}
- if (!cpu_online(sleep_cpu)) {
- pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
- ret = cpu_up(sleep_cpu);
- if (ret) {
- pr_err("Failed to bring hibernate-CPU up!\n");
- sleep_cpu = -EINVAL;
- return ret;
- }
+
+ ret = bringup_hibernate_cpu(sleep_cpu);
+ if (ret) {
+ sleep_cpu = -EINVAL;
+ return ret;
}

resume_hdr = *hdr;
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 64a246e9c8db..aebe8186cb07 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -93,6 +93,7 @@ int add_cpu(unsigned int cpu);
void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
+extern int bringup_hibernate_cpu(unsigned int sleep_cpu);

#else /* CONFIG_SMP */
#define cpuhp_tasks_frozen 0
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 03c727195b65..bf39c5bfb6d9 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1275,6 +1275,30 @@ int add_cpu(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(add_cpu);

+/**
+ * bringup_hibernate_cpu - Bring up the CPU that we hibernated on
+ * @sleep_cpu: The cpu we hibernated on and should be brought up.
+ *
+ * On some archs like arm64, we can hibernate on any CPU, but on wake up the
+ * CPU we hibernated on might be offline as a side effect of using maxcpus= for
+ * example.
+ */
+int bringup_hibernate_cpu(unsigned int sleep_cpu)
+{
+ int ret;
+
+ if (!cpu_online(sleep_cpu)) {
+ pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
+ ret = cpu_up(sleep_cpu);
+ if (ret) {
+ pr_err("Failed to bring hibernate-CPU up!\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_PM_SLEEP_SMP
static cpumask_var_t frozen_cpus;

--
2.17.1

2020-03-23 13:52:32

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 11/17] sparc: Replace cpu_up/down with add/remove_cpu

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Acked-by: David S. Miller <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: "David S. Miller" <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: Bjorn Helgaas <[email protected]>
CC: "Rafael J. Wysocki" <[email protected]>
CC: Greg Kroah-Hartman <[email protected]>
CC: Sakari Ailus <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/sparc/kernel/ds.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index bbf59b3b4af8..75232cbd58bf 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -555,7 +555,7 @@ static int dr_cpu_configure(struct ds_info *dp, struct ds_cap_state *cp,

printk(KERN_INFO "ds-%llu: Starting cpu %d...\n",
dp->id, cpu);
- err = cpu_up(cpu);
+ err = add_cpu(cpu);
if (err) {
__u32 res = DR_CPU_RES_FAILURE;
__u32 stat = DR_CPU_STAT_UNCONFIGURED;
@@ -611,7 +611,7 @@ static int dr_cpu_unconfigure(struct ds_info *dp,

printk(KERN_INFO "ds-%llu: Shutting down cpu %d...\n",
dp->id, cpu);
- err = cpu_down(cpu);
+ err = remove_cpu(cpu);
if (err)
dr_cpu_mark(resp, cpu, ncpus,
DR_CPU_RES_FAILURE,
--
2.17.1

2020-03-23 13:52:37

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 13/17] driver: xen: Replace cpu_up/down with device_online/offline

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Reviewed-by: Juergen Gross <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: Boris Ostrovsky <[email protected]>
CC: Juergen Gross <[email protected]>
CC: Stefano Stabellini <[email protected]>
CC: [email protected]
CC: [email protected]
---
drivers/xen/cpu_hotplug.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index f192b6f42da9..ec975decb5de 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -94,7 +94,7 @@ static int setup_cpu_watcher(struct notifier_block *notifier,

for_each_possible_cpu(cpu) {
if (vcpu_online(cpu) == 0) {
- (void)cpu_down(cpu);
+ device_offline(get_cpu_device(cpu));
set_cpu_present(cpu, false);
}
}
--
2.17.1

2020-03-23 13:52:38

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 14/17] firmware: psci: Replace cpu_up/down with add/remove_cpu

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Signed-off-by: Qais Yousef <[email protected]>
CC: Mark Rutland <[email protected]>
CC: Lorenzo Pieralisi <[email protected]>
CC: [email protected]
CC: [email protected]
---
drivers/firmware/psci/psci_checker.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
index 6a445397771c..873841af8d57 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -84,7 +84,7 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,

/* Try to power down all CPUs in the mask. */
for_each_cpu(cpu, cpus) {
- int ret = cpu_down(cpu);
+ int ret = remove_cpu(cpu);

/*
* cpu_down() checks the number of online CPUs before the TOS
@@ -116,7 +116,7 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,

/* Try to power up all the CPUs that have been offlined. */
for_each_cpu(cpu, offlined_cpus) {
- int ret = cpu_up(cpu);
+ int ret = add_cpu(cpu);

if (ret != 0) {
pr_err("Error occurred (%d) while trying "
--
2.17.1

2020-03-23 13:52:49

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 17/17] cpu: Hide cpu_up/down

Provide a special exported function for the device core to bring a cpu
up/down and hide the real cpu_up/down as they are treated as private
functions. cpu_up/down are lower level API and users outside the cpu
subsystem should use add/remove_cpu() which will take care of extra
housekeeping work like keeping sysfs in sync.

Signed-off-by: Qais Yousef <[email protected]>
CC: Greg Kroah-Hartman <[email protected]>
CC: "Rafael J. Wysocki" <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: Josh Poimboeuf <[email protected]>
CC: Nicholas Piggin <[email protected]>
CC: "Peter Zijlstra (Intel)" <[email protected]>
CC: Jiri Kosina <[email protected]>
CC: Daniel Lezcano <[email protected]>
CC: Eiichi Tsukata <[email protected]>
CC: Zhenzhong Duan <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: Pavankumar Kondeti <[email protected]>
CC: [email protected]
---
drivers/base/cpu.c | 4 ++--
include/linux/cpu.h | 4 ++--
kernel/cpu.c | 32 ++++++++++++++++++++++++++++----
3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 6265871a4af2..9a134cd362ee 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -55,7 +55,7 @@ static int cpu_subsys_online(struct device *dev)
if (from_nid == NUMA_NO_NODE)
return -ENODEV;

- ret = cpu_up(cpuid);
+ ret = cpu_subsys_up(dev);
/*
* When hot adding memory to memoryless node and enabling a cpu
* on the node, node number of the cpu may internally change.
@@ -69,7 +69,7 @@ static int cpu_subsys_online(struct device *dev)

static int cpu_subsys_offline(struct device *dev)
{
- return cpu_down(dev->id);
+ return cpu_subsys_down(dev);
}

void unregister_cpu(struct cpu *cpu)
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 3d3caecef395..e1bbd8d6ecec 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -88,8 +88,8 @@ extern ssize_t arch_cpu_release(const char *, size_t);

#ifdef CONFIG_SMP
extern bool cpuhp_tasks_frozen;
-int cpu_up(unsigned int cpu);
int add_cpu(unsigned int cpu);
+int cpu_subsys_up(struct device *dev);
void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
@@ -120,8 +120,8 @@ extern void lockdep_assert_cpus_held(void);
extern void cpu_hotplug_disable(void);
extern void cpu_hotplug_enable(void);
void clear_tasks_mm_cpumask(int cpu);
-int cpu_down(unsigned int cpu);
int remove_cpu(unsigned int cpu);
+int cpu_subsys_down(struct device *dev);
extern void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);

#else /* CONFIG_HOTPLUG_CPU */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 7c6aa427a3a3..017e16dfcccd 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1051,11 +1051,23 @@ static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
return err;
}

-int cpu_down(unsigned int cpu)
+static int cpu_down(unsigned int cpu)
{
return do_cpu_down(cpu, CPUHP_OFFLINE);
}
-EXPORT_SYMBOL(cpu_down);
+
+/**
+ * cpu_subsys_down - Bring down a cpu device
+ * @dev: Pointer to the cpu device to offline
+ *
+ * This function is meant to be used by device core cpu subsystem only.
+ *
+ * Other subsystems should use remove_cpu() instead.
+ */
+int cpu_subsys_down(struct device *dev)
+{
+ return cpu_down(dev->id);
+}

int remove_cpu(unsigned int cpu)
{
@@ -1257,11 +1269,23 @@ static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
return err;
}

-int cpu_up(unsigned int cpu)
+static int cpu_up(unsigned int cpu)
{
return do_cpu_up(cpu, CPUHP_ONLINE);
}
-EXPORT_SYMBOL_GPL(cpu_up);
+
+/**
+ * cpu_subsys_up - Bring up a cpu device
+ * @dev: Pointer to the cpu device to online
+ *
+ * This function is meant to be used by device core cpu subsystem only.
+ *
+ * Other subsystems should use add_cpu() instead.
+ */
+int cpu_subsys_up(struct device *dev)
+{
+ return cpu_up(dev->id);
+}

int add_cpu(unsigned int cpu)
{
--
2.17.1

2020-03-23 13:53:00

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 01/17] cpu: Add new {add,remove}_cpu() functions

The new functions use device_{online,offline}() which are userspace
safe.

This is in preparation to move cpu_{up, down} kernel users to use
a safer interface that is not racy with userspace.

Suggested-by: "Paul E. McKenney" <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: "Paul E. McKenney" <[email protected]>
CC: Helge Deller <[email protected]>
CC: Michael Ellerman <[email protected]>
CC: "David S. Miller" <[email protected]>
CC: Juergen Gross <[email protected]>
CC: Mark Rutland <[email protected]>
CC: Lorenzo Pieralisi <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
---
include/linux/cpu.h | 2 ++
kernel/cpu.c | 24 ++++++++++++++++++++++++
2 files changed, 26 insertions(+)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 1ca2baf817ed..cf8cf38dca43 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -89,6 +89,7 @@ extern ssize_t arch_cpu_release(const char *, size_t);
#ifdef CONFIG_SMP
extern bool cpuhp_tasks_frozen;
int cpu_up(unsigned int cpu);
+int add_cpu(unsigned int cpu);
void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
@@ -118,6 +119,7 @@ extern void cpu_hotplug_disable(void);
extern void cpu_hotplug_enable(void);
void clear_tasks_mm_cpumask(int cpu);
int cpu_down(unsigned int cpu);
+int remove_cpu(unsigned int cpu);

#else /* CONFIG_HOTPLUG_CPU */

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 9c706af713fb..069802f7010f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1057,6 +1057,18 @@ int cpu_down(unsigned int cpu)
}
EXPORT_SYMBOL(cpu_down);

+int remove_cpu(unsigned int cpu)
+{
+ int ret;
+
+ lock_device_hotplug();
+ ret = device_offline(get_cpu_device(cpu));
+ unlock_device_hotplug();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(remove_cpu);
+
#else
#define takedown_cpu NULL
#endif /*CONFIG_HOTPLUG_CPU*/
@@ -1209,6 +1221,18 @@ int cpu_up(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(cpu_up);

+int add_cpu(unsigned int cpu)
+{
+ int ret;
+
+ lock_device_hotplug();
+ ret = device_online(get_cpu_device(cpu));
+ unlock_device_hotplug();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(add_cpu);
+
#ifdef CONFIG_PM_SLEEP_SMP
static cpumask_var_t frozen_cpus;

--
2.17.1

2020-03-23 13:53:04

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 12/17] parisc: Replace cpu_up/down with add/remove_cpu

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Acked-by: Helge Deller <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: "James E.J. Bottomley" <[email protected]>
CC: Helge Deller <[email protected]>
CC: Richard Fontana <[email protected]>
CC: Armijn Hemel <[email protected]>
CC: Greg Kroah-Hartman <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/parisc/kernel/processor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 13f771f74ee3..7f2d0c0ecc80 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -212,7 +212,7 @@ static int __init processor_probe(struct parisc_device *dev)
#ifdef CONFIG_SMP
if (cpuid) {
set_cpu_present(cpuid, true);
- cpu_up(cpuid);
+ add_cpu(cpuid);
}
#endif

--
2.17.1

2020-03-23 13:53:07

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 07/17] arm64: Use reboot_cpu instead of hardconding it to 0

Use `reboot_cpu` variable instead of hardcoding 0 as the reboot cpu in
machine_shutdown().

Acked-by: Catalin Marinas <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: Catalin Marinas <[email protected]>
CC: Will Deacon <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/arm64/kernel/process.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 1b9f7b749d75..3e5a6ad66cbe 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -145,7 +145,7 @@ void arch_cpu_idle_dead(void)
*/
void machine_shutdown(void)
{
- smp_shutdown_nonboot_cpus(0);
+ smp_shutdown_nonboot_cpus(reboot_cpu);
}

/*
--
2.17.1

2020-03-23 13:53:09

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 04/17] arm: Don't use disable_nonboot_cpus()

disable_nonboot_cpus() is not safe to use when doing machine_down(),
because it relies on freeze_secondary_cpus() which in turn is
a suspend/resume related freeze and could abort if the logic detects any
pending activities that can prevent finishing the offlining process.

Beside disable_nonboot_cpus() is dependent on CONFIG_PM_SLEEP_SMP which
is an othogonal config to rely on to ensure this function works
correctly.

Signed-off-by: Qais Yousef <[email protected]>
CC: Russell King <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/arm/kernel/reboot.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index bb18ed0539f4..58ad1a70f770 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -88,11 +88,11 @@ void soft_restart(unsigned long addr)
* to execute e.g. a RAM-based pin loop is not sufficient. This allows the
* kexec'd kernel to use any and all RAM as it sees fit, without having to
* avoid any code or data used by any SW CPU pin loop. The CPU hotplug
- * functionality embodied in disable_nonboot_cpus() to achieve this.
+ * functionality embodied in smp_shutdown_nonboot_cpus() to achieve this.
*/
void machine_shutdown(void)
{
- disable_nonboot_cpus();
+ smp_shutdown_nonboot_cpus(0);
}

/*
--
2.17.1

2020-03-23 13:53:10

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 09/17] x86: Replace cpu_up/down with add/remove_cpu

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Signed-off-by: Qais Yousef <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: Borislav Petkov <[email protected]>
CC: "H. Peter Anvin" <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/x86/kernel/topology.c | 22 ++++++----------------
arch/x86/mm/mmio-mod.c | 4 ++--
arch/x86/xen/smp.c | 2 +-
3 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index be5bc2e47c71..b8810ebbc8ae 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -59,39 +59,29 @@ __setup("cpu0_hotplug", enable_cpu0_hotplug);
*/
int _debug_hotplug_cpu(int cpu, int action)
{
- struct device *dev = get_cpu_device(cpu);
int ret;

if (!cpu_is_hotpluggable(cpu))
return -EINVAL;

- lock_device_hotplug();
-
switch (action) {
case 0:
- ret = cpu_down(cpu);
- if (!ret) {
+ ret = remove_cpu(cpu);
+ if (!ret)
pr_info("DEBUG_HOTPLUG_CPU0: CPU %u is now offline\n", cpu);
- dev->offline = true;
- kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
- } else
+ else
pr_debug("Can't offline CPU%d.\n", cpu);
break;
case 1:
- ret = cpu_up(cpu);
- if (!ret) {
- dev->offline = false;
- kobject_uevent(&dev->kobj, KOBJ_ONLINE);
- } else {
+ ret = add_cpu(cpu);
+ if (ret)
pr_debug("Can't online CPU%d.\n", cpu);
- }
+
break;
default:
ret = -EINVAL;
}

- unlock_device_hotplug();
-
return ret;
}

diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 673de6063345..109325d77b3e 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -386,7 +386,7 @@ static void enter_uniprocessor(void)
put_online_cpus();

for_each_cpu(cpu, downed_cpus) {
- err = cpu_down(cpu);
+ err = remove_cpu(cpu);
if (!err)
pr_info("CPU%d is down.\n", cpu);
else
@@ -406,7 +406,7 @@ static void leave_uniprocessor(void)
return;
pr_notice("Re-enabling CPUs...\n");
for_each_cpu(cpu, downed_cpus) {
- err = cpu_up(cpu);
+ err = add_cpu(cpu);
if (!err)
pr_info("enabled CPU%d.\n", cpu);
else
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 7a43b2ae19f1..2097fa0ebdb5 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -132,7 +132,7 @@ void __init xen_smp_cpus_done(unsigned int max_cpus)
if (xen_vcpu_nr(cpu) < MAX_VIRT_CPUS)
continue;

- rc = cpu_down(cpu);
+ rc = remove_cpu(cpu);

if (rc == 0) {
/*
--
2.17.1

2020-03-23 13:53:12

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 06/17] arm64: Don't use disable_nonboot_cpus()

disable_nonboot_cpus() is not safe to use when doing machine_down(),
because it relies on freeze_secondary_cpus() which in turn is
a suspend/resume related freeze and could abort if the logic detects any
pending activities that can prevent finishing the offlining process.

Beside disable_nonboot_cpus() is dependent on CONFIG_PM_SLEEP_SMP which
is an othogonal config to rely on to ensure this function works
correctly.

Acked-by: Catalin Marinas <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: Catalin Marinas <[email protected]>
CC: Will Deacon <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/arm64/kernel/process.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 00626057a384..1b9f7b749d75 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -141,11 +141,11 @@ void arch_cpu_idle_dead(void)
* to execute e.g. a RAM-based pin loop is not sufficient. This allows the
* kexec'd kernel to use any and all RAM as it sees fit, without having to
* avoid any code or data used by any SW CPU pin loop. The CPU hotplug
- * functionality embodied in disable_nonboot_cpus() to achieve this.
+ * functionality embodied in smpt_shutdown_nonboot_cpus() to achieve this.
*/
void machine_shutdown(void)
{
- disable_nonboot_cpus();
+ smp_shutdown_nonboot_cpus(0);
}

/*
--
2.17.1

2020-03-23 13:53:38

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 15/17] torture: Replace cpu_up/down with add/remove_cpu

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Acked-by: "Paul E. McKenney" <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: "Paul E. McKenney" <[email protected]>
CC: Davidlohr Bueso <[email protected]>
CC: Josh Triplett <[email protected]>
CC: [email protected]
---
kernel/torture.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/kernel/torture.c b/kernel/torture.c
index 7c13f5558b71..a479689eac73 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -97,7 +97,7 @@ bool torture_offline(int cpu, long *n_offl_attempts, long *n_offl_successes,
torture_type, cpu);
starttime = jiffies;
(*n_offl_attempts)++;
- ret = cpu_down(cpu);
+ ret = remove_cpu(cpu);
if (ret) {
if (verbose)
pr_alert("%s" TORTURE_FLAG
@@ -148,7 +148,7 @@ bool torture_online(int cpu, long *n_onl_attempts, long *n_onl_successes,
torture_type, cpu);
starttime = jiffies;
(*n_onl_attempts)++;
- ret = cpu_up(cpu);
+ ret = add_cpu(cpu);
if (ret) {
if (verbose)
pr_alert("%s" TORTURE_FLAG
@@ -192,17 +192,18 @@ torture_onoff(void *arg)
for_each_online_cpu(cpu)
maxcpu = cpu;
WARN_ON(maxcpu < 0);
- if (!IS_MODULE(CONFIG_TORTURE_TEST))
+ if (!IS_MODULE(CONFIG_TORTURE_TEST)) {
for_each_possible_cpu(cpu) {
if (cpu_online(cpu))
continue;
- ret = cpu_up(cpu);
+ ret = add_cpu(cpu);
if (ret && verbose) {
pr_alert("%s" TORTURE_FLAG
"%s: Initial online %d: errno %d\n",
__func__, torture_type, cpu, ret);
}
}
+ }

if (maxcpu == 0) {
VERBOSE_TOROUT_STRING("Only one CPU, so CPU-hotplug testing is disabled");
--
2.17.1

2020-03-23 13:53:55

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 16/17] smp: Create a new function to bringup nonboot cpus online

This is the last direct user of cpu_up() before we can hide it now as
internal implementation detail of the cpu subsystem.

Signed-off-by: Qais Yousef <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: Josh Poimboeuf <[email protected]>
CC: "Peter Zijlstra (Intel)" <[email protected]>
CC: Jiri Kosina <[email protected]>
CC: Nicholas Piggin <[email protected]>
CC: Daniel Lezcano <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: Eiichi Tsukata <[email protected]>
CC: Zhenzhong Duan <[email protected]>
CC: Nadav Amit <[email protected]>
CC: Greg Kroah-Hartman <[email protected]>
CC: "Rafael J. Wysocki" <[email protected]>
CC: [email protected]
---
include/linux/cpu.h | 1 +
kernel/cpu.c | 12 ++++++++++++
kernel/smp.c | 9 +--------
3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index aebe8186cb07..3d3caecef395 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -94,6 +94,7 @@ void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
extern int bringup_hibernate_cpu(unsigned int sleep_cpu);
+extern void smp_bringup_nonboot_cpus(unsigned int setup_max_cpus);

#else /* CONFIG_SMP */
#define cpuhp_tasks_frozen 0
diff --git a/kernel/cpu.c b/kernel/cpu.c
index bf39c5bfb6d9..7c6aa427a3a3 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1299,6 +1299,18 @@ int bringup_hibernate_cpu(unsigned int sleep_cpu)
return 0;
}

+void smp_bringup_nonboot_cpus(unsigned int setup_max_cpus)
+{
+ unsigned int cpu;
+
+ for_each_present_cpu(cpu) {
+ if (num_online_cpus() >= setup_max_cpus)
+ break;
+ if (!cpu_online(cpu))
+ cpu_up(cpu);
+ }
+}
+
#ifdef CONFIG_PM_SLEEP_SMP
static cpumask_var_t frozen_cpus;

diff --git a/kernel/smp.c b/kernel/smp.c
index d0ada39eb4d4..9e793cfd6128 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -589,20 +589,13 @@ void __init setup_nr_cpu_ids(void)
void __init smp_init(void)
{
int num_nodes, num_cpus;
- unsigned int cpu;

idle_threads_init();
cpuhp_threads_init();

pr_info("Bringing up secondary CPUs ...\n");

- /* FIXME: This should be done in userspace --RR */
- for_each_present_cpu(cpu) {
- if (num_online_cpus() >= setup_max_cpus)
- break;
- if (!cpu_online(cpu))
- cpu_up(cpu);
- }
+ smp_bringup_nonboot_cpus(setup_max_cpus);

num_nodes = num_online_nodes();
num_cpus = num_online_cpus();
--
2.17.1

2020-03-23 13:54:04

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 10/17] powerpc: Replace cpu_up/down with add/remove_cpu

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Acked-by: Michael Ellerman <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
CC: Benjamin Herrenschmidt <[email protected]>
CC: Paul Mackerras <[email protected]>
CC: Michael Ellerman <[email protected]>
CC: Enrico Weigelt <[email protected]>
CC: Ram Pai <[email protected]>
CC: Nicholas Piggin <[email protected]>
CC: Thiago Jung Bauermann <[email protected]>
CC: Christophe Leroy <[email protected]>
CC: Thomas Gleixner <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/powerpc/kexec/core_64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 04a7cba58eff..b4184092172a 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -212,7 +212,7 @@ static void wake_offline_cpus(void)
if (!cpu_online(cpu)) {
printk(KERN_INFO "kexec: Waking offline cpu %d.\n",
cpu);
- WARN_ON(cpu_up(cpu));
+ WARN_ON(add_cpu(cpu));
}
}
}
--
2.17.1

2020-03-23 13:54:06

by Qais Yousef

[permalink] [raw]
Subject: [PATCH v4 03/17] ia64: Replace cpu_down with smp_shutdown_nonboot_cpus()

Use the new smp_shutdown_nonboot_cpus() instead of open coding using
cpu_down() directly.

Use reboot_cpu instead of hardcoding the boot CPU to 0.

This also prepares to make cpu_up/down a private interface for anything
but the cpu subsystem.

Signed-off-by: Qais Yousef <[email protected]>
CC: Tony Luck <[email protected]>
CC: Fenghua Yu <[email protected]>
CC: [email protected]
CC: [email protected]
---
arch/ia64/kernel/process.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 968b5f33e725..bf4c0cdb7a25 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -646,14 +646,8 @@ cpu_halt (void)

void machine_shutdown(void)
{
-#ifdef CONFIG_HOTPLUG_CPU
- int cpu;
+ smp_shutdown_nonboot_cpus(reboot_cpu);

- for_each_online_cpu(cpu) {
- if (cpu != smp_processor_id())
- cpu_down(cpu);
- }
-#endif
#ifdef CONFIG_KEXEC
kexec_disable_iosapic();
#endif
--
2.17.1

2020-03-23 15:01:42

by Paul E. McKenney

[permalink] [raw]
Subject: Re: [PATCH v4 01/17] cpu: Add new {add,remove}_cpu() functions

On Mon, Mar 23, 2020 at 01:50:54PM +0000, Qais Yousef wrote:
> The new functions use device_{online,offline}() which are userspace
> safe.
>
> This is in preparation to move cpu_{up, down} kernel users to use
> a safer interface that is not racy with userspace.
>
> Suggested-by: "Paul E. McKenney" <[email protected]>
> Signed-off-by: Qais Yousef <[email protected]>
> CC: Thomas Gleixner <[email protected]>
> CC: "Paul E. McKenney" <[email protected]>

Reviewed-by: Paul E. McKenney <[email protected]>

> CC: Helge Deller <[email protected]>
> CC: Michael Ellerman <[email protected]>
> CC: "David S. Miller" <[email protected]>
> CC: Juergen Gross <[email protected]>
> CC: Mark Rutland <[email protected]>
> CC: Lorenzo Pieralisi <[email protected]>
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> ---
> include/linux/cpu.h | 2 ++
> kernel/cpu.c | 24 ++++++++++++++++++++++++
> 2 files changed, 26 insertions(+)
>
> diff --git a/include/linux/cpu.h b/include/linux/cpu.h
> index 1ca2baf817ed..cf8cf38dca43 100644
> --- a/include/linux/cpu.h
> +++ b/include/linux/cpu.h
> @@ -89,6 +89,7 @@ extern ssize_t arch_cpu_release(const char *, size_t);
> #ifdef CONFIG_SMP
> extern bool cpuhp_tasks_frozen;
> int cpu_up(unsigned int cpu);
> +int add_cpu(unsigned int cpu);
> void notify_cpu_starting(unsigned int cpu);
> extern void cpu_maps_update_begin(void);
> extern void cpu_maps_update_done(void);
> @@ -118,6 +119,7 @@ extern void cpu_hotplug_disable(void);
> extern void cpu_hotplug_enable(void);
> void clear_tasks_mm_cpumask(int cpu);
> int cpu_down(unsigned int cpu);
> +int remove_cpu(unsigned int cpu);
>
> #else /* CONFIG_HOTPLUG_CPU */
>
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 9c706af713fb..069802f7010f 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -1057,6 +1057,18 @@ int cpu_down(unsigned int cpu)
> }
> EXPORT_SYMBOL(cpu_down);
>
> +int remove_cpu(unsigned int cpu)
> +{
> + int ret;
> +
> + lock_device_hotplug();
> + ret = device_offline(get_cpu_device(cpu));
> + unlock_device_hotplug();
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(remove_cpu);
> +
> #else
> #define takedown_cpu NULL
> #endif /*CONFIG_HOTPLUG_CPU*/
> @@ -1209,6 +1221,18 @@ int cpu_up(unsigned int cpu)
> }
> EXPORT_SYMBOL_GPL(cpu_up);
>
> +int add_cpu(unsigned int cpu)
> +{
> + int ret;
> +
> + lock_device_hotplug();
> + ret = device_online(get_cpu_device(cpu));
> + unlock_device_hotplug();
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(add_cpu);
> +
> #ifdef CONFIG_PM_SLEEP_SMP
> static cpumask_var_t frozen_cpus;
>
> --
> 2.17.1
>

Subject: [tip: smp/core] cpu/hotplug: Hide cpu_up/down()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 33c3736ec88811b9b6f6ce2cc8967f6b97c3db5e
Gitweb: https://git.kernel.org/tip/33c3736ec88811b9b6f6ce2cc8967f6b97c3db5e
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:10
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:38 +01:00

cpu/hotplug: Hide cpu_up/down()

Use separate functions for the device core to bring a CPU up and down.

Users outside the device core must use add/remove_cpu() which will take
care of extra housekeeping work like keeping sysfs in sync.

Make cpu_up/down() static and replace the extra layer of indirection.

[ tglx: Removed the extra wrapper functions and adjusted function names ]

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
---
drivers/base/cpu.c | 4 ++--
include/linux/cpu.h | 4 ++--
kernel/cpu.c | 42 ++++++++++++++++++++++++++++--------------
3 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 6265871..b93a8f8 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -55,7 +55,7 @@ static int cpu_subsys_online(struct device *dev)
if (from_nid == NUMA_NO_NODE)
return -ENODEV;

- ret = cpu_up(cpuid);
+ ret = cpu_device_up(dev);
/*
* When hot adding memory to memoryless node and enabling a cpu
* on the node, node number of the cpu may internally change.
@@ -69,7 +69,7 @@ static int cpu_subsys_online(struct device *dev)

static int cpu_subsys_offline(struct device *dev)
{
- return cpu_down(dev->id);
+ return cpu_device_down(dev);
}

void unregister_cpu(struct cpu *cpu)
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 8b295f7..9ead281 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -88,8 +88,8 @@ extern ssize_t arch_cpu_release(const char *, size_t);

#ifdef CONFIG_SMP
extern bool cpuhp_tasks_frozen;
-int cpu_up(unsigned int cpu);
int add_cpu(unsigned int cpu);
+int cpu_device_up(struct device *dev);
void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
@@ -120,8 +120,8 @@ extern void lockdep_assert_cpus_held(void);
extern void cpu_hotplug_disable(void);
extern void cpu_hotplug_enable(void);
void clear_tasks_mm_cpumask(int cpu);
-int cpu_down(unsigned int cpu);
int remove_cpu(unsigned int cpu);
+int cpu_device_down(struct device *dev);
extern void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);

#else /* CONFIG_HOTPLUG_CPU */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 4783d81..3084849 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1041,7 +1041,7 @@ static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target)
return _cpu_down(cpu, 0, target);
}

-static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
+static int cpu_down(unsigned int cpu, enum cpuhp_state target)
{
int err;

@@ -1051,11 +1051,18 @@ static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
return err;
}

-int cpu_down(unsigned int cpu)
+/**
+ * cpu_device_down - Bring down a cpu device
+ * @dev: Pointer to the cpu device to offline
+ *
+ * This function is meant to be used by device core cpu subsystem only.
+ *
+ * Other subsystems should use remove_cpu() instead.
+ */
+int cpu_device_down(struct device *dev)
{
- return do_cpu_down(cpu, CPUHP_OFFLINE);
+ return cpu_down(dev->id, CPUHP_OFFLINE);
}
-EXPORT_SYMBOL(cpu_down);

int remove_cpu(unsigned int cpu)
{
@@ -1178,8 +1185,8 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
}

/*
- * The caller of do_cpu_up might have raced with another
- * caller. Ignore it for now.
+ * The caller of cpu_up() might have raced with another
+ * caller. Nothing to do.
*/
if (st->state >= target)
goto out;
@@ -1223,7 +1230,7 @@ out:
return ret;
}

-static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
+static int cpu_up(unsigned int cpu, enum cpuhp_state target)
{
int err = 0;

@@ -1257,11 +1264,18 @@ out:
return err;
}

-int cpu_up(unsigned int cpu)
+/**
+ * cpu_device_up - Bring up a cpu device
+ * @dev: Pointer to the cpu device to online
+ *
+ * This function is meant to be used by device core cpu subsystem only.
+ *
+ * Other subsystems should use add_cpu() instead.
+ */
+int cpu_device_up(struct device *dev)
{
- return do_cpu_up(cpu, CPUHP_ONLINE);
+ return cpu_up(dev->id, CPUHP_ONLINE);
}
-EXPORT_SYMBOL_GPL(cpu_up);

int add_cpu(unsigned int cpu)
{
@@ -1289,7 +1303,7 @@ int bringup_hibernate_cpu(unsigned int sleep_cpu)

if (!cpu_online(sleep_cpu)) {
pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
- ret = cpu_up(sleep_cpu);
+ ret = cpu_up(sleep_cpu, CPUHP_ONLINE);
if (ret) {
pr_err("Failed to bring hibernate-CPU up!\n");
return ret;
@@ -1306,7 +1320,7 @@ void bringup_nonboot_cpus(unsigned int setup_max_cpus)
if (num_online_cpus() >= setup_max_cpus)
break;
if (!cpu_online(cpu))
- cpu_up(cpu);
+ cpu_up(cpu, CPUHP_ONLINE);
}
}

@@ -2129,9 +2143,9 @@ static ssize_t write_cpuhp_target(struct device *dev,
goto out;

if (st->state < target)
- ret = do_cpu_up(dev->id, target);
+ ret = cpu_up(dev->id, target);
else
- ret = do_cpu_down(dev->id, target);
+ ret = cpu_down(dev->id, target);
out:
unlock_device_hotplug();
return ret ? ret : count;

Subject: [tip: smp/core] cpu/hotplug: Move bringup of secondary CPUs out of smp_init()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: b99a26593b5190fac6b5c1f81a7f8cc128a25c98
Gitweb: https://git.kernel.org/tip/b99a26593b5190fac6b5c1f81a7f8cc128a25c98
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:09
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:37 +01:00

cpu/hotplug: Move bringup of secondary CPUs out of smp_init()

This is the last direct user of cpu_up() before it can become an internal
implementation detail of the cpu subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
include/linux/cpu.h | 1 +
kernel/cpu.c | 12 ++++++++++++
kernel/smp.c | 9 +--------
3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 9dc1e89..8b295f7 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -94,6 +94,7 @@ void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
int bringup_hibernate_cpu(unsigned int sleep_cpu);
+void bringup_nonboot_cpus(unsigned int setup_max_cpus);

#else /* CONFIG_SMP */
#define cpuhp_tasks_frozen 0
diff --git a/kernel/cpu.c b/kernel/cpu.c
index f803678..4783d81 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1298,6 +1298,18 @@ int bringup_hibernate_cpu(unsigned int sleep_cpu)
return 0;
}

+void bringup_nonboot_cpus(unsigned int setup_max_cpus)
+{
+ unsigned int cpu;
+
+ for_each_present_cpu(cpu) {
+ if (num_online_cpus() >= setup_max_cpus)
+ break;
+ if (!cpu_online(cpu))
+ cpu_up(cpu);
+ }
+}
+
#ifdef CONFIG_PM_SLEEP_SMP
static cpumask_var_t frozen_cpus;

diff --git a/kernel/smp.c b/kernel/smp.c
index 97f1d97..786092a 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -597,20 +597,13 @@ void __init setup_nr_cpu_ids(void)
void __init smp_init(void)
{
int num_nodes, num_cpus;
- unsigned int cpu;

idle_threads_init();
cpuhp_threads_init();

pr_info("Bringing up secondary CPUs ...\n");

- /* FIXME: This should be done in userspace --RR */
- for_each_present_cpu(cpu) {
- if (num_online_cpus() >= setup_max_cpus)
- break;
- if (!cpu_online(cpu))
- cpu_up(cpu);
- }
+ bringup_nonboot_cpus(setup_max_cpus);

num_nodes = num_online_nodes();
num_cpus = num_online_cpus();

Subject: [tip: smp/core] cpu/hotplug: Create a new function to shutdown nonboot cpus

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 0441a5597c5d02ed7abed1d989eaaa1595dedac5
Gitweb: https://git.kernel.org/tip/0441a5597c5d02ed7abed1d989eaaa1595dedac5
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:50:55
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:31 +01:00

cpu/hotplug: Create a new function to shutdown nonboot cpus

This function will be used later in machine_shutdown() for some
architectures.

disable_nonboot_cpus() is not safe to use when doing machine_down(),
because it relies on freeze_secondary_cpus() which in turn is a
suspend/resume related freeze and could abort if the logic detects any
pending activities that can prevent finishing the offlining process.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
include/linux/cpu.h | 2 ++
kernel/cpu.c | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index cf8cf38..64a246e 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -120,6 +120,7 @@ extern void cpu_hotplug_enable(void);
void clear_tasks_mm_cpumask(int cpu);
int cpu_down(unsigned int cpu);
int remove_cpu(unsigned int cpu);
+extern void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);

#else /* CONFIG_HOTPLUG_CPU */

@@ -131,6 +132,7 @@ static inline int cpus_read_trylock(void) { return true; }
static inline void lockdep_assert_cpus_held(void) { }
static inline void cpu_hotplug_disable(void) { }
static inline void cpu_hotplug_enable(void) { }
+static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { }
#endif /* !CONFIG_HOTPLUG_CPU */

/* Wrappers which go away once all code is converted */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 069802f..03c7271 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1069,6 +1069,48 @@ int remove_cpu(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(remove_cpu);

+void smp_shutdown_nonboot_cpus(unsigned int primary_cpu)
+{
+ unsigned int cpu;
+ int error;
+
+ cpu_maps_update_begin();
+
+ /*
+ * Make certain the cpu I'm about to reboot on is online.
+ *
+ * This is inline to what migrate_to_reboot_cpu() already do.
+ */
+ if (!cpu_online(primary_cpu))
+ primary_cpu = cpumask_first(cpu_online_mask);
+
+ for_each_online_cpu(cpu) {
+ if (cpu == primary_cpu)
+ continue;
+
+ error = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
+ if (error) {
+ pr_err("Failed to offline CPU%d - error=%d",
+ cpu, error);
+ break;
+ }
+ }
+
+ /*
+ * Ensure all but the reboot CPU are offline.
+ */
+ BUG_ON(num_online_cpus() > 1);
+
+ /*
+ * Make sure the CPUs won't be enabled by someone else after this
+ * point. Kexec will reboot to a new kernel shortly resetting
+ * everything along the way.
+ */
+ cpu_hotplug_disabled++;
+
+ cpu_maps_update_done();
+}
+
#else
#define takedown_cpu NULL
#endif /*CONFIG_HOTPLUG_CPU*/

Subject: [tip: smp/core] parisc: Replace cpu_up/down() with add/remove_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 02addaeaa7e5fa238963972d7030fa7ad57d9f1a
Gitweb: https://git.kernel.org/tip/02addaeaa7e5fa238963972d7030fa7ad57d9f1a
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:05
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:36 +01:00

parisc: Replace cpu_up/down() with add/remove_cpu()

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down().

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down() a private interface of the CPU
subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Helge Deller <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/parisc/kernel/processor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 13f771f..7f2d0c0 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -212,7 +212,7 @@ static int __init processor_probe(struct parisc_device *dev)
#ifdef CONFIG_SMP
if (cpuid) {
set_cpu_present(cpuid, true);
- cpu_up(cpuid);
+ add_cpu(cpuid);
}
#endif

Subject: [tip: smp/core] arm64: Don't use disable_nonboot_cpus()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: d66b16f5df4b41c719b98f7b5f61f0161e9e9246
Gitweb: https://git.kernel.org/tip/d66b16f5df4b41c719b98f7b5f61f0161e9e9246
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:50:59
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:33 +01:00

arm64: Don't use disable_nonboot_cpus()

disable_nonboot_cpus() is not safe to use when doing machine_down(),
because it relies on freeze_secondary_cpus() which in turn is
a suspend/resume related freeze and could abort if the logic detects any
pending activities that can prevent finishing the offlining process.

Beside disable_nonboot_cpus() is dependent on CONFIG_PM_SLEEP_SMP which
is an othogonal config to rely on to ensure this function works
correctly.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/arm64/kernel/process.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 0062605..1b9f7b7 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -141,11 +141,11 @@ void arch_cpu_idle_dead(void)
* to execute e.g. a RAM-based pin loop is not sufficient. This allows the
* kexec'd kernel to use any and all RAM as it sees fit, without having to
* avoid any code or data used by any SW CPU pin loop. The CPU hotplug
- * functionality embodied in disable_nonboot_cpus() to achieve this.
+ * functionality embodied in smpt_shutdown_nonboot_cpus() to achieve this.
*/
void machine_shutdown(void)
{
- disable_nonboot_cpus();
+ smp_shutdown_nonboot_cpus(0);
}

/*

Subject: [tip: smp/core] sparc: Replace cpu_up/down() with add/remove_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 7f6707a2040fecfae131752b5097c028885cc161
Gitweb: https://git.kernel.org/tip/7f6707a2040fecfae131752b5097c028885cc161
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:04
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:36 +01:00

sparc: Replace cpu_up/down() with add/remove_cpu()

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down().

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down() a private interface of the CPU
subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: David S. Miller <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/sparc/kernel/ds.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index bbf59b3..75232cb 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -555,7 +555,7 @@ static int dr_cpu_configure(struct ds_info *dp, struct ds_cap_state *cp,

printk(KERN_INFO "ds-%llu: Starting cpu %d...\n",
dp->id, cpu);
- err = cpu_up(cpu);
+ err = add_cpu(cpu);
if (err) {
__u32 res = DR_CPU_RES_FAILURE;
__u32 stat = DR_CPU_STAT_UNCONFIGURED;
@@ -611,7 +611,7 @@ static int dr_cpu_unconfigure(struct ds_info *dp,

printk(KERN_INFO "ds-%llu: Shutting down cpu %d...\n",
dp->id, cpu);
- err = cpu_down(cpu);
+ err = remove_cpu(cpu);
if (err)
dr_cpu_mark(resp, cpu, ncpus,
DR_CPU_RES_FAILURE,

Subject: [tip: smp/core] ia64: Replace cpu_down() with smp_shutdown_nonboot_cpus()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 1e42176b4dac328b0be7075c2cebdf2006d31eb3
Gitweb: https://git.kernel.org/tip/1e42176b4dac328b0be7075c2cebdf2006d31eb3
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:50:56
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:32 +01:00

ia64: Replace cpu_down() with smp_shutdown_nonboot_cpus()

Use the new smp_shutdown_nonboot_cpus() instead of using cpu_down()
directly.

Use reboot_cpu instead of hardcoding the boot CPU to 0.

This also prepares to make cpu_up/down() a private interface of the CPU
subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Fenghua Yu <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/ia64/kernel/process.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 968b5f3..bf4c0cd 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -646,14 +646,8 @@ cpu_halt (void)

void machine_shutdown(void)
{
-#ifdef CONFIG_HOTPLUG_CPU
- int cpu;
+ smp_shutdown_nonboot_cpus(reboot_cpu);

- for_each_online_cpu(cpu) {
- if (cpu != smp_processor_id())
- cpu_down(cpu);
- }
-#endif
#ifdef CONFIG_KEXEC
kexec_disable_iosapic();
#endif

Subject: [tip: smp/core] ARM: Use reboot_cpu instead of hardcoding it to 0

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 11ee270e3520129f977751e6174ebf8bf5f08a2f
Gitweb: https://git.kernel.org/tip/11ee270e3520129f977751e6174ebf8bf5f08a2f
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:50:58
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:33 +01:00

ARM: Use reboot_cpu instead of hardcoding it to 0

Use `reboot_cpu` variable instead of hardcoding 0 as the reboot cpu in
machine_shutdown().

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Russell King <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/arm/kernel/reboot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 58ad1a7..0ce388f 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -92,7 +92,7 @@ void soft_restart(unsigned long addr)
*/
void machine_shutdown(void)
{
- smp_shutdown_nonboot_cpus(0);
+ smp_shutdown_nonboot_cpus(reboot_cpu);
}

/*

Subject: [tip: smp/core] cpu/hotplug: Add new {add,remove}_cpu() functions

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 93ef1429e556f739a208e3968883ed51480580e8
Gitweb: https://git.kernel.org/tip/93ef1429e556f739a208e3968883ed51480580e8
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:50:54
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:31 +01:00

cpu/hotplug: Add new {add,remove}_cpu() functions

The new functions use device_{online,offline}() which are userspace safe.

This is in preparation to move cpu_{up, down} kernel users to use a safer
interface that is not racy with userspace.

Suggested-by: "Paul E. McKenney" <[email protected]>
Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Paul E. McKenney <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
include/linux/cpu.h | 2 ++
kernel/cpu.c | 24 ++++++++++++++++++++++++
2 files changed, 26 insertions(+)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 1ca2baf..cf8cf38 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -89,6 +89,7 @@ extern ssize_t arch_cpu_release(const char *, size_t);
#ifdef CONFIG_SMP
extern bool cpuhp_tasks_frozen;
int cpu_up(unsigned int cpu);
+int add_cpu(unsigned int cpu);
void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
@@ -118,6 +119,7 @@ extern void cpu_hotplug_disable(void);
extern void cpu_hotplug_enable(void);
void clear_tasks_mm_cpumask(int cpu);
int cpu_down(unsigned int cpu);
+int remove_cpu(unsigned int cpu);

#else /* CONFIG_HOTPLUG_CPU */

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 9c706af..069802f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1057,6 +1057,18 @@ int cpu_down(unsigned int cpu)
}
EXPORT_SYMBOL(cpu_down);

+int remove_cpu(unsigned int cpu)
+{
+ int ret;
+
+ lock_device_hotplug();
+ ret = device_offline(get_cpu_device(cpu));
+ unlock_device_hotplug();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(remove_cpu);
+
#else
#define takedown_cpu NULL
#endif /*CONFIG_HOTPLUG_CPU*/
@@ -1209,6 +1221,18 @@ int cpu_up(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(cpu_up);

+int add_cpu(unsigned int cpu)
+{
+ int ret;
+
+ lock_device_hotplug();
+ ret = device_online(get_cpu_device(cpu));
+ unlock_device_hotplug();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(add_cpu);
+
#ifdef CONFIG_PM_SLEEP_SMP
static cpumask_var_t frozen_cpus;

Subject: [tip: smp/core] ARM: Don't use disable_nonboot_cpus()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: dddf3578e0d497e66ebe654d0f3258ac20a07e27
Gitweb: https://git.kernel.org/tip/dddf3578e0d497e66ebe654d0f3258ac20a07e27
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:50:57
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:32 +01:00

ARM: Don't use disable_nonboot_cpus()

disable_nonboot_cpus() is not safe to use when doing machine_down(),
because it relies on freeze_secondary_cpus() which in turn is
a suspend/resume related freeze and could abort if the logic detects any
pending activities that can prevent finishing the offlining process.

Beside disable_nonboot_cpus() is dependent on CONFIG_PM_SLEEP_SMP which
is an othogonal config to rely on to ensure this function works
correctly.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Russell King <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/arm/kernel/reboot.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index bb18ed0..58ad1a7 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -88,11 +88,11 @@ void soft_restart(unsigned long addr)
* to execute e.g. a RAM-based pin loop is not sufficient. This allows the
* kexec'd kernel to use any and all RAM as it sees fit, without having to
* avoid any code or data used by any SW CPU pin loop. The CPU hotplug
- * functionality embodied in disable_nonboot_cpus() to achieve this.
+ * functionality embodied in smp_shutdown_nonboot_cpus() to achieve this.
*/
void machine_shutdown(void)
{
- disable_nonboot_cpus();
+ smp_shutdown_nonboot_cpus(0);
}

/*

Subject: [tip: smp/core] arm64: Use reboot_cpu instead of hardconding it to 0

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 5efbe6a6e1c077b4022d9e89d79543c6106c6e25
Gitweb: https://git.kernel.org/tip/5efbe6a6e1c077b4022d9e89d79543c6106c6e25
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:00
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:33 +01:00

arm64: Use reboot_cpu instead of hardconding it to 0

Use `reboot_cpu` variable instead of hardcoding 0 as the reboot cpu in
machine_shutdown().

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/arm64/kernel/process.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 1b9f7b7..3e5a6ad 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -145,7 +145,7 @@ void arch_cpu_idle_dead(void)
*/
void machine_shutdown(void)
{
- smp_shutdown_nonboot_cpus(0);
+ smp_shutdown_nonboot_cpus(reboot_cpu);
}

/*

Subject: [tip: smp/core] cpu/hotplug: Provide bringup_hibernate_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: d720f98604391dab6aa3cb4c1bc005ed1aba4703
Gitweb: https://git.kernel.org/tip/d720f98604391dab6aa3cb4c1bc005ed1aba4703
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:01
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:34 +01:00

cpu/hotplug: Provide bringup_hibernate_cpu()

arm64 uses cpu_up() in the resume from hibernation code to ensure that the
CPU on which the system hibernated is online. Provide a core function for
this.

[ tglx: Split out from the combo arm64 patch ]

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
include/linux/cpu.h | 1 +
kernel/cpu.c | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 64a246e..9dc1e89 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -93,6 +93,7 @@ int add_cpu(unsigned int cpu);
void notify_cpu_starting(unsigned int cpu);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
+int bringup_hibernate_cpu(unsigned int sleep_cpu);

#else /* CONFIG_SMP */
#define cpuhp_tasks_frozen 0
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 03c7271..f803678 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1275,6 +1275,29 @@ int add_cpu(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(add_cpu);

+/**
+ * bringup_hibernate_cpu - Bring up the CPU that we hibernated on
+ * @sleep_cpu: The cpu we hibernated on and should be brought up.
+ *
+ * On some architectures like arm64, we can hibernate on any CPU, but on
+ * wake up the CPU we hibernated on might be offline as a side effect of
+ * using maxcpus= for example.
+ */
+int bringup_hibernate_cpu(unsigned int sleep_cpu)
+{
+ int ret;
+
+ if (!cpu_online(sleep_cpu)) {
+ pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
+ ret = cpu_up(sleep_cpu);
+ if (ret) {
+ pr_err("Failed to bring hibernate-CPU up!\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
#ifdef CONFIG_PM_SLEEP_SMP
static cpumask_var_t frozen_cpus;

Subject: [tip: smp/core] powerpc: Replace cpu_up/down() with add/remove_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 4d37cc2dc3dfffb782663c46cc0ee2c483e2f2ba
Gitweb: https://git.kernel.org/tip/4d37cc2dc3dfffb782663c46cc0ee2c483e2f2ba
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:03
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:35 +01:00

powerpc: Replace cpu_up/down() with add/remove_cpu()

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down.

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down() a private interface of the CPU
subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Michael Ellerman <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/powerpc/kexec/core_64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 04a7cba..b418409 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -212,7 +212,7 @@ static void wake_offline_cpus(void)
if (!cpu_online(cpu)) {
printk(KERN_INFO "kexec: Waking offline cpu %d.\n",
cpu);
- WARN_ON(cpu_up(cpu));
+ WARN_ON(add_cpu(cpu));
}
}
}

Subject: [tip: smp/core] xen/cpuhotplug: Replace cpu_up/down() with device_online/offline()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: a926f81d2f6c51458e116c5b3ff3af471b56098f
Gitweb: https://git.kernel.org/tip/a926f81d2f6c51458e116c5b3ff3af471b56098f
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:06
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:36 +01:00

xen/cpuhotplug: Replace cpu_up/down() with device_online/offline()

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down().

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down() a private interface of the cpu
subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Juergen Gross <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
drivers/xen/cpu_hotplug.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index f192b6f..ec975de 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -94,7 +94,7 @@ static int setup_cpu_watcher(struct notifier_block *notifier,

for_each_possible_cpu(cpu) {
if (vcpu_online(cpu) == 0) {
- (void)cpu_down(cpu);
+ device_offline(get_cpu_device(cpu));
set_cpu_present(cpu, false);
}
}

Subject: [tip: smp/core] x86/smp: Replace cpu_up/down() with add/remove_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: af7aa04683e85ccb9088e31fe67a0397167b7abd
Gitweb: https://git.kernel.org/tip/af7aa04683e85ccb9088e31fe67a0397167b7abd
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:02
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:35 +01:00

x86/smp: Replace cpu_up/down() with add/remove_cpu()

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down().

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down() a private interface of the CPU
subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/x86/kernel/topology.c | 22 ++++++----------------
arch/x86/mm/mmio-mod.c | 4 ++--
arch/x86/xen/smp.c | 2 +-
3 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index be5bc2e..b8810eb 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -59,39 +59,29 @@ __setup("cpu0_hotplug", enable_cpu0_hotplug);
*/
int _debug_hotplug_cpu(int cpu, int action)
{
- struct device *dev = get_cpu_device(cpu);
int ret;

if (!cpu_is_hotpluggable(cpu))
return -EINVAL;

- lock_device_hotplug();
-
switch (action) {
case 0:
- ret = cpu_down(cpu);
- if (!ret) {
+ ret = remove_cpu(cpu);
+ if (!ret)
pr_info("DEBUG_HOTPLUG_CPU0: CPU %u is now offline\n", cpu);
- dev->offline = true;
- kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
- } else
+ else
pr_debug("Can't offline CPU%d.\n", cpu);
break;
case 1:
- ret = cpu_up(cpu);
- if (!ret) {
- dev->offline = false;
- kobject_uevent(&dev->kobj, KOBJ_ONLINE);
- } else {
+ ret = add_cpu(cpu);
+ if (ret)
pr_debug("Can't online CPU%d.\n", cpu);
- }
+
break;
default:
ret = -EINVAL;
}

- unlock_device_hotplug();
-
return ret;
}

diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 673de60..109325d 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -386,7 +386,7 @@ static void enter_uniprocessor(void)
put_online_cpus();

for_each_cpu(cpu, downed_cpus) {
- err = cpu_down(cpu);
+ err = remove_cpu(cpu);
if (!err)
pr_info("CPU%d is down.\n", cpu);
else
@@ -406,7 +406,7 @@ static void leave_uniprocessor(void)
return;
pr_notice("Re-enabling CPUs...\n");
for_each_cpu(cpu, downed_cpus) {
- err = cpu_up(cpu);
+ err = add_cpu(cpu);
if (!err)
pr_info("enabled CPU%d.\n", cpu);
else
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 7a43b2a..2097fa0 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -132,7 +132,7 @@ void __init xen_smp_cpus_done(unsigned int max_cpus)
if (xen_vcpu_nr(cpu) < MAX_VIRT_CPUS)
continue;

- rc = cpu_down(cpu);
+ rc = remove_cpu(cpu);

if (rc == 0) {
/*

Subject: [tip: smp/core] torture: Replace cpu_up/down() with add/remove_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 457bc8ed3ec7edc567200302d9312ac8bbc31316
Gitweb: https://git.kernel.org/tip/457bc8ed3ec7edc567200302d9312ac8bbc31316
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:08
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:37 +01:00

torture: Replace cpu_up/down() with add/remove_cpu()

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down().

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down() a private interface of the CPU
subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: "Paul E. McKenney" <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
kernel/torture.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/kernel/torture.c b/kernel/torture.c
index 7c13f55..a479689 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -97,7 +97,7 @@ bool torture_offline(int cpu, long *n_offl_attempts, long *n_offl_successes,
torture_type, cpu);
starttime = jiffies;
(*n_offl_attempts)++;
- ret = cpu_down(cpu);
+ ret = remove_cpu(cpu);
if (ret) {
if (verbose)
pr_alert("%s" TORTURE_FLAG
@@ -148,7 +148,7 @@ bool torture_online(int cpu, long *n_onl_attempts, long *n_onl_successes,
torture_type, cpu);
starttime = jiffies;
(*n_onl_attempts)++;
- ret = cpu_up(cpu);
+ ret = add_cpu(cpu);
if (ret) {
if (verbose)
pr_alert("%s" TORTURE_FLAG
@@ -192,17 +192,18 @@ torture_onoff(void *arg)
for_each_online_cpu(cpu)
maxcpu = cpu;
WARN_ON(maxcpu < 0);
- if (!IS_MODULE(CONFIG_TORTURE_TEST))
+ if (!IS_MODULE(CONFIG_TORTURE_TEST)) {
for_each_possible_cpu(cpu) {
if (cpu_online(cpu))
continue;
- ret = cpu_up(cpu);
+ ret = add_cpu(cpu);
if (ret && verbose) {
pr_alert("%s" TORTURE_FLAG
"%s: Initial online %d: errno %d\n",
__func__, torture_type, cpu, ret);
}
}
+ }

if (maxcpu == 0) {
VERBOSE_TOROUT_STRING("Only one CPU, so CPU-hotplug testing is disabled");

Subject: [tip: smp/core] arm64: hibernate: Use bringup_hibernate_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: e646ac5bb88d9480eeb3b0d31d2e3eed056c2638
Gitweb: https://git.kernel.org/tip/e646ac5bb88d9480eeb3b0d31d2e3eed056c2638
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:01
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:34 +01:00

arm64: hibernate: Use bringup_hibernate_cpu()

Use bringup_hibernate_cpu() instead of open coding it.

[ tglx: Split out the core change ]

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/arm64/kernel/hibernate.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 590963c..5b73e92 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -166,14 +166,11 @@ int arch_hibernation_header_restore(void *addr)
sleep_cpu = -EINVAL;
return -EINVAL;
}
- if (!cpu_online(sleep_cpu)) {
- pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
- ret = cpu_up(sleep_cpu);
- if (ret) {
- pr_err("Failed to bring hibernate-CPU up!\n");
- sleep_cpu = -EINVAL;
- return ret;
- }
+
+ ret = bringup_hibernate_cpu(sleep_cpu);
+ if (ret) {
+ sleep_cpu = -EINVAL;
+ return ret;
}

resume_hdr = *hdr;

Subject: [tip: smp/core] firmware: psci: Replace cpu_up/down() with add/remove_cpu()

The following commit has been merged into the smp/core branch of tip:

Commit-ID: 20fb50295b139494754964d7d005b5a2f465ef08
Gitweb: https://git.kernel.org/tip/20fb50295b139494754964d7d005b5a2f465ef08
Author: Qais Yousef <[email protected]>
AuthorDate: Mon, 23 Mar 2020 13:51:07
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 25 Mar 2020 12:59:37 +01:00

firmware: psci: Replace cpu_up/down() with add/remove_cpu()

The core device API performs extra housekeeping bits that are missing
from directly calling cpu_up/down().

See commit a6717c01ddc2 ("powerpc/rtas: use device model APIs and
serialization during LPM") for an example description of what might go
wrong.

This also prepares to make cpu_up/down a private interface of the CPU subsystem.

Signed-off-by: Qais Yousef <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
drivers/firmware/psci/psci_checker.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
index 6a44539..873841a 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -84,7 +84,7 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,

/* Try to power down all CPUs in the mask. */
for_each_cpu(cpu, cpus) {
- int ret = cpu_down(cpu);
+ int ret = remove_cpu(cpu);

/*
* cpu_down() checks the number of online CPUs before the TOS
@@ -116,7 +116,7 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,

/* Try to power up all the CPUs that have been offlined. */
for_each_cpu(cpu, offlined_cpus) {
- int ret = cpu_up(cpu);
+ int ret = add_cpu(cpu);

if (ret != 0) {
pr_err("Error occurred (%d) while trying "