mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Donghai Qiao <dqiao@redhat.com>
To: akpm@linux-foundation.org, sfr@canb.auug.org.au, arnd@arndb.de,
	peterz@infradead.org, heying24@huawei.com,
	andriy.shevchenko@linux.intel.com, axboe@kernel.dk,
	rdunlap@infradead.org, tglx@linutronix.de, gor@linux.ibm.com
Cc: donghai.w.qiao@gmail.com, linux-kernel@vger.kernel.org,
	Donghai Qiao <dqiao@redhat.com>
Subject: [PATCH v2 07/11] smp: change smp_call_function_any() to smp_call_any()
Date: Fri, 22 Apr 2022 16:00:36 -0400	[thread overview]
Message-ID: <20220422200040.93813-8-dqiao@redhat.com> (raw)
In-Reply-To: <20220422200040.93813-1-dqiao@redhat.com>

Rename smp_call_function_any() to smp_call_any() and also make
the changes necessary.

Replace all the invocations of smp_call_function_any() with
smp_call_any() for all.

Actually the kernel consumers can use smp_call() when they want
to use smp_call_function_any(). The extra logics handled by
smp_call_function_any() should be moved out of there and have the
consumers choose the preferred CPU. Because there are quite a few
of the cross call consumers need to run their functions on just
one of the CPUs of a given CPU set, so there is some advantage to
add smp_call_any() to the interface.

Signed-off-by: Donghai Qiao <dqiao@redhat.com>
---
v1 -> v2: removed 'x' from the function names and change XCALL to SMP_CALL from the new macros

 arch/arm/kernel/perf_event_v7.c           |  6 +-
 arch/arm64/kernel/perf_event.c            |  6 +-
 arch/x86/kernel/cpu/resctrl/ctrlmondata.c |  2 +-
 drivers/cpufreq/acpi-cpufreq.c            |  4 +-
 drivers/cpufreq/powernv-cpufreq.c         | 12 ++--
 drivers/perf/arm_spe_pmu.c                |  2 +-
 include/linux/smp.h                       | 12 +---
 kernel/smp.c                              | 78 ++++++++++-------------
 8 files changed, 53 insertions(+), 69 deletions(-)

diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index eb2190477da1..ae008cba28c4 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -1192,9 +1192,9 @@ static void armv7_read_num_pmnc_events(void *info)
 
 static int armv7_probe_num_events(struct arm_pmu *arm_pmu)
 {
-	return smp_call_function_any(&arm_pmu->supported_cpus,
-				     armv7_read_num_pmnc_events,
-				     &arm_pmu->num_events, 1);
+	return smp_call_any(&arm_pmu->supported_cpus,
+			     armv7_read_num_pmnc_events,
+			     &arm_pmu->num_events, SMP_CALL_TYPE_SYNC);
 }
 
 static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index cb69ff1e6138..7326c7cc67de 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1186,9 +1186,9 @@ static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu)
 	};
 	int ret;
 
-	ret = smp_call_function_any(&cpu_pmu->supported_cpus,
-				    __armv8pmu_probe_pmu,
-				    &probe, 1);
+	ret = smp_call_any(&cpu_pmu->supported_cpus,
+			    __armv8pmu_probe_pmu,
+			    &probe, SMP_CALL_TYPE_SYNC);
 	if (ret)
 		return ret;
 
diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
index 87666275eed9..418c83c3c4b5 100644
--- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
+++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
@@ -512,7 +512,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
 	rr->val = 0;
 	rr->first = first;
 
-	smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1);
+	(void) smp_call_any(&d->cpu_mask, mon_event_count, rr, SMP_CALL_TYPE_SYNC);
 }
 
 int rdtgroup_mondata_show(struct seq_file *m, void *arg)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 3d514b82d055..e0c4b3c6575d 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -312,8 +312,8 @@ static u32 drv_read(struct acpi_cpufreq_data *data, const struct cpumask *mask)
 	};
 	int err;
 
-	err = smp_call_function_any(mask, do_drv_read, &cmd, 1);
-	WARN_ON_ONCE(err);	/* smp_call_function_any() was buggy? */
+	err = smp_call_any(mask, do_drv_read, &cmd, SMP_CALL_TYPE_SYNC);
+	WARN_ON_ONCE(err);	/* smp_call_any() was buggy? */
 	return cmd.val;
 }
 
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index fddbd1ea1635..d4f45bb9c419 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -507,8 +507,8 @@ static unsigned int powernv_cpufreq_get(unsigned int cpu)
 {
 	struct powernv_smp_call_data freq_data;
 
-	smp_call_function_any(cpu_sibling_mask(cpu), powernv_read_cpu_freq,
-			&freq_data, 1);
+	(void) smp_call_any(cpu_sibling_mask(cpu), powernv_read_cpu_freq,
+			&freq_data, SMP_CALL_TYPE_SYNC);
 
 	return freq_data.freq;
 }
@@ -820,8 +820,10 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
 	 * Use smp_call_function to send IPI and execute the
 	 * mtspr on target CPU.  We could do that without IPI
 	 * if current CPU is within policy->cpus (core)
+	 *
+	 * Shouldn't return the value of smp_call_any() ?
 	 */
-	smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1);
+	(void) smp_call_any(policy->cpus, set_pstate, &freq_data, SMP_CALL_TYPE_SYNC);
 	return 0;
 }
 
@@ -921,8 +923,8 @@ static void powernv_cpufreq_work_fn(struct work_struct *work)
 
 	cpus_read_lock();
 	cpumask_and(&mask, &chip->mask, cpu_online_mask);
-	smp_call_function_any(&mask,
-			      powernv_cpufreq_throttle_check, NULL, 0);
+	(void) smp_call_any(&mask, powernv_cpufreq_throttle_check,
+			     NULL, SMP_CALL_TYPE_ASYNC);
 
 	if (!chip->restore)
 		goto out;
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index d44bcc29d99c..e1059c60feab 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -1108,7 +1108,7 @@ static int arm_spe_pmu_dev_init(struct arm_spe_pmu *spe_pmu)
 	cpumask_t *mask = &spe_pmu->supported_cpus;
 
 	/* Make sure we probe the hardware on a relevant CPU */
-	ret = smp_call_function_any(mask,  __arm_spe_pmu_dev_probe, spe_pmu, 1);
+	ret = smp_call_any(mask,  __arm_spe_pmu_dev_probe, spe_pmu, SMP_CALL_TYPE_SYNC);
 	if (ret || !(spe_pmu->features & SPE_PMU_FEAT_DEV_PROBED))
 		return -ENXIO;
 
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 0301faf270bf..3a6663bce18f 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -161,6 +161,8 @@ do {						\
 	*(_csd) = CSD_INIT((_func), (_info));	\
 } while (0)
 
+extern int smp_call_any(const struct cpumask *mask, smp_call_func_t func,
+			 void *info, unsigned int flags);
 
 /*
  * smp_call Interface.
@@ -304,9 +306,6 @@ void smp_call_function(smp_call_func_t func, void *info, int wait);
 void smp_call_function_many(const struct cpumask *mask,
 			    smp_call_func_t func, void *info, bool wait);
 
-int smp_call_function_any(const struct cpumask *mask,
-			  smp_call_func_t func, void *info, int wait);
-
 void kick_all_cpus_sync(void);
 void wake_up_all_idle_cpus(void);
 
@@ -355,13 +354,6 @@ static inline void smp_send_reschedule(int cpu) { }
 			(up_smp_call_function(func, info))
 static inline void call_function_init(void) { }
 
-static inline int
-smp_call_function_any(const struct cpumask *mask, smp_call_func_t func,
-		      void *info, int wait)
-{
-	return smp_call_function_single(0, func, info, wait);
-}
-
 static inline void kick_all_cpus_sync(void) {  }
 static inline void wake_up_all_idle_cpus(void) {  }
 
diff --git a/kernel/smp.c b/kernel/smp.c
index 51715633b4f7..6a43ab165aee 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -626,49 +626,6 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info,
 }
 EXPORT_SYMBOL(smp_call_function_single);
 
-/*
- * smp_call_function_any - Run a function on any of the given cpus
- * @mask: The mask of cpus it can run on.
- * @func: The function to run. This must be fast and non-blocking.
- * @info: An arbitrary pointer to pass to the function.
- * @wait: If true, wait until function has completed.
- *
- * Returns 0 on success, else a negative status code (if no cpus were online).
- *
- * Selection preference:
- *	1) current cpu if in @mask
- *	2) any cpu of current node if in @mask
- *	3) any other online cpu in @mask
- */
-int smp_call_function_any(const struct cpumask *mask,
-			  smp_call_func_t func, void *info, int wait)
-{
-	unsigned int cpu;
-	const struct cpumask *nodemask;
-	int ret;
-
-	/* Try for same CPU (cheapest) */
-	cpu = get_cpu();
-	if (cpumask_test_cpu(cpu, mask))
-		goto call;
-
-	/* Try for same node. */
-	nodemask = cpumask_of_node(cpu_to_node(cpu));
-	for (cpu = cpumask_first_and(nodemask, mask); cpu < nr_cpu_ids;
-	     cpu = cpumask_next_and(cpu, nodemask, mask)) {
-		if (cpu_online(cpu))
-			goto call;
-	}
-
-	/* Any online will do: smp_call_function_single handles nr_cpu_ids. */
-	cpu = cpumask_any_and(mask, cpu_online_mask);
-call:
-	ret = smp_call_function_single(cpu, func, info, wait);
-	put_cpu();
-	return ret;
-}
-EXPORT_SYMBOL_GPL(smp_call_function_any);
-
 static void smp_call_function_many_cond(const struct cpumask *mask,
 					smp_call_func_t func, void *info,
 					bool wait,
@@ -1276,6 +1233,39 @@ EXPORT_SYMBOL(smp_call_private);
 int smp_call_any(const struct cpumask *mask, smp_call_func_t func,
 		void *info, unsigned int flags)
 {
-	return 0;
+	int cpu;
+        const struct cpumask *nodemask;
+
+	if (mask == NULL || func == NULL ||
+	    (flags != SMP_CALL_TYPE_SYNC && flags != SMP_CALL_TYPE_ASYNC))
+		return -EINVAL;
+
+        /* Try for same CPU (cheapest) */
+	preempt_disable();
+	cpu = smp_processor_id();
+
+        if (cpumask_test_cpu(cpu, mask))
+                goto call;
+
+        /* Try for same node. */
+        nodemask = cpumask_of_node(cpu_to_node(cpu));
+        for (cpu = cpumask_first_and(nodemask, mask); (unsigned int)cpu < nr_cpu_ids;
+             cpu = cpumask_next_and(cpu, nodemask, mask)) {
+                if (cpu_online(cpu))
+                        goto call;
+        }
+
+        /* Any online will do: smp_call_function_single handles nr_cpu_ids. */
+        cpu = cpumask_any_and(mask, cpu_online_mask);
+	if ((unsigned int)cpu >= nr_cpu_ids) {
+        	preempt_enable();
+		return -ENXIO;
+	}
+
+call:
+	(void) smp_call(cpu, func, info, flags);
+
+        preempt_enable();
+        return 0;
 }
 EXPORT_SYMBOL(smp_call_any);
-- 
2.27.0


  parent reply	other threads:[~2022-04-22 21:57 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-22 20:00 [PATCH v2 00/11] smp: cross CPU call interface Donghai Qiao
2022-04-22 20:00 ` [PATCH v2 01/11] smp: consolidate the structure definitions to smp.h Donghai Qiao
2022-04-23  4:57   ` kernel test robot
2022-04-25  8:39   ` Peter Zijlstra
2022-04-25  9:52   ` Thomas Gleixner
2022-04-22 20:00 ` [PATCH v2 02/11] smp: define the cross call interface Donghai Qiao
2022-04-25  9:05   ` Peter Zijlstra
2022-04-22 20:00 ` [PATCH v2 03/11] smp: eliminate SCF_WAIT and SCF_RUN_LOCAL Donghai Qiao
2022-04-25  9:10   ` Peter Zijlstra
2022-04-22 20:00 ` [PATCH v2 04/11] smp: replace smp_call_function_single() with smp_call() Donghai Qiao
2022-04-25  9:33   ` Peter Zijlstra
2022-04-22 20:00 ` [PATCH v2 05/11] smp: replace smp_call_function_single_async() with smp_call_private() Donghai Qiao
2022-04-23  7:30   ` kernel test robot
2022-04-24 22:06     ` Nathan Chancellor
2022-04-25  9:35   ` Peter Zijlstra
2022-04-22 20:00 ` [PATCH v2 06/11] smp: use smp_call_private() fron irq_work.c and core.c Donghai Qiao
2022-04-25  9:37   ` Peter Zijlstra
2022-04-22 20:00 ` Donghai Qiao [this message]
2022-04-22 20:00 ` [PATCH v2 08/11] smp: replace smp_call_function_many_cond() with __smp_call_mask_cond() Donghai Qiao
2022-04-22 20:00 ` [PATCH v2 09/11] smp: replace smp_call_function_single_async with smp_call_private Donghai Qiao
2022-04-22 20:00 ` [PATCH v2 10/11] smp: replace smp_call_function_single() with smp_call() Donghai Qiao
2022-04-22 20:00 ` [PATCH v2 11/11] smp: modify up.c to adopt the same format of cross CPU call Donghai Qiao
2022-04-23  5:17   ` kernel test robot
2022-04-23  5:58   ` kernel test robot
2022-04-26 14:00 ` [PATCH v2 00/11] smp: cross CPU call interface Christoph Hellwig

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=20220422200040.93813-8-dqiao@redhat.com \
    --to=dqiao@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=arnd@arndb.de \
    --cc=axboe@kernel.dk \
    --cc=donghai.w.qiao@gmail.com \
    --cc=gor@linux.ibm.com \
    --cc=heying24@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=rdunlap@infradead.org \
    --cc=sfr@canb.auug.org.au \
    --cc=tglx@linutronix.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®