All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Dawei Li <dawei.li@shingroup.cn>
To: davem@davemloft.net, andreas@gaisler.com
Cc: sparclinux@vger.kernel.org, linux-kernel@vger.kernel.org,
	sam@ravnborg.org, Dawei Li <dawei.li@shingroup.cn>
Subject: [PATCH v2 7/7] sparc/smp: Remove on-stack cpumask var
Date: Sat, 20 Apr 2024 13:15:47 +0800	[thread overview]
Message-ID: <20240420051547.3681642-8-dawei.li@shingroup.cn> (raw)
In-Reply-To: <20240420051547.3681642-1-dawei.li@shingroup.cn>

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@shingroup.cn>
---
 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


  parent reply	other threads:[~2024-04-20  5:17 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-20  5:15 [PATCH v2 0/7] Remove onstack cpumask var for sparc Dawei Li
2024-04-20  5:15 ` [PATCH v2 1/7] sparc/srmmu: Remove on-stack cpumask var Dawei Li
2024-04-20  7:58   ` Sam Ravnborg
2024-04-22  5:46     ` Dawei Li
2024-04-20  5:15 ` [PATCH v2 2/7] sparc/irq: " Dawei Li
2024-04-20  8:22   ` Sam Ravnborg
2024-04-20  5:15 ` [PATCH v2 3/7] sparc/of: " Dawei Li
2024-04-20  8:23   ` Sam Ravnborg
2024-04-20  5:15 ` [PATCH v2 4/7] sparc/pci_msi: " Dawei Li
2024-04-20  8:23   ` Sam Ravnborg
2024-04-20  5:15 ` [PATCH v2 5/7] sparc: " Dawei Li
2024-04-20  8:28   ` Sam Ravnborg
2024-04-22  5:49     ` Dawei Li
2024-04-20  5:15 ` [PATCH v2 6/7] sparc/leon: " Dawei Li
2024-04-20  8:32   ` Sam Ravnborg
2024-04-22  6:15     ` Dawei Li
2024-04-20  5:15 ` Dawei Li [this message]
2024-04-20 11:42   ` [PATCH v2 7/7] sparc/smp: " Sam Ravnborg
2024-04-22  6:19     ` Dawei Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240420051547.3681642-8-dawei.li@shingroup.cn \
    --to=dawei.li@shingroup.cn \
    --cc=andreas@gaisler.com \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sam@ravnborg.org \
    --cc=sparclinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.