All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY
@ 2022-03-25 14:38 Helge Deller
  2022-03-25 14:38 ` [PATCH 02/12] parisc: Add __cpuinit section for HOTPLUG_CPU Helge Deller
                   ` (12 more replies)
  0 siblings, 13 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Switch away from the own cpu topology code to common code which is used
by ARM64 and RISCV. That allows us to enable hotplug later on too.

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/Kconfig                |  2 +-
 arch/parisc/include/asm/topology.h | 20 +--------
 arch/parisc/kernel/processor.c     |  2 +
 arch/parisc/kernel/topology.c      | 72 +++++++-----------------------
 4 files changed, 19 insertions(+), 77 deletions(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 00cb889bd9a6..6bd42c82a019 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -37,7 +37,7 @@ config PARISC
 	select GENERIC_PCI_IOMAP
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
-	select GENERIC_CPU_DEVICES
+	select GENERIC_ARCH_TOPOLOGY
 	select GENERIC_LIB_DEVMEM_IS_ALLOWED
 	select SYSCTL_ARCH_UNALIGN_ALLOW
 	select SYSCTL_EXCEPTION_TRACE
diff --git a/arch/parisc/include/asm/topology.h b/arch/parisc/include/asm/topology.h
index 6f0750c74e47..734eddf096f7 100644
--- a/arch/parisc/include/asm/topology.h
+++ b/arch/parisc/include/asm/topology.h
@@ -4,25 +4,7 @@
 #ifdef CONFIG_PARISC_CPU_TOPOLOGY

 #include <linux/cpumask.h>
-
-struct cputopo_parisc {
-	int thread_id;
-	int core_id;
-	int socket_id;
-	cpumask_t thread_sibling;
-	cpumask_t core_sibling;
-};
-
-extern struct cputopo_parisc cpu_topology[NR_CPUS];
-
-#define topology_physical_package_id(cpu)	(cpu_topology[cpu].socket_id)
-#define topology_core_id(cpu)		(cpu_topology[cpu].core_id)
-#define topology_core_cpumask(cpu)	(&cpu_topology[cpu].core_sibling)
-#define topology_sibling_cpumask(cpu)	(&cpu_topology[cpu].thread_sibling)
-
-void init_cpu_topology(void);
-void store_cpu_topology(unsigned int cpuid);
-const struct cpumask *cpu_coregroup_mask(int cpu);
+#include <linux/arch_topology.h>

 #else

diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index ccaf075d0750..d0bfd61a4623 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -19,6 +19,7 @@
 #include <linux/random.h>
 #include <linux/slab.h>
 #include <linux/cpu.h>
+#include <asm/topology.h>
 #include <asm/param.h>
 #include <asm/cache.h>
 #include <asm/hardware.h>	/* for register_parisc_driver() stuff */
@@ -459,5 +460,6 @@ static struct parisc_driver cpu_driver __refdata = {
  */
 void __init processor_init(void)
 {
+	reset_cpu_topology();
 	register_parisc_driver(&cpu_driver);
 }
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
index e88a6ce7c96d..72d9aeb54fbe 100644
--- a/arch/parisc/kernel/topology.c
+++ b/arch/parisc/kernel/topology.c
@@ -13,45 +13,11 @@
 #include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/sched/topology.h>
+#include <linux/cpu.h>

 #include <asm/topology.h>

- /*
-  * cpu topology table
-  */
-struct cputopo_parisc cpu_topology[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL_GPL(cpu_topology);
-
-const struct cpumask *cpu_coregroup_mask(int cpu)
-{
-	return &cpu_topology[cpu].core_sibling;
-}
-
-static void update_siblings_masks(unsigned int cpuid)
-{
-	struct cputopo_parisc *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
-	int cpu;
-
-	/* update core and thread sibling masks */
-	for_each_possible_cpu(cpu) {
-		cpu_topo = &cpu_topology[cpu];
-
-		if (cpuid_topo->socket_id != cpu_topo->socket_id)
-			continue;
-
-		cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
-		if (cpu != cpuid)
-			cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
-
-		if (cpuid_topo->core_id != cpu_topo->core_id)
-			continue;
-
-		cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
-		if (cpu != cpuid)
-			cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
-	}
-	smp_wmb();
-}
+static DEFINE_PER_CPU(struct cpu, cpu_devices);

 static int dualcores_found __initdata;

@@ -62,7 +28,7 @@ static int dualcores_found __initdata;
  */
 void __init store_cpu_topology(unsigned int cpuid)
 {
-	struct cputopo_parisc *cpuid_topo = &cpu_topology[cpuid];
+	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
 	struct cpuinfo_parisc *p;
 	int max_socket = -1;
 	unsigned long cpu;
@@ -71,6 +37,12 @@ void __init store_cpu_topology(unsigned int cpuid)
 	if (cpuid_topo->core_id != -1)
 		return;

+#ifdef CONFIG_HOTPLUG_CPU
+	per_cpu(cpu_devices, cpuid).hotpluggable = 1;
+#endif
+	if (register_cpu(&per_cpu(cpu_devices, cpuid), cpuid))
+		printk("Failed to register CPU device");
+
 	/* create cpu topology mapping */
 	cpuid_topo->thread_id = -1;
 	cpuid_topo->core_id = 0;
@@ -86,25 +58,25 @@ void __init store_cpu_topology(unsigned int cpuid)
 			cpuid_topo->core_id = cpu_topology[cpu].core_id;
 			if (p->cpu_loc) {
 				cpuid_topo->core_id++;
-				cpuid_topo->socket_id = cpu_topology[cpu].socket_id;
+				cpuid_topo->package_id = cpu_topology[cpu].package_id;
 				dualcores_found = 1;
 				continue;
 			}
 		}

-		if (cpuid_topo->socket_id == -1)
-			max_socket = max(max_socket, cpu_topology[cpu].socket_id);
+		if (cpuid_topo->package_id == -1)
+			max_socket = max(max_socket, cpu_topology[cpu].package_id);
 	}

-	if (cpuid_topo->socket_id == -1)
-		cpuid_topo->socket_id = max_socket + 1;
+	if (cpuid_topo->package_id == -1)
+		cpuid_topo->package_id = max_socket + 1;

 	update_siblings_masks(cpuid);

 	pr_info("CPU%u: cpu core %d of socket %d\n",
 		cpuid,
 		cpu_topology[cpuid].core_id,
-		cpu_topology[cpuid].socket_id);
+		cpu_topology[cpuid].package_id);
 }

 static struct sched_domain_topology_level parisc_mc_topology[] = {
@@ -122,20 +94,6 @@ static struct sched_domain_topology_level parisc_mc_topology[] = {
  */
 void __init init_cpu_topology(void)
 {
-	unsigned int cpu;
-
-	/* init core mask and capacity */
-	for_each_possible_cpu(cpu) {
-		struct cputopo_parisc *cpu_topo = &(cpu_topology[cpu]);
-
-		cpu_topo->thread_id = -1;
-		cpu_topo->core_id =  -1;
-		cpu_topo->socket_id = -1;
-		cpumask_clear(&cpu_topo->core_sibling);
-		cpumask_clear(&cpu_topo->thread_sibling);
-	}
-	smp_wmb();
-
 	/* Set scheduler topology descriptor */
 	if (dualcores_found)
 		set_sched_topology(parisc_mc_topology);
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 02/12] parisc: Add __cpuinit section for HOTPLUG_CPU
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 14:38 ` [PATCH 03/12] parisc: Move store_cpu_topology() into __cpuinit section Helge Deller
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Provide a __cpuinit section which needs to be used instead of __init
when CPU hotplugging is enabled.

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/include/asm/sections.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h
index bb52aea0cb21..4c28c7adaf5f 100644
--- a/arch/parisc/include/asm/sections.h
+++ b/arch/parisc/include/asm/sections.h
@@ -7,6 +7,12 @@

 extern char __alt_instructions[], __alt_instructions_end[];

+#ifdef CONFIG_HOTPLUG_CPU
+#define __cpuinit
+#else
+#define __cpuinit	__init
+#endif
+
 #ifdef CONFIG_64BIT

 #define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 03/12] parisc: Move store_cpu_topology() into __cpuinit section
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
  2022-03-25 14:38 ` [PATCH 02/12] parisc: Add __cpuinit section for HOTPLUG_CPU Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 16:52   ` Rolf Eike Beer
  2022-03-25 14:38 ` [PATCH 04/12] parisc: Move start_cpu_itimer() " Helge Deller
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/topology.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
index 72d9aeb54fbe..dc766fb55491 100644
--- a/arch/parisc/kernel/topology.c
+++ b/arch/parisc/kernel/topology.c
@@ -16,17 +16,18 @@
 #include <linux/cpu.h>

 #include <asm/topology.h>
+#include <asm/sections.h>

 static DEFINE_PER_CPU(struct cpu, cpu_devices);

-static int dualcores_found __initdata;
+static int dualcores_found;

 /*
  * store_cpu_topology is called at boot when only one cpu is running
  * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
  * which prevents simultaneous write access to cpu_topology array
  */
-void __init store_cpu_topology(unsigned int cpuid)
+void __cpuinit store_cpu_topology(unsigned int cpuid)
 {
 	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
 	struct cpuinfo_parisc *p;
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 04/12] parisc: Move start_cpu_itimer() into __cpuinit section
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
  2022-03-25 14:38 ` [PATCH 02/12] parisc: Add __cpuinit section for HOTPLUG_CPU Helge Deller
  2022-03-25 14:38 ` [PATCH 03/12] parisc: Move store_cpu_topology() into __cpuinit section Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 16:53   ` Rolf Eike Beer
  2022-03-25 14:38 ` [PATCH 05/12] parisc: Move init_per_cpu() init " Helge Deller
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/time.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 061119a56fbe..4101392bf74d 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -150,7 +150,7 @@ static struct clocksource clocksource_cr16 = {
 	.flags			= CLOCK_SOURCE_IS_CONTINUOUS,
 };

-void __init start_cpu_itimer(void)
+void __cpuinit start_cpu_itimer(void)
 {
 	unsigned int cpu = smp_processor_id();
 	unsigned long next_tick = mfctl(16) + clocktick;
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 05/12] parisc: Move init_per_cpu() init __cpuinit section
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (2 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 04/12] parisc: Move start_cpu_itimer() " Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 14:38 ` [PATCH 06/12] parisc: Move disable_sr_hashing_asm() into " Helge Deller
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/processor.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index d0bfd61a4623..89284e79c159 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -29,6 +29,7 @@
 #include <asm/pdcpat.h>
 #include <asm/irq.h>		/* for struct irq_region */
 #include <asm/parisc-device.h>
+#include <asm/sections.h>

 struct system_cpuinfo_parisc boot_cpu_data __ro_after_init;
 EXPORT_SYMBOL(boot_cpu_data);
@@ -317,7 +318,7 @@ void __init collect_boot_cpu_data(void)
  *
  * o Enable CPU profiling hooks.
  */
-int __init init_per_cpu(int cpunum)
+int __cpuinit init_per_cpu(int cpunum)
 {
 	int ret;
 	struct pdc_coproc_cfg coproc_cfg;
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 06/12] parisc: Move disable_sr_hashing_asm() into __cpuinit section
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (3 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 05/12] parisc: Move init_per_cpu() init " Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 14:38 ` [PATCH 07/12] parisc: Move disable_sr_hashing() " Helge Deller
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/pacache.S | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index b2ba6d633065..661b1834ac94 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -1264,7 +1264,11 @@ ENTRY_CFI(flush_kernel_icache_range_asm)
 	nop
 ENDPROC_CFI(flush_kernel_icache_range_asm)

+#ifdef CONFIG_HOTPLUG_CPU
+	.text
+#else
 	__INIT
+#endif

 	/* align should cover use of rfi in disable_sr_hashing_asm and
 	 * srdis_done.
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 07/12] parisc: Move disable_sr_hashing() into __cpuinit section
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (4 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 06/12] parisc: Move disable_sr_hashing_asm() into " Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 14:38 ` [PATCH 08/12] parisc: Move init_IRQ() " Helge Deller
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 456e879d34a8..6be03d3a2382 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -273,7 +273,7 @@ parisc_cache_init(void)
 	}
 }

-void __init disable_sr_hashing(void)
+void __cpuinit disable_sr_hashing(void)
 {
 	int srhash_type, retval;
 	unsigned long space_bits;
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 08/12] parisc: Move init_IRQ() into __cpuinit section
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (5 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 07/12] parisc: Move disable_sr_hashing() " Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 14:38 ` [PATCH 09/12] parisc: Ensure set_firmware_width() is called only once Helge Deller
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index eb18e16362f6..a8372db32492 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -582,7 +582,7 @@ static void claim_cpu_irqs(void)
 #endif
 }

-void __init init_IRQ(void)
+void __cpuinit init_IRQ(void)
 {
 	local_irq_disable();	/* PARANOID - should already be disabled */
 	mtctl(~0UL, 23);	/* EIRR : clear all pending external intr */
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 09/12] parisc: Ensure set_firmware_width() is called only once
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (6 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 08/12] parisc: Move init_IRQ() " Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-26  8:58   ` Rolf Eike Beer
  2022-03-25 14:38 ` [PATCH 10/12] parisc: Move common_stext into text section when CONFIG_HOTPLUG_CPU=y Helge Deller
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Make sure, that set_firmware_width() is only called once at
runtime. This prevents that if secondary CPUs are started later
get stuck in spinlocks.

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/firmware.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 3370e347dde3..c6b11bdb8602 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -83,7 +83,7 @@ extern unsigned long pdc_result2[NUM_PDC_RESULT];

 /* Firmware needs to be initially set to narrow to determine the
  * actual firmware width. */
-int parisc_narrow_firmware __ro_after_init = 1;
+int parisc_narrow_firmware __ro_after_init = 2;
 #endif

 /* On most currently-supported platforms, IODC I/O calls are 32-bit calls
@@ -174,6 +174,11 @@ void set_firmware_width_unlocked(void)
 void set_firmware_width(void)
 {
 	unsigned long flags;
+
+	/* already initialized? */
+	if (parisc_narrow_firmware != 2)
+		return;
+
 	spin_lock_irqsave(&pdc_lock, flags);
 	set_firmware_width_unlocked();
 	spin_unlock_irqrestore(&pdc_lock, flags);
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 10/12] parisc: Move common_stext into text section when CONFIG_HOTPLUG_CPU=y
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (7 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 09/12] parisc: Ensure set_firmware_width() is called only once Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 14:38 ` [PATCH 11/12] parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging Helge Deller
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Move the common_stext function into the non-init text section if hotplug
is enabled. This function is called from the firmware when secondary
CPUS are brought up when CPU hotplug is enabled.

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/head.S | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index b24f77748c22..e0a9e9657622 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -162,6 +162,15 @@ $pgt_fill_loop:
 	/* FALLTHROUGH */
 	.procend

+#ifdef CONFIG_HOTPLUG_CPU
+	/* common_stext is far away in another section... jump there */
+	load32		PA(common_stext), %rp
+	bv,n		(%rp)
+
+	/* common_stext and smp_slave_stext needs to be in text section */
+	.text
+#endif
+
 	/*
 	** Code Common to both Monarch and Slave processors.
 	** Entry:
@@ -371,8 +380,6 @@ smp_slave_stext:
 	.procend
 #endif /* CONFIG_SMP */

-ENDPROC(parisc_kernel_start)
-
 #ifndef CONFIG_64BIT
 	.section .data..ro_after_init

--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 11/12] parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (8 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 10/12] parisc: Move common_stext into text section when CONFIG_HOTPLUG_CPU=y Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 16:56   ` Rolf Eike Beer
  2022-03-25 14:38 ` [PATCH 12/12] parisc: Implement __cpu_die() and __cpu_disable() " Helge Deller
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Let the PDC firmware put the CPU into firmware idle loop with
pdc_cpu_rendezvous() function.

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/kernel/process.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index ea3d83b6fb62..44fa89fbb280 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -38,6 +38,7 @@
 #include <linux/rcupdate.h>
 #include <linux/random.h>
 #include <linux/nmi.h>
+#include <linux/sched/hotplug.h>

 #include <asm/io.h>
 #include <asm/asm-offsets.h>
@@ -46,6 +47,7 @@
 #include <asm/pdc_chassis.h>
 #include <asm/unwind.h>
 #include <asm/sections.h>
+#include <asm/cacheflush.h>

 #define COMMAND_GLOBAL  F_EXTEND(0xfffe0030)
 #define CMD_RESET       5       /* reset any module */
@@ -158,10 +160,35 @@ void release_thread(struct task_struct *dead_task)
 int running_on_qemu __ro_after_init;
 EXPORT_SYMBOL(running_on_qemu);

-void __cpuidle arch_cpu_idle_dead(void)
+/*
+ * Called from the idle thread for the CPU which has been shutdown.
+ */
+void arch_cpu_idle_dead(void)
 {
-	/* nop on real hardware, qemu will offline CPU. */
-	asm volatile("or %%r31,%%r31,%%r31\n":::);
+#ifdef CONFIG_HOTPLUG_CPU
+	idle_task_exit();
+
+	local_irq_disable();
+
+	/*
+	 * Tell __cpu_die() that this CPU is now safe to dispose of.
+	 */
+	(void)cpu_report_death();
+
+	/*
+	 * Ensure that the cache lines are written out.
+	 */
+	flush_cache_all_local();
+	flush_tlb_all_local(NULL);
+
+	/*
+	 * Let PDC firmware put CPU into firmware idle loop.
+	 */
+	__pdc_cpu_rendezvous();
+
+	pr_warn("PDC does not provide rendezvous function.\n");
+#endif
+	while (1);
 }

 void __cpuidle arch_cpu_idle(void)
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 12/12] parisc: Implement __cpu_die() and __cpu_disable() for CPU hotplugging
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (9 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 11/12] parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging Helge Deller
@ 2022-03-25 14:38 ` Helge Deller
  2022-03-25 17:10   ` Rolf Eike Beer
  2022-03-25 14:53 ` [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
  2022-03-25 16:46 ` Rolf Eike Beer
  12 siblings, 1 reply; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:38 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin

Add relevant code to __cpu_die() and __cpu_disable() to finally enable
the CPU hotplugging features. Reset the irq count values in smp_callin()
to zero before bringing up the CPU.

Use "chcpu -d 1" to bring CPU1 down, and "chcpu -e 1" to bring it up.

Signed-off-by: Helge Deller <deller@gmx.de>
---
 arch/parisc/Kconfig           |  1 +
 arch/parisc/include/asm/smp.h |  9 +---
 arch/parisc/kernel/smp.c      | 80 +++++++++++++++++++++++++++++++++--
 3 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 6bd42c82a019..ec5bb9626d06 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -56,6 +56,7 @@ config PARISC
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select GENERIC_SCHED_CLOCK
+	select GENERIC_IRQ_MIGRATION
 	select HAVE_UNSTABLE_SCHED_CLOCK if SMP
 	select LEGACY_TIMER_TICK
 	select CPU_NO_EFFICIENT_FFS
diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h
index 2279ebe5e2da..94d1f21ce99a 100644
--- a/arch/parisc/include/asm/smp.h
+++ b/arch/parisc/include/asm/smp.h
@@ -44,12 +44,7 @@ static inline void smp_send_all_nop(void) { return; }

 #define NO_PROC_ID		0xFF		/* No processor magic marker */
 #define ANY_PROC_ID		0xFF		/* Any processor magic marker */
-static inline int __cpu_disable (void) {
-  return 0;
-}
-static inline void __cpu_die (unsigned int cpu) {
-  while(1)
-    ;
-}
+int __cpu_disable(void);
+void __cpu_die(unsigned int cpu);

 #endif /*  __ASM_SMP_H */
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index a32a882a2d58..60cc33fd345c 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -30,6 +30,7 @@
 #include <linux/ftrace.h>
 #include <linux/cpu.h>
 #include <linux/kgdb.h>
+#include <linux/sched/hotplug.h>

 #include <linux/atomic.h>
 #include <asm/current.h>
@@ -309,7 +310,7 @@ smp_cpu_init(int cpunum)
  * Slaves start using C here. Indirectly called from smp_slave_stext.
  * Do what start_kernel() and main() do for boot strap processor (aka monarch)
  */
-void __init smp_callin(unsigned long pdce_proc)
+void __cpuinit smp_callin(unsigned long pdce_proc)
 {
 	int slave_id = cpu_now_booting;

@@ -339,6 +340,19 @@ int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
 	const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
 	long timeout;

+#ifdef CONFIG_HOTPLUG_CPU
+	int i;
+
+	/* reset irq statistics for this CPU */
+	memset(&per_cpu(irq_stat, cpuid), 0, sizeof(irq_cpustat_t));
+	for (i = 0; i < NR_IRQS; i++) {
+		struct irq_desc *desc = irq_to_desc(i);
+
+		if (desc && desc->kstat_irqs)
+			*per_cpu_ptr(desc->kstat_irqs, cpuid) = 0;
+	}
+#endif
+
 	/* Let _start know what logical CPU we're booting
 	** (offset into init_tasks[],cpu_data[])
 	*/
@@ -430,10 +444,68 @@ void smp_cpus_done(unsigned int cpu_max)

 int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	if (cpu != 0 && cpu < parisc_max_cpus && smp_boot_one_cpu(cpu, tidle))
-		return -ENOSYS;
+	if (cpu_online(cpu))
+		return 0;
+
+	if (num_online_cpus() < parisc_max_cpus && smp_boot_one_cpu(cpu, tidle))
+		return -EIO;
+
+	return cpu_online(cpu) ? 0 : -EIO;
+}
+
+/*
+ * __cpu_disable runs on the processor to be shutdown.
+ */
+int __cpu_disable(void)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+	unsigned int cpu = smp_processor_id();
+
+	remove_cpu_topology(cpu);
+
+	/*
+	 * Take this CPU offline.  Once we clear this, we can't return,
+	 * and we must not schedule until we're ready to give up the cpu.
+	 */
+	set_cpu_online(cpu, false);
+
+	/*
+	 * disable IPI interrupt
+	 */
+	disable_percpu_irq(IPI_IRQ);
+
+	/*
+	 * migrate IRQs away from this CPU
+	 */
+	irq_migrate_all_off_this_cpu();
+
+	/*
+	 * Flush user cache and TLB mappings, and then remove this CPU
+	 * from the vm mask set of all processes.
+	 *
+	 * Caches are flushed to the Level of Unification Inner Shareable
+	 * to write-back dirty lines to unified caches shared by all CPUs.
+	 */
+	flush_cache_all_local();
+	flush_tlb_all_local(NULL);

-	return cpu_online(cpu) ? 0 : -ENOSYS;
+	/* disable all irqs, including timer irq */
+	local_irq_disable();
+#endif
+	return 0;
+}
+
+/*
+ * called on the thread which is asking for a CPU to be shutdown -
+ * waits until shutdown has completed, or it is timed out.
+ */
+void __cpu_die(unsigned int cpu)
+{
+	if (!cpu_wait_death(cpu, 5)) {
+		pr_crit("CPU%u: cpu didn't die\n", cpu);
+		return;
+	}
+	pr_debug("CPU%u: shutdown\n", cpu);
 }

 #ifdef CONFIG_PROC_FS
--
2.35.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (10 preceding siblings ...)
  2022-03-25 14:38 ` [PATCH 12/12] parisc: Implement __cpu_die() and __cpu_disable() " Helge Deller
@ 2022-03-25 14:53 ` Helge Deller
  2022-03-25 16:46 ` Rolf Eike Beer
  12 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 14:53 UTC (permalink / raw)
  To: linux-parisc; +Cc: James Bottomley, John David Anglin, Sven Schnelle

On 3/25/22 15:38, Helge Deller wrote:
> Switch away from the own cpu topology code to common code which is used
> by ARM64 and RISCV. That allows us to enable hotplug later on too.

With this series I was able to use CPU hotplugging on the PA-RISC machines.
I sucessfully tested it on qemu (32bit kernel) and on a 2-way C8000 (64bit kernel).

For qemu the patch I committed today is required:
https://github.com/hdeller/seabios-hppa/commit/5cec13f11d3917cf3bceaf68ce23e9fa5f206a35

There is still some issue with the irq balancing on qemu with the emulated GSC, e.g. in this
example with 3 CPUs you can only disable CPU0 or CPU2, which both don't use any IRQs.
During shutdown of CPU1 the irqs 17-20 needs to be moved to another CPU which doesn't
work reliable yet.

Example:

root@debian:~# cat /proc/interrupts
           CPU0       CPU1       CPU2
 17:          0          0          0        GSC-ASIC  parport0
 18:          0       1759          0         GSC-PCI  ttyS0
 19:          0       3572          0         GSC-PCI  sym53c8xx
 20:          0       2359          0         GSC-PCI  enp0s1
 64:        224     148358     128518             CPU  timer
 65:         16       4224        677             CPU  IPI
 66:          0          0          0             CPU  lasi
 67:          0       8758          0             CPU  Dino
STK:       2240       6080       3072   Kernel stack usage

root@debian:~# chcpu -d 2	# disables CPU2
CPU 2 disabled

root@debian:~# cat /proc/interrupts
           CPU0       CPU1
 17:          0          0        GSC-ASIC  parport0
 18:          0       1843         GSC-PCI  ttyS0
 19:          0       3662         GSC-PCI  sym53c8xx
 20:...

root@debian:~# chcpu -e 2	# enable CPU2
[    6.466714] Releasing cpu 2 now, hpa=fffb2000
CPU 2 enabled

root@debian:~# cat /proc/interrupts
           CPU0       CPU1       CPU2
 17:          0          0          0        GSC-ASIC  parport0
 18:          0       1915          0         GSC-PCI  ttyS0
 19:          0       3668          0         GSC-PCI  sym53c8xx
...

CPU hotplugging on the C8000 seems to work reliable.

Helge

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY
  2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
                   ` (11 preceding siblings ...)
  2022-03-25 14:53 ` [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
@ 2022-03-25 16:46 ` Rolf Eike Beer
  12 siblings, 0 replies; 23+ messages in thread
From: Rolf Eike Beer @ 2022-03-25 16:46 UTC (permalink / raw)
  To: linux-parisc, Helge Deller; +Cc: James Bottomley, John David Anglin

[-- Attachment #1: Type: text/plain, Size: 855 bytes --]

Am Freitag, 25. März 2022, 15:38:22 CET schrieb Helge Deller:
> Switch away from the own cpu topology code to common code which is used
> by ARM64 and RISCV. That allows us to enable hotplug later on too.

> diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
> index e88a6ce7c96d..72d9aeb54fbe 100644
> --- a/arch/parisc/kernel/topology.c
> +++ b/arch/parisc/kernel/topology.c
> @@ -71,6 +37,12 @@ void __init store_cpu_topology(unsigned int cpuid)
>  	if (cpuid_topo->core_id != -1)
>  		return;
> 
> +#ifdef CONFIG_HOTPLUG_CPU
> +	per_cpu(cpu_devices, cpuid).hotpluggable = 1;
> +#endif
> +	if (register_cpu(&per_cpu(cpu_devices, cpuid), cpuid))
> +		printk("Failed to register CPU device");
> +

This seems to be missing a level, and I think also printing the id of the 
failing CPU wouldn't hurt either.


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 03/12] parisc: Move store_cpu_topology() into __cpuinit section
  2022-03-25 14:38 ` [PATCH 03/12] parisc: Move store_cpu_topology() into __cpuinit section Helge Deller
@ 2022-03-25 16:52   ` Rolf Eike Beer
  2022-03-25 17:12     ` Helge Deller
  0 siblings, 1 reply; 23+ messages in thread
From: Rolf Eike Beer @ 2022-03-25 16:52 UTC (permalink / raw)
  To: linux-parisc, Helge Deller; +Cc: James Bottomley, John David Anglin

[-- Attachment #1: Type: text/plain, Size: 730 bytes --]

Am Freitag, 25. März 2022, 15:38:24 CET schrieb Helge Deller:
> Signed-off-by: Helge Deller <deller@gmx.de>
> ---
>  arch/parisc/kernel/topology.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
> index 72d9aeb54fbe..dc766fb55491 100644
> --- a/arch/parisc/kernel/topology.c
> +++ b/arch/parisc/kernel/topology.c
> @@ -16,17 +16,18 @@
>  #include <linux/cpu.h>
> 
>  #include <asm/topology.h>
> +#include <asm/sections.h>
> 
>  static DEFINE_PER_CPU(struct cpu, cpu_devices);
> 
> -static int dualcores_found __initdata;
> +static int dualcores_found;

I wonder if that should not be something like __cpuinit_data.

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 04/12] parisc: Move start_cpu_itimer() into __cpuinit section
  2022-03-25 14:38 ` [PATCH 04/12] parisc: Move start_cpu_itimer() " Helge Deller
@ 2022-03-25 16:53   ` Rolf Eike Beer
  2022-03-25 17:13     ` Helge Deller
  0 siblings, 1 reply; 23+ messages in thread
From: Rolf Eike Beer @ 2022-03-25 16:53 UTC (permalink / raw)
  To: linux-parisc, Helge Deller; +Cc: James Bottomley, John David Anglin

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

Am Freitag, 25. März 2022, 15:38:25 CET schrieb Helge Deller:
> Signed-off-by: Helge Deller <deller@gmx.de>
> ---
>  arch/parisc/kernel/time.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
> index 061119a56fbe..4101392bf74d 100644
> --- a/arch/parisc/kernel/time.c
> +++ b/arch/parisc/kernel/time.c
> @@ -150,7 +150,7 @@ static struct clocksource clocksource_cr16 = {
>  	.flags			= CLOCK_SOURCE_IS_CONTINUOUS,
>  };
> 
> -void __init start_cpu_itimer(void)
> +void __cpuinit start_cpu_itimer(void)
>  {
>  	unsigned int cpu = smp_processor_id();
>  	unsigned long next_tick = mfctl(16) + clocktick;

I would have squashed this and 5, 7, and 8 together. None of these patches 
adds any sensible description and all do the same.

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 11/12] parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging
  2022-03-25 14:38 ` [PATCH 11/12] parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging Helge Deller
@ 2022-03-25 16:56   ` Rolf Eike Beer
  2022-03-25 17:14     ` Helge Deller
  0 siblings, 1 reply; 23+ messages in thread
From: Rolf Eike Beer @ 2022-03-25 16:56 UTC (permalink / raw)
  To: linux-parisc, Helge Deller; +Cc: James Bottomley, John David Anglin

[-- Attachment #1: Type: text/plain, Size: 1958 bytes --]

Am Freitag, 25. März 2022, 15:38:32 CET schrieb Helge Deller:
> Let the PDC firmware put the CPU into firmware idle loop with
> pdc_cpu_rendezvous() function.
> 
> Signed-off-by: Helge Deller <deller@gmx.de>
> ---
>  arch/parisc/kernel/process.c | 33 ++++++++++++++++++++++++++++++---
>  1 file changed, 30 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
> index ea3d83b6fb62..44fa89fbb280 100644
> --- a/arch/parisc/kernel/process.c
> +++ b/arch/parisc/kernel/process.c
> @@ -38,6 +38,7 @@
>  #include <linux/rcupdate.h>
>  #include <linux/random.h>
>  #include <linux/nmi.h>
> +#include <linux/sched/hotplug.h>
> 
>  #include <asm/io.h>
>  #include <asm/asm-offsets.h>
> @@ -46,6 +47,7 @@
>  #include <asm/pdc_chassis.h>
>  #include <asm/unwind.h>
>  #include <asm/sections.h>
> +#include <asm/cacheflush.h>
> 
>  #define COMMAND_GLOBAL  F_EXTEND(0xfffe0030)
>  #define CMD_RESET       5       /* reset any module */
> @@ -158,10 +160,35 @@ void release_thread(struct task_struct *dead_task)
>  int running_on_qemu __ro_after_init;
>  EXPORT_SYMBOL(running_on_qemu);
> 
> -void __cpuidle arch_cpu_idle_dead(void)
> +/*
> + * Called from the idle thread for the CPU which has been shutdown.
> + */
> +void arch_cpu_idle_dead(void)
>  {
> -	/* nop on real hardware, qemu will offline CPU. */
> -	asm volatile("or %%r31,%%r31,%%r31\n":::);
> +#ifdef CONFIG_HOTPLUG_CPU
> +	idle_task_exit();
> +
> +	local_irq_disable();
> +
> +	/*
> +	 * Tell __cpu_die() that this CPU is now safe to dispose of.
> +	 */
> +	(void)cpu_report_death();
> +
> +	/*
> +	 * Ensure that the cache lines are written out.
> +	 */
> +	flush_cache_all_local();
> +	flush_tlb_all_local(NULL);
> +
> +	/*
> +	 * Let PDC firmware put CPU into firmware idle loop.
> +	 */
> +	__pdc_cpu_rendezvous();

That could all be one-line comments for a higher code/line ratio ;)

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 12/12] parisc: Implement __cpu_die() and __cpu_disable() for CPU hotplugging
  2022-03-25 14:38 ` [PATCH 12/12] parisc: Implement __cpu_die() and __cpu_disable() " Helge Deller
@ 2022-03-25 17:10   ` Rolf Eike Beer
  2022-03-25 18:00     ` Helge Deller
  0 siblings, 1 reply; 23+ messages in thread
From: Rolf Eike Beer @ 2022-03-25 17:10 UTC (permalink / raw)
  To: linux-parisc, Helge Deller; +Cc: James Bottomley, John David Anglin

[-- Attachment #1: Type: text/plain, Size: 3258 bytes --]

Am Freitag, 25. März 2022, 15:38:33 CET schrieb Helge Deller:
> Add relevant code to __cpu_die() and __cpu_disable() to finally enable
> the CPU hotplugging features. Reset the irq count values in smp_callin()
> to zero before bringing up the CPU.
> 
> Use "chcpu -d 1" to bring CPU1 down, and "chcpu -e 1" to bring it up.
> 
> Signed-off-by: Helge Deller <deller@gmx.de>
> ---
>  arch/parisc/Kconfig           |  1 +
>  arch/parisc/include/asm/smp.h |  9 +---
>  arch/parisc/kernel/smp.c      | 80 +++++++++++++++++++++++++++++++++--
>  3 files changed, 79 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
> index a32a882a2d58..60cc33fd345c 100644
> --- a/arch/parisc/kernel/smp.c
> +++ b/arch/parisc/kernel/smp.c
> @@ -430,10 +444,68 @@ void smp_cpus_done(unsigned int cpu_max)
> 
>  int __cpu_up(unsigned int cpu, struct task_struct *tidle)
>  {
> -	if (cpu != 0 && cpu < parisc_max_cpus && smp_boot_one_cpu(cpu, 
tidle))
> -		return -ENOSYS;
> +	if (cpu_online(cpu))
> +		return 0;
> +
> +	if (num_online_cpus() < parisc_max_cpus && smp_boot_one_cpu(cpu, 
tidle))
> +		return -EIO;

I had to look up parisc_max_cpus, and found this:

> static int parisc_max_cpus = 1;

Hm, signed?

> parisc_max_cpus = max_cpus;
>        if (!max_cpus)
>                printk(KERN_INFO "SMP mode deactivated.\n");

So parisc_max_cpus is now 0, which seems wrong. Shouldn't the check be before 
the assignment? This would have avoided the "cpu != 0" in the old code 
completely.

> +
> +	return cpu_online(cpu) ? 0 : -EIO;
> +}
> +
> +/*
> + * __cpu_disable runs on the processor to be shutdown.
> + */
> +int __cpu_disable(void)
> +{
> +#ifdef CONFIG_HOTPLUG_CPU
> +	unsigned int cpu = smp_processor_id();
> +
> +	remove_cpu_topology(cpu);
> +
> +	/*
> +	 * Take this CPU offline.  Once we clear this, we can't return,
> +	 * and we must not schedule until we're ready to give up the cpu.
> +	 */
> +	set_cpu_online(cpu, false);
> +
> +	/*
> +	 * disable IPI interrupt
> +	 */
> +	disable_percpu_irq(IPI_IRQ);
> +
> +	/*
> +	 * migrate IRQs away from this CPU
> +	 */
> +	irq_migrate_all_off_this_cpu();

While I really enjoy good code comments the last 2 seem a t bit wasteful, 
given that the code is basically exactly the same as the text.

> +	/*
> +	 * Flush user cache and TLB mappings, and then remove this CPU
> +	 * from the vm mask set of all processes.
> +	 *
> +	 * Caches are flushed to the Level of Unification Inner Shareable
> +	 * to write-back dirty lines to unified caches shared by all CPUs.
> +	 */
> +	flush_cache_all_local();
> +	flush_tlb_all_local(NULL);
> 
> -	return cpu_online(cpu) ? 0 : -ENOSYS;
> +	/* disable all irqs, including timer irq */
> +	local_irq_disable();
> +#endif
> +	return 0;
> +}
> +
> +/*
> + * called on the thread which is asking for a CPU to be shutdown -
> + * waits until shutdown has completed, or it is timed out.
> + */
> +void __cpu_die(unsigned int cpu)
> +{
> +	if (!cpu_wait_death(cpu, 5)) {
> +		pr_crit("CPU%u: cpu didn't die\n", cpu);
> +		return;
> +	}
> +	pr_debug("CPU%u: shutdown\n", cpu);
>  }
> 
>  #ifdef CONFIG_PROC_FS
> --
> 2.35.1


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 03/12] parisc: Move store_cpu_topology() into __cpuinit section
  2022-03-25 16:52   ` Rolf Eike Beer
@ 2022-03-25 17:12     ` Helge Deller
  0 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 17:12 UTC (permalink / raw)
  To: Rolf Eike Beer, linux-parisc; +Cc: James Bottomley, John David Anglin

On 3/25/22 17:52, Rolf Eike Beer wrote:
> Am Freitag, 25. März 2022, 15:38:24 CET schrieb Helge Deller:
>> Signed-off-by: Helge Deller <deller@gmx.de>
>> ---
>>  arch/parisc/kernel/topology.c | 5 +++--
>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
>> index 72d9aeb54fbe..dc766fb55491 100644
>> --- a/arch/parisc/kernel/topology.c
>> +++ b/arch/parisc/kernel/topology.c
>> @@ -16,17 +16,18 @@
>>  #include <linux/cpu.h>
>>
>>  #include <asm/topology.h>
>> +#include <asm/sections.h>
>>
>>  static DEFINE_PER_CPU(struct cpu, cpu_devices);
>>
>> -static int dualcores_found __initdata;
>> +static int dualcores_found;
>
> I wonder if that should not be something like __cpuinit_data.

Heh ... all other platforms got rid of __cpuinit and __cpuinit_data.
I just wanted to keep it on parisc in order to have small code in case of UP.
That said, introducing a __cpuinit_data section for this single variable didn't made sense.

Helge

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 04/12] parisc: Move start_cpu_itimer() into __cpuinit section
  2022-03-25 16:53   ` Rolf Eike Beer
@ 2022-03-25 17:13     ` Helge Deller
  0 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 17:13 UTC (permalink / raw)
  To: Rolf Eike Beer, linux-parisc; +Cc: James Bottomley, John David Anglin

On 3/25/22 17:53, Rolf Eike Beer wrote:
> Am Freitag, 25. März 2022, 15:38:25 CET schrieb Helge Deller:
>> Signed-off-by: Helge Deller <deller@gmx.de>
>> ---
>>  arch/parisc/kernel/time.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
>> index 061119a56fbe..4101392bf74d 100644
>> --- a/arch/parisc/kernel/time.c
>> +++ b/arch/parisc/kernel/time.c
>> @@ -150,7 +150,7 @@ static struct clocksource clocksource_cr16 = {
>>  	.flags			= CLOCK_SOURCE_IS_CONTINUOUS,
>>  };
>>
>> -void __init start_cpu_itimer(void)
>> +void __cpuinit start_cpu_itimer(void)
>>  {
>>  	unsigned int cpu = smp_processor_id();
>>  	unsigned long next_tick = mfctl(16) + clocktick;
>
> I would have squashed this and 5, 7, and 8 together. None of these patches
> adds any sensible description and all do the same.

Yes, maybe I'll do that. Keeping them seperate makes handling easier for me.

Helge

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 11/12] parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging
  2022-03-25 16:56   ` Rolf Eike Beer
@ 2022-03-25 17:14     ` Helge Deller
  0 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 17:14 UTC (permalink / raw)
  To: Rolf Eike Beer, linux-parisc; +Cc: James Bottomley, John David Anglin

On 3/25/22 17:56, Rolf Eike Beer wrote:
> Am Freitag, 25. März 2022, 15:38:32 CET schrieb Helge Deller:
>> Let the PDC firmware put the CPU into firmware idle loop with
>> pdc_cpu_rendezvous() function.
>>
>> Signed-off-by: Helge Deller <deller@gmx.de>
>> ---
>>  arch/parisc/kernel/process.c | 33 ++++++++++++++++++++++++++++++---
>>  1 file changed, 30 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
>> index ea3d83b6fb62..44fa89fbb280 100644
>> --- a/arch/parisc/kernel/process.c
>> +++ b/arch/parisc/kernel/process.c
>> @@ -38,6 +38,7 @@
>>  #include <linux/rcupdate.h>
>>  #include <linux/random.h>
>>  #include <linux/nmi.h>
>> +#include <linux/sched/hotplug.h>
>>
>>  #include <asm/io.h>
>>  #include <asm/asm-offsets.h>
>> @@ -46,6 +47,7 @@
>>  #include <asm/pdc_chassis.h>
>>  #include <asm/unwind.h>
>>  #include <asm/sections.h>
>> +#include <asm/cacheflush.h>
>>
>>  #define COMMAND_GLOBAL  F_EXTEND(0xfffe0030)
>>  #define CMD_RESET       5       /* reset any module */
>> @@ -158,10 +160,35 @@ void release_thread(struct task_struct *dead_task)
>>  int running_on_qemu __ro_after_init;
>>  EXPORT_SYMBOL(running_on_qemu);
>>
>> -void __cpuidle arch_cpu_idle_dead(void)
>> +/*
>> + * Called from the idle thread for the CPU which has been shutdown.
>> + */
>> +void arch_cpu_idle_dead(void)
>>  {
>> -	/* nop on real hardware, qemu will offline CPU. */
>> -	asm volatile("or %%r31,%%r31,%%r31\n":::);
>> +#ifdef CONFIG_HOTPLUG_CPU
>> +	idle_task_exit();
>> +
>> +	local_irq_disable();
>> +
>> +	/*
>> +	 * Tell __cpu_die() that this CPU is now safe to dispose of.
>> +	 */
>> +	(void)cpu_report_death();
>> +
>> +	/*
>> +	 * Ensure that the cache lines are written out.
>> +	 */
>> +	flush_cache_all_local();
>> +	flush_tlb_all_local(NULL);
>> +
>> +	/*
>> +	 * Let PDC firmware put CPU into firmware idle loop.
>> +	 */
>> +	__pdc_cpu_rendezvous();
>
> That could all be one-line comments for a higher code/line ratio ;)

Yes. The syntax is mostly copied from other arches, where it's like this.

Helge

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 12/12] parisc: Implement __cpu_die() and __cpu_disable() for CPU hotplugging
  2022-03-25 17:10   ` Rolf Eike Beer
@ 2022-03-25 18:00     ` Helge Deller
  0 siblings, 0 replies; 23+ messages in thread
From: Helge Deller @ 2022-03-25 18:00 UTC (permalink / raw)
  To: Rolf Eike Beer, linux-parisc; +Cc: James Bottomley, John David Anglin

On 3/25/22 18:10, Rolf Eike Beer wrote:
> Am Freitag, 25. März 2022, 15:38:33 CET schrieb Helge Deller:
>> Add relevant code to __cpu_die() and __cpu_disable() to finally enable
>> the CPU hotplugging features. Reset the irq count values in smp_callin()
>> to zero before bringing up the CPU.
>>
>> Use "chcpu -d 1" to bring CPU1 down, and "chcpu -e 1" to bring it up.
>>
>> Signed-off-by: Helge Deller <deller@gmx.de>
>> ---
>>  arch/parisc/Kconfig           |  1 +
>>  arch/parisc/include/asm/smp.h |  9 +---
>>  arch/parisc/kernel/smp.c      | 80 +++++++++++++++++++++++++++++++++--
>>  3 files changed, 79 insertions(+), 11 deletions(-)
>>
>> diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
>> index a32a882a2d58..60cc33fd345c 100644
>> --- a/arch/parisc/kernel/smp.c
>> +++ b/arch/parisc/kernel/smp.c
>> @@ -430,10 +444,68 @@ void smp_cpus_done(unsigned int cpu_max)
>>
>>  int __cpu_up(unsigned int cpu, struct task_struct *tidle)
>>  {
>> -	if (cpu != 0 && cpu < parisc_max_cpus && smp_boot_one_cpu(cpu,
> tidle))
>> -		return -ENOSYS;
>> +	if (cpu_online(cpu))
>> +		return 0;
>> +
>> +	if (num_online_cpus() < parisc_max_cpus && smp_boot_one_cpu(cpu,
> tidle))
>> +		return -EIO;
>
> I had to look up parisc_max_cpus, and found this:
>
>> static int parisc_max_cpus = 1;
>
> Hm, signed?
>
>> parisc_max_cpus = max_cpus;
>>        if (!max_cpus)
>>                printk(KERN_INFO "SMP mode deactivated.\n");
>
> So parisc_max_cpus is now 0, which seems wrong. Shouldn't the check be before
> the assignment? This would have avoided the "cpu != 0" in the old code
> completely.

No, the old
	cpu != 0 && ....smp_boot_one_cpu(cpu, tidle))
was to avoid that smp_boot_one_cpu() gets called for the monarch cpu.

Anyway, you are right, the code could need cleanups.
But in my patch series I wanted to keep the changes minimal in the first place.

>
>> +
>> +	return cpu_online(cpu) ? 0 : -EIO;
>> +}
>> +
>> +/*
>> + * __cpu_disable runs on the processor to be shutdown.
>> + */
>> +int __cpu_disable(void)
>> +{
>> +#ifdef CONFIG_HOTPLUG_CPU
>> +	unsigned int cpu = smp_processor_id();
>> +
>> +	remove_cpu_topology(cpu);
>> +
>> +	/*
>> +	 * Take this CPU offline.  Once we clear this, we can't return,
>> +	 * and we must not schedule until we're ready to give up the cpu.
>> +	 */
>> +	set_cpu_online(cpu, false);
>> +
>> +	/*
>> +	 * disable IPI interrupt
>> +	 */
>> +	disable_percpu_irq(IPI_IRQ);
>> +
>> +	/*
>> +	 * migrate IRQs away from this CPU
>> +	 */
>> +	irq_migrate_all_off_this_cpu();
>
> While I really enjoy good code comments the last 2 seem a t bit wasteful,
> given that the code is basically exactly the same as the text.

Yep.

Helge

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 09/12] parisc: Ensure set_firmware_width() is called only once
  2022-03-25 14:38 ` [PATCH 09/12] parisc: Ensure set_firmware_width() is called only once Helge Deller
@ 2022-03-26  8:58   ` Rolf Eike Beer
  0 siblings, 0 replies; 23+ messages in thread
From: Rolf Eike Beer @ 2022-03-26  8:58 UTC (permalink / raw)
  To: linux-parisc, Helge Deller; +Cc: James Bottomley, John David Anglin

[-- Attachment #1: Type: text/plain, Size: 269 bytes --]

Am Freitag, 25. März 2022, 15:38:30 CET schrieb Helge Deller:
> Make sure, that set_firmware_width() is only called once at
> runtime. This prevents that if secondary CPUs are started later
> get stuck in spinlocks.

The second sentence seems to be missing a word.

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2022-03-26  8:58 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-25 14:38 [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
2022-03-25 14:38 ` [PATCH 02/12] parisc: Add __cpuinit section for HOTPLUG_CPU Helge Deller
2022-03-25 14:38 ` [PATCH 03/12] parisc: Move store_cpu_topology() into __cpuinit section Helge Deller
2022-03-25 16:52   ` Rolf Eike Beer
2022-03-25 17:12     ` Helge Deller
2022-03-25 14:38 ` [PATCH 04/12] parisc: Move start_cpu_itimer() " Helge Deller
2022-03-25 16:53   ` Rolf Eike Beer
2022-03-25 17:13     ` Helge Deller
2022-03-25 14:38 ` [PATCH 05/12] parisc: Move init_per_cpu() init " Helge Deller
2022-03-25 14:38 ` [PATCH 06/12] parisc: Move disable_sr_hashing_asm() into " Helge Deller
2022-03-25 14:38 ` [PATCH 07/12] parisc: Move disable_sr_hashing() " Helge Deller
2022-03-25 14:38 ` [PATCH 08/12] parisc: Move init_IRQ() " Helge Deller
2022-03-25 14:38 ` [PATCH 09/12] parisc: Ensure set_firmware_width() is called only once Helge Deller
2022-03-26  8:58   ` Rolf Eike Beer
2022-03-25 14:38 ` [PATCH 10/12] parisc: Move common_stext into text section when CONFIG_HOTPLUG_CPU=y Helge Deller
2022-03-25 14:38 ` [PATCH 11/12] parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging Helge Deller
2022-03-25 16:56   ` Rolf Eike Beer
2022-03-25 17:14     ` Helge Deller
2022-03-25 14:38 ` [PATCH 12/12] parisc: Implement __cpu_die() and __cpu_disable() " Helge Deller
2022-03-25 17:10   ` Rolf Eike Beer
2022-03-25 18:00     ` Helge Deller
2022-03-25 14:53 ` [PATCH 01/12] parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY Helge Deller
2022-03-25 16:46 ` Rolf Eike Beer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.