diff mbox series

[RFC,5/6] RISC-V: Move spinwait booting method to its own config

Message ID 20211204002038.113653-6-atishp@atishpatra.org (mailing list archive)
State New, archived
Headers show
Series Sparse HART id support | expand

Commit Message

Atish Patra Dec. 4, 2021, 12:20 a.m. UTC
From: Atish Patra <atishp@rivosinc.com>

The spinwait booting method should only be used for platforms with older
firmware without SBI HSM extension or M-mode firmware because spinwait
method can't support cpu hotplug, kexec or sparse hartid. It is better
to move the entire spinwait implementation to its own config which can
be disabled if required. It is enabled by default to maintain backward
compatibility and M-mode Linux.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 arch/riscv/Kconfig          | 14 ++++++++++++++
 arch/riscv/kernel/Makefile  |  3 ++-
 arch/riscv/kernel/cpu_ops.c |  8 ++++++++
 arch/riscv/kernel/head.S    |  6 +++---
 arch/riscv/kernel/head.h    |  2 ++
 5 files changed, 29 insertions(+), 4 deletions(-)

Comments

Randy Dunlap Dec. 4, 2021, 12:40 a.m. UTC | #1
Hi--

On 12/3/21 16:20, Atish Patra wrote:
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 821252b65f89..4afb42d5707d 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -403,6 +403,20 @@ config RISCV_SBI_V01
>  	  This config allows kernel to use SBI v0.1 APIs. This will be
>  	  deprecated in future once legacy M-mode software are no longer in use.
>  
> +config RISCV_BOOT_SPINWAIT
> +	bool "Spinwait booting method"
> +	depends on SMP
> +	default y
> +	help
> +	  This enables support for booting Linux via spinwait method. In the
> +	  spinwait method, all cores randomly jump to Linux. One of the core

	                                                                cores

> +	  gets chosen via lottery and all other keeps spinning on a percpu

	                                  others keep

> +	  variable. This method can not support cpu hotplug and sparse hartid

	                        cannot support CPU hotplug and sparse hartid

> +	  scheme. It should be only enabled for M-mode Linux or platforms relying
> +	  on older firmware without SBI HSM extension. All other platform should

	                                                         platforms

> +	  rely on ordered booing via SBI HSM extension which gets chosen

	                  booting

> +          dynamically at runtime if the firmware supports it.

	  dynamically at runtime if the firmware supports it.

(Last line should be indented with tab + 2 spaces, not 10 spaces.)
Anup Patel Dec. 13, 2021, 1:01 p.m. UTC | #2
On Sat, Dec 4, 2021 at 5:51 AM Atish Patra <atishp@atishpatra.org> wrote:
>
> From: Atish Patra <atishp@rivosinc.com>
>
> The spinwait booting method should only be used for platforms with older
> firmware without SBI HSM extension or M-mode firmware because spinwait
> method can't support cpu hotplug, kexec or sparse hartid. It is better
> to move the entire spinwait implementation to its own config which can
> be disabled if required. It is enabled by default to maintain backward
> compatibility and M-mode Linux.
>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> ---
>  arch/riscv/Kconfig          | 14 ++++++++++++++
>  arch/riscv/kernel/Makefile  |  3 ++-
>  arch/riscv/kernel/cpu_ops.c |  8 ++++++++
>  arch/riscv/kernel/head.S    |  6 +++---
>  arch/riscv/kernel/head.h    |  2 ++
>  5 files changed, 29 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 821252b65f89..4afb42d5707d 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -403,6 +403,20 @@ config RISCV_SBI_V01
>           This config allows kernel to use SBI v0.1 APIs. This will be
>           deprecated in future once legacy M-mode software are no longer in use.
>
> +config RISCV_BOOT_SPINWAIT
> +       bool "Spinwait booting method"
> +       depends on SMP
> +       default y
> +       help
> +         This enables support for booting Linux via spinwait method. In the
> +         spinwait method, all cores randomly jump to Linux. One of the core
> +         gets chosen via lottery and all other keeps spinning on a percpu
> +         variable. This method can not support cpu hotplug and sparse hartid
> +         scheme. It should be only enabled for M-mode Linux or platforms relying
> +         on older firmware without SBI HSM extension. All other platform should
> +         rely on ordered booing via SBI HSM extension which gets chosen
> +          dynamically at runtime if the firmware supports it.
> +
>  config KEXEC
>         bool "Kexec system call"
>         select KEXEC_CORE
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 3397ddac1a30..612556faa527 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -43,7 +43,8 @@ obj-$(CONFIG_FPU)             += fpu.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
>  obj-$(CONFIG_SMP)              += cpu_ops.o
> -obj-$(CONFIG_SMP)              += cpu_ops_spinwait.o
> +
> +obj-$(CONFIG_RISCV_BOOT_SPINWAIT) += cpu_ops_spinwait.o
>  obj-$(CONFIG_MODULES)          += module.o
>  obj-$(CONFIG_MODULE_SECTIONS)  += module-sections.o
>
> diff --git a/arch/riscv/kernel/cpu_ops.c b/arch/riscv/kernel/cpu_ops.c
> index c1e30f403c3b..170d07e57721 100644
> --- a/arch/riscv/kernel/cpu_ops.c
> +++ b/arch/riscv/kernel/cpu_ops.c
> @@ -15,7 +15,15 @@
>  const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
>
>  extern const struct cpu_operations cpu_ops_sbi;
> +#ifdef CONFIG_RISCV_BOOT_SPINWAIT
>  extern const struct cpu_operations cpu_ops_spinwait;
> +#else
> +const struct cpu_operations cpu_ops_spinwait = {
> +       .name           = "",
> +       .cpu_prepare    = NULL,
> +       .cpu_start      = NULL,
> +};
> +#endif
>
>  void __init cpu_set_ops(int cpuid)
>  {
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 9f16bfe9307e..4a694e15b95b 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -259,7 +259,7 @@ pmp_done:
>         li t0, SR_FS
>         csrc CSR_STATUS, t0
>
> -#ifdef CONFIG_SMP
> +#ifdef CONFIG_RISCV_BOOT_SPINWAIT
>         li t0, CONFIG_NR_CPUS
>         blt a0, t0, .Lgood_cores
>         tail .Lsecondary_park
> @@ -285,7 +285,7 @@ pmp_done:
>         beq t0, t1, .Lsecondary_start
>
>  #endif /* CONFIG_XIP */
> -#endif /* CONFIG_SMP */
> +#endif /* CONFIG_RISCV_BOOT_SPINWAIT */
>
>  #ifdef CONFIG_XIP_KERNEL
>         la sp, _end + THREAD_SIZE
> @@ -344,7 +344,7 @@ clear_bss_done:
>         call soc_early_init
>         tail start_kernel
>
> -#ifdef CONFIG_SMP
> +#if defined(CONFIG_SMP) && defined(CONFIG_RISCV_BOOT_SPINWAIT)

The RISCV_BOOT_SPINWAIT option already depends on SMP.

Do you still need to check defined(CONFIG_SMP) here ?

Regards,
Anup

>  .Lsecondary_start:
>         /* Set trap vector to spin forever to help debug */
>         la a3, .Lsecondary_park
> diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h
> index 5393cca77790..726731ada534 100644
> --- a/arch/riscv/kernel/head.h
> +++ b/arch/riscv/kernel/head.h
> @@ -16,7 +16,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa);
>  asmlinkage void __init __copy_data(void);
>  #endif
>
> +#ifdef CONFIG_RISCV_BOOT_SPINWAIT
>  extern void *__cpu_spinwait_stack_pointer[];
>  extern void *__cpu_spinwait_task_pointer[];
> +#endif
>
>  #endif /* __ASM_HEAD_H */
> --
> 2.33.1
>
Atish Patra Dec. 13, 2021, 9:08 p.m. UTC | #3
On Mon, Dec 13, 2021 at 5:02 AM Anup Patel <anup@brainfault.org> wrote:
>
> On Sat, Dec 4, 2021 at 5:51 AM Atish Patra <atishp@atishpatra.org> wrote:
> >
> > From: Atish Patra <atishp@rivosinc.com>
> >
> > The spinwait booting method should only be used for platforms with older
> > firmware without SBI HSM extension or M-mode firmware because spinwait
> > method can't support cpu hotplug, kexec or sparse hartid. It is better
> > to move the entire spinwait implementation to its own config which can
> > be disabled if required. It is enabled by default to maintain backward
> > compatibility and M-mode Linux.
> >
> > Signed-off-by: Atish Patra <atishp@rivosinc.com>
> > ---
> >  arch/riscv/Kconfig          | 14 ++++++++++++++
> >  arch/riscv/kernel/Makefile  |  3 ++-
> >  arch/riscv/kernel/cpu_ops.c |  8 ++++++++
> >  arch/riscv/kernel/head.S    |  6 +++---
> >  arch/riscv/kernel/head.h    |  2 ++
> >  5 files changed, 29 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 821252b65f89..4afb42d5707d 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -403,6 +403,20 @@ config RISCV_SBI_V01
> >           This config allows kernel to use SBI v0.1 APIs. This will be
> >           deprecated in future once legacy M-mode software are no longer in use.
> >
> > +config RISCV_BOOT_SPINWAIT
> > +       bool "Spinwait booting method"
> > +       depends on SMP
> > +       default y
> > +       help
> > +         This enables support for booting Linux via spinwait method. In the
> > +         spinwait method, all cores randomly jump to Linux. One of the core
> > +         gets chosen via lottery and all other keeps spinning on a percpu
> > +         variable. This method can not support cpu hotplug and sparse hartid
> > +         scheme. It should be only enabled for M-mode Linux or platforms relying
> > +         on older firmware without SBI HSM extension. All other platform should
> > +         rely on ordered booing via SBI HSM extension which gets chosen
> > +          dynamically at runtime if the firmware supports it.
> > +
> >  config KEXEC
> >         bool "Kexec system call"
> >         select KEXEC_CORE
> > diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> > index 3397ddac1a30..612556faa527 100644
> > --- a/arch/riscv/kernel/Makefile
> > +++ b/arch/riscv/kernel/Makefile
> > @@ -43,7 +43,8 @@ obj-$(CONFIG_FPU)             += fpu.o
> >  obj-$(CONFIG_SMP)              += smpboot.o
> >  obj-$(CONFIG_SMP)              += smp.o
> >  obj-$(CONFIG_SMP)              += cpu_ops.o
> > -obj-$(CONFIG_SMP)              += cpu_ops_spinwait.o
> > +
> > +obj-$(CONFIG_RISCV_BOOT_SPINWAIT) += cpu_ops_spinwait.o
> >  obj-$(CONFIG_MODULES)          += module.o
> >  obj-$(CONFIG_MODULE_SECTIONS)  += module-sections.o
> >
> > diff --git a/arch/riscv/kernel/cpu_ops.c b/arch/riscv/kernel/cpu_ops.c
> > index c1e30f403c3b..170d07e57721 100644
> > --- a/arch/riscv/kernel/cpu_ops.c
> > +++ b/arch/riscv/kernel/cpu_ops.c
> > @@ -15,7 +15,15 @@
> >  const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
> >
> >  extern const struct cpu_operations cpu_ops_sbi;
> > +#ifdef CONFIG_RISCV_BOOT_SPINWAIT
> >  extern const struct cpu_operations cpu_ops_spinwait;
> > +#else
> > +const struct cpu_operations cpu_ops_spinwait = {
> > +       .name           = "",
> > +       .cpu_prepare    = NULL,
> > +       .cpu_start      = NULL,
> > +};
> > +#endif
> >
> >  void __init cpu_set_ops(int cpuid)
> >  {
> > diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> > index 9f16bfe9307e..4a694e15b95b 100644
> > --- a/arch/riscv/kernel/head.S
> > +++ b/arch/riscv/kernel/head.S
> > @@ -259,7 +259,7 @@ pmp_done:
> >         li t0, SR_FS
> >         csrc CSR_STATUS, t0
> >
> > -#ifdef CONFIG_SMP
> > +#ifdef CONFIG_RISCV_BOOT_SPINWAIT
> >         li t0, CONFIG_NR_CPUS
> >         blt a0, t0, .Lgood_cores
> >         tail .Lsecondary_park
> > @@ -285,7 +285,7 @@ pmp_done:
> >         beq t0, t1, .Lsecondary_start
> >
> >  #endif /* CONFIG_XIP */
> > -#endif /* CONFIG_SMP */
> > +#endif /* CONFIG_RISCV_BOOT_SPINWAIT */
> >
> >  #ifdef CONFIG_XIP_KERNEL
> >         la sp, _end + THREAD_SIZE
> > @@ -344,7 +344,7 @@ clear_bss_done:
> >         call soc_early_init
> >         tail start_kernel
> >
> > -#ifdef CONFIG_SMP
> > +#if defined(CONFIG_SMP) && defined(CONFIG_RISCV_BOOT_SPINWAIT)
>
> The RISCV_BOOT_SPINWAIT option already depends on SMP.
>
> Do you still need to check defined(CONFIG_SMP) here ?
>

Nope. I guess this one slipped through the cracks. All other related
#ifdef have only CONFIG_RISCV_BOOT_SPINWAIT
I will fix it in v2.

> Regards,
> Anup
>
> >  .Lsecondary_start:
> >         /* Set trap vector to spin forever to help debug */
> >         la a3, .Lsecondary_park
> > diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h
> > index 5393cca77790..726731ada534 100644
> > --- a/arch/riscv/kernel/head.h
> > +++ b/arch/riscv/kernel/head.h
> > @@ -16,7 +16,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa);
> >  asmlinkage void __init __copy_data(void);
> >  #endif
> >
> > +#ifdef CONFIG_RISCV_BOOT_SPINWAIT
> >  extern void *__cpu_spinwait_stack_pointer[];
> >  extern void *__cpu_spinwait_task_pointer[];
> > +#endif
> >
> >  #endif /* __ASM_HEAD_H */
> > --
> > 2.33.1
> >
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 821252b65f89..4afb42d5707d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -403,6 +403,20 @@  config RISCV_SBI_V01
 	  This config allows kernel to use SBI v0.1 APIs. This will be
 	  deprecated in future once legacy M-mode software are no longer in use.
 
+config RISCV_BOOT_SPINWAIT
+	bool "Spinwait booting method"
+	depends on SMP
+	default y
+	help
+	  This enables support for booting Linux via spinwait method. In the
+	  spinwait method, all cores randomly jump to Linux. One of the core
+	  gets chosen via lottery and all other keeps spinning on a percpu
+	  variable. This method can not support cpu hotplug and sparse hartid
+	  scheme. It should be only enabled for M-mode Linux or platforms relying
+	  on older firmware without SBI HSM extension. All other platform should
+	  rely on ordered booing via SBI HSM extension which gets chosen
+          dynamically at runtime if the firmware supports it.
+
 config KEXEC
 	bool "Kexec system call"
 	select KEXEC_CORE
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 3397ddac1a30..612556faa527 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -43,7 +43,8 @@  obj-$(CONFIG_FPU)		+= fpu.o
 obj-$(CONFIG_SMP)		+= smpboot.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP)		+= cpu_ops.o
-obj-$(CONFIG_SMP)		+= cpu_ops_spinwait.o
+
+obj-$(CONFIG_RISCV_BOOT_SPINWAIT) += cpu_ops_spinwait.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_MODULE_SECTIONS)	+= module-sections.o
 
diff --git a/arch/riscv/kernel/cpu_ops.c b/arch/riscv/kernel/cpu_ops.c
index c1e30f403c3b..170d07e57721 100644
--- a/arch/riscv/kernel/cpu_ops.c
+++ b/arch/riscv/kernel/cpu_ops.c
@@ -15,7 +15,15 @@ 
 const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
 
 extern const struct cpu_operations cpu_ops_sbi;
+#ifdef CONFIG_RISCV_BOOT_SPINWAIT
 extern const struct cpu_operations cpu_ops_spinwait;
+#else
+const struct cpu_operations cpu_ops_spinwait = {
+	.name		= "",
+	.cpu_prepare	= NULL,
+	.cpu_start	= NULL,
+};
+#endif
 
 void __init cpu_set_ops(int cpuid)
 {
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 9f16bfe9307e..4a694e15b95b 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -259,7 +259,7 @@  pmp_done:
 	li t0, SR_FS
 	csrc CSR_STATUS, t0
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_RISCV_BOOT_SPINWAIT
 	li t0, CONFIG_NR_CPUS
 	blt a0, t0, .Lgood_cores
 	tail .Lsecondary_park
@@ -285,7 +285,7 @@  pmp_done:
 	beq t0, t1, .Lsecondary_start
 
 #endif /* CONFIG_XIP */
-#endif /* CONFIG_SMP */
+#endif /* CONFIG_RISCV_BOOT_SPINWAIT */
 
 #ifdef CONFIG_XIP_KERNEL
 	la sp, _end + THREAD_SIZE
@@ -344,7 +344,7 @@  clear_bss_done:
 	call soc_early_init
 	tail start_kernel
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(CONFIG_RISCV_BOOT_SPINWAIT)
 .Lsecondary_start:
 	/* Set trap vector to spin forever to help debug */
 	la a3, .Lsecondary_park
diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h
index 5393cca77790..726731ada534 100644
--- a/arch/riscv/kernel/head.h
+++ b/arch/riscv/kernel/head.h
@@ -16,7 +16,9 @@  asmlinkage void __init setup_vm(uintptr_t dtb_pa);
 asmlinkage void __init __copy_data(void);
 #endif
 
+#ifdef CONFIG_RISCV_BOOT_SPINWAIT
 extern void *__cpu_spinwait_stack_pointer[];
 extern void *__cpu_spinwait_task_pointer[];
+#endif
 
 #endif /* __ASM_HEAD_H */