Re: [PATCH v2 7/7] sparc/smp: Remove on-stack cpumask var

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dawei

On Sat, Apr 20, 2024 at 01:15:47PM +0800, Dawei Li wrote:
> In general it's preferable to avoid placing cpumasks on the stack, as
> for large values of NR_CPUS these can consume significant amounts of
> stack space and make stack overflows more likely.
> 
> - Change prototype of sparc32_ipi_ops::cross_call() so that it takes
>   const cpumask * arg and all its callers accordingly.
> 
> - As for all cross_call() implementations, divide cpumask_test_cpu() call
>   into several sub calls to avoid on-stack cpumask var.
> 
> Signed-off-by: Dawei Li <dawei.li@xxxxxxxxxxxx>

The code changes looks ok from a quick look.
But we have a bunch of patches pending touching or removing the same
files. On top of this, the right approach would be to take a
look at code from a higher level.

In other words - I advise to drop this, and maybe re-visit in a few
months after the pending patches has hit -next.

Sorry for asking you to look as this.

	Sam

> ---
>  arch/sparc/include/asm/smp_32.h | 12 ++++++------
>  arch/sparc/kernel/kernel.h      | 11 +++++++++++
>  arch/sparc/kernel/leon_smp.c    | 11 ++++-------
>  arch/sparc/kernel/sun4d_smp.c   | 10 ++++------
>  arch/sparc/kernel/sun4m_smp.c   | 10 ++++------
>  5 files changed, 29 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h
> index 2cf7971d7f6c..9b6a166f6a57 100644
> --- a/arch/sparc/include/asm/smp_32.h
> +++ b/arch/sparc/include/asm/smp_32.h
> @@ -54,7 +54,7 @@ void smp_bogo(struct seq_file *);
>  void smp_info(struct seq_file *);
>  
>  struct sparc32_ipi_ops {
> -	void (*cross_call)(void *func, cpumask_t mask, unsigned long arg1,
> +	void (*cross_call)(void *func, const cpumask_t *mask, unsigned long arg1,
>  			   unsigned long arg2, unsigned long arg3,
>  			   unsigned long arg4);
>  	void (*resched)(int cpu);
> @@ -65,29 +65,29 @@ extern const struct sparc32_ipi_ops *sparc32_ipi_ops;
>  
>  static inline void xc0(void *func)
>  {
> -	sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0);
> +	sparc32_ipi_ops->cross_call(func, cpu_online_mask, 0, 0, 0, 0);
>  }
>  
>  static inline void xc1(void *func, unsigned long arg1)
>  {
> -	sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0);
> +	sparc32_ipi_ops->cross_call(func, cpu_online_mask, arg1, 0, 0, 0);
>  }
>  static inline void xc2(void *func, unsigned long arg1, unsigned long arg2)
>  {
> -	sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0);
> +	sparc32_ipi_ops->cross_call(func, cpu_online_mask, arg1, arg2, 0, 0);
>  }
>  
>  static inline void xc3(void *func, unsigned long arg1, unsigned long arg2,
>  		       unsigned long arg3)
>  {
> -	sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
> +	sparc32_ipi_ops->cross_call(func, cpu_online_mask,
>  				    arg1, arg2, arg3, 0);
>  }
>  
>  static inline void xc4(void *func, unsigned long arg1, unsigned long arg2,
>  		       unsigned long arg3, unsigned long arg4)
>  {
> -	sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
> +	sparc32_ipi_ops->cross_call(func, cpu_online_mask,
>  				    arg1, arg2, arg3, arg4);
>  }
>  
> diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
> index a8fb7c0bf053..36747e8f7e36 100644
> --- a/arch/sparc/kernel/kernel.h
> +++ b/arch/sparc/kernel/kernel.h
> @@ -4,6 +4,7 @@
>  
>  #include <linux/interrupt.h>
>  #include <linux/ftrace.h>
> +#include <linux/smp.h>
>  
>  #include <asm/traps.h>
>  #include <asm/head.h>
> @@ -75,6 +76,16 @@ int sparc32_classify_syscall(unsigned int syscall);
>  #endif
>  
>  #ifdef CONFIG_SPARC32
> +
> +#ifdef CONFIG_SMP
> +static inline bool cpu_for_ipi(const cpumask_t *mask, unsigned int cpu)
> +{
> +	return cpumask_test_cpu(cpu, mask) &&
> +	       cpumask_test_cpu(cpu, cpu_online_mask) &&
> +	       cpu != smp_processor_id();
> +}
> +#endif /* CONFIG_SMP */
> +
>  /* setup_32.c */
>  struct linux_romvec;
>  void sparc32_start_kernel(struct linux_romvec *rp);
> diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
> index 1ee393abc463..291884c8d82a 100644
> --- a/arch/sparc/kernel/leon_smp.c
> +++ b/arch/sparc/kernel/leon_smp.c
> @@ -372,7 +372,7 @@ static struct smp_funcall {
>  static DEFINE_SPINLOCK(cross_call_lock);
>  
>  /* Cross calls must be serialized, at least currently. */
> -static void leon_cross_call(void *func, cpumask_t mask, unsigned long arg1,
> +static void leon_cross_call(void *func, const cpumask_t *mask, unsigned long arg1,
>  			    unsigned long arg2, unsigned long arg3,
>  			    unsigned long arg4)
>  {
> @@ -403,14 +403,11 @@ static void leon_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  		{
>  			register int i;
>  
> -			cpumask_clear_cpu(smp_processor_id(), &mask);
> -			cpumask_and(&mask, cpu_online_mask, &mask);
>  			for (i = 0; i <= high; i++) {
> -				if (cpumask_test_cpu(i, &mask)) {
> +				if (cpu_for_ipi(mask, i)) {
>  					ccall_info.processors_in[i] = 0;
>  					ccall_info.processors_out[i] = 0;
>  					leon_send_ipi(i, LEON3_IRQ_CROSS_CALL);
> -
>  				}
>  			}
>  		}
> @@ -420,7 +417,7 @@ static void leon_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  
>  			i = 0;
>  			do {
> -				if (!cpumask_test_cpu(i, &mask))
> +				if (!cpu_for_ipi(mask, i))
>  					continue;
>  
>  				while (!ccall_info.processors_in[i])
> @@ -429,7 +426,7 @@ static void leon_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  
>  			i = 0;
>  			do {
> -				if (!cpumask_test_cpu(i, &mask))
> +				if (!cpu_for_ipi(mask, i))
>  					continue;
>  
>  				while (!ccall_info.processors_out[i])
> diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
> index 9a62a5cf3337..7dc57ca05728 100644
> --- a/arch/sparc/kernel/sun4d_smp.c
> +++ b/arch/sparc/kernel/sun4d_smp.c
> @@ -281,7 +281,7 @@ static struct smp_funcall {
>  static DEFINE_SPINLOCK(cross_call_lock);
>  
>  /* Cross calls must be serialized, at least currently. */
> -static void sun4d_cross_call(void *func, cpumask_t mask, unsigned long arg1,
> +static void sun4d_cross_call(void *func, const cpumask_t *mask, unsigned long arg1,
>  			     unsigned long arg2, unsigned long arg3,
>  			     unsigned long arg4)
>  {
> @@ -315,10 +315,8 @@ static void sun4d_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  		{
>  			register int i;
>  
> -			cpumask_clear_cpu(smp_processor_id(), &mask);
> -			cpumask_and(&mask, cpu_online_mask, &mask);
>  			for (i = 0; i <= high; i++) {
> -				if (cpumask_test_cpu(i, &mask)) {
> +				if (cpu_for_ipi(mask, i)) {
>  					ccall_info.processors_in[i] = 0;
>  					ccall_info.processors_out[i] = 0;
>  					sun4d_send_ipi(i, IRQ_CROSS_CALL);
> @@ -331,7 +329,7 @@ static void sun4d_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  
>  			i = 0;
>  			do {
> -				if (!cpumask_test_cpu(i, &mask))
> +				if (!cpu_for_ipi(mask, i))
>  					continue;
>  				while (!ccall_info.processors_in[i])
>  					barrier();
> @@ -339,7 +337,7 @@ static void sun4d_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  
>  			i = 0;
>  			do {
> -				if (!cpumask_test_cpu(i, &mask))
> +				if (!cpu_for_ipi(mask, i))
>  					continue;
>  				while (!ccall_info.processors_out[i])
>  					barrier();
> diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
> index 056df034e79e..3f43f64e3489 100644
> --- a/arch/sparc/kernel/sun4m_smp.c
> +++ b/arch/sparc/kernel/sun4m_smp.c
> @@ -170,7 +170,7 @@ static struct smp_funcall {
>  static DEFINE_SPINLOCK(cross_call_lock);
>  
>  /* Cross calls must be serialized, at least currently. */
> -static void sun4m_cross_call(void *func, cpumask_t mask, unsigned long arg1,
> +static void sun4m_cross_call(void *func, const cpumask_t *mask, unsigned long arg1,
>  			     unsigned long arg2, unsigned long arg3,
>  			     unsigned long arg4)
>  {
> @@ -191,10 +191,8 @@ static void sun4m_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  		{
>  			register int i;
>  
> -			cpumask_clear_cpu(smp_processor_id(), &mask);
> -			cpumask_and(&mask, cpu_online_mask, &mask);
>  			for (i = 0; i < ncpus; i++) {
> -				if (cpumask_test_cpu(i, &mask)) {
> +				if (cpu_for_ipi(mask, i)) {
>  					ccall_info.processors_in[i] = 0;
>  					ccall_info.processors_out[i] = 0;
>  					sun4m_send_ipi(i, IRQ_CROSS_CALL);
> @@ -210,7 +208,7 @@ static void sun4m_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  
>  			i = 0;
>  			do {
> -				if (!cpumask_test_cpu(i, &mask))
> +				if (!cpu_for_ipi(mask, i))
>  					continue;
>  				while (!ccall_info.processors_in[i])
>  					barrier();
> @@ -218,7 +216,7 @@ static void sun4m_cross_call(void *func, cpumask_t mask, unsigned long arg1,
>  
>  			i = 0;
>  			do {
> -				if (!cpumask_test_cpu(i, &mask))
> +				if (!cpu_for_ipi(mask, i))
>  					continue;
>  				while (!ccall_info.processors_out[i])
>  					barrier();
> -- 
> 2.27.0




[Index of Archives]     [Kernel Development]     [DCCP]     [Linux ARM Development]     [Linux]     [Photo]     [Yosemite Help]     [Linux ARM Kernel]     [Linux SCSI]     [Linux x86_64]     [Linux Hams]

  Powered by Linux