All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [PATCH v4 15/25] x86: mp: Add iterators for CPUs
Date: Tue,  7 Jul 2020 19:34:35 -0600	[thread overview]
Message-ID: <20200708013446.2600256-14-sjg@chromium.org> (raw)
In-Reply-To: <20200708013446.2600256-1-sjg@chromium.org>

It is convenient to iterate through the CPUs performing work on each one
and processing the result. Add a few iterator functions which handle this.
These can be used by any client code. It can call mp_run_on_cpus() on
each CPU that is returned, handling them one at a time.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

Changes in v4:
- Update mp_next_cpu() to stop if CONFIG_SMP_AP_WORK is not enabled

Changes in v3:
- Add more comments on how the iterators work

 arch/x86/cpu/mp_init.c    | 63 +++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/mp.h | 42 ++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 721b729d92..56e07ecd8f 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -686,6 +686,69 @@ int mp_park_aps(void)
 	return get_timer(start);
 }
 
+int mp_first_cpu(int cpu_select)
+{
+	struct udevice *dev;
+	int num_cpus;
+	int ret;
+
+	/*
+	 * This assumes that CPUs are numbered from 0. This function tries to
+	 * avoid assuming the CPU 0 is the boot CPU
+	 */
+	if (cpu_select == MP_SELECT_ALL)
+		return 0;   /* start with the first one */
+
+	ret = get_bsp(&dev, &num_cpus);
+	if (ret < 0)
+		return log_msg_ret("bsp", ret);
+
+	/* Return boot CPU if requested */
+	if (cpu_select == MP_SELECT_BSP)
+		return ret;
+
+	/* Return something other than the boot CPU, if APs requested */
+	if (cpu_select == MP_SELECT_APS && num_cpus > 1)
+		return ret == 0 ? 1 : 0;
+
+	/* Try to check for an invalid value */
+	if (cpu_select < 0 || cpu_select >= num_cpus)
+		return -EINVAL;
+
+	return cpu_select;  /* return the only selected one */
+}
+
+int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+	struct udevice *dev;
+	int num_cpus;
+	int ret;
+	int bsp;
+
+	/* If we selected the BSP or a particular single CPU, we are done */
+	if (!IS_ENABLED(CONFIG_SMP_AP_WORK) || cpu_select == MP_SELECT_BSP ||
+	    cpu_select >= 0)
+		return -EFBIG;
+
+	/* Must be doing MP_SELECT_ALL or MP_SELECT_APS; return the next CPU */
+	ret = get_bsp(&dev, &num_cpus);
+	if (ret < 0)
+		return log_msg_ret("bsp", ret);
+	bsp = ret;
+
+	/* Move to the next CPU */
+	assert(prev_cpu >= 0);
+	ret = prev_cpu + 1;
+
+	/* Skip the BSP if needed */
+	if (cpu_select == MP_SELECT_APS && ret == bsp)
+		ret++;
+	if (ret >= num_cpus)
+		return -EFBIG;
+
+	return ret;
+}
+
 int mp_init(void)
 {
 	int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 93b1786b66..34d724938a 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -118,6 +118,33 @@ int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg);
  * @return time taken to park the APs on success (in microseconds), -ve on error
  */
 int mp_park_aps(void);
+
+/**
+ * mp_first_cpu() - Get the first CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. Call this function first, then
+ * call mp_next_cpu() repeatedly (with the same @cpu_select) until it returns
+ * -EFBIG.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_first_cpu(int cpu_select);
+
+/**
+ * mp_next_cpu() - Get the next CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. After first calling
+ * mp_first_cpu() once, call this function repeatedly until it returns -EFBIG.
+ *
+ * The value of @cpu_select must be the same for all calls and must match the
+ * value passed to mp_first_cpu(), otherwise the behaviour is undefined.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @prev_cpu: Previous value returned by mp_first_cpu()/mp_next_cpu()
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_next_cpu(int cpu_select, int prev_cpu);
 #else
 static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 {
@@ -134,6 +161,21 @@ static inline int mp_park_aps(void)
 	return 0;
 }
 
+static inline int mp_first_cpu(int cpu_select)
+{
+	/* We cannot run on any APs, nor a selected CPU */
+	return cpu_select == MP_SELECT_APS ? -EFBIG : MP_SELECT_BSP;
+}
+
+static inline int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+	/*
+	 * When MP is not enabled, there is only one CPU and we did it in
+	 * mp_first_cpu()
+	 */
+	return -EFBIG;
+}
+
 #endif
 
 #endif /* _X86_MP_H_ */
-- 
2.27.0.383.g050319c2ae-goog

  parent reply	other threads:[~2020-07-08  1:34 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-08  1:34 [PATCH v4 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
2020-07-08  1:34 ` [PATCH v4 01/25] x86: mp_init: Switch to livetree Simon Glass
2020-07-08  1:34 ` [PATCH v4 02/25] x86: Move MP code into mp_init Simon Glass
2020-07-08  1:34 ` [PATCH v4 03/25] x86: mp_init: Avoid declarations in header files Simon Glass
2020-07-08  1:34 ` [PATCH v4 04/25] x86: mp_init: Switch parameter names in start_aps() Simon Glass
2020-07-08  1:34 ` [PATCH v4 05/25] x86: mp_init: Drop the num_cpus static variable Simon Glass
2020-07-08  1:34 ` [PATCH v4 06/25] x86: mtrr: Fix 'ensable' typo Simon Glass
2020-07-08  1:34 ` [PATCH v4 07/25] x86: mp_init: Set up the CPU numbers at the start Simon Glass
2020-07-08  1:34 ` [PATCH v4 08/25] x86: mp_init: Adjust bsp_init() to return more information Simon Glass
2020-07-08  1:34 ` [PATCH v4 09/25] x86: cpu: Remove unnecessary #ifdefs Simon Glass
2020-07-08  1:34 ` [PATCH v4 10/25] x86: mp: Support APs waiting for instructions Simon Glass
2020-07-13  4:48   ` Bin Meng
2020-07-08  1:34 ` [PATCH v4 11/25] global_data: Add a generic global_data flag for SMP state Simon Glass
2020-07-13  4:49   ` Bin Meng
2020-07-08  1:34 ` [PATCH v4 12/25] x86: Set the SMP flag when MP init is complete Simon Glass
2020-07-08  1:34 ` [PATCH v4 13/25] x86: mp: Allow running functions on multiple CPUs Simon Glass
2020-07-13  4:56   ` Bin Meng
2020-07-13 20:57     ` Simon Glass
2020-07-08  1:34 ` [PATCH v4 14/25] x86: mp: Park CPUs before running the OS Simon Glass
2020-07-08  1:34 ` Simon Glass [this message]
2020-07-13  4:57   ` [PATCH v4 15/25] x86: mp: Add iterators for CPUs Bin Meng
2020-07-08  1:34 ` [PATCH v4 16/25] x86: mtrr: Use MP calls to list the MTRRs Simon Glass
2020-07-08  1:34 ` [PATCH v4 17/25] x86: Don't enable SMP in SPL Simon Glass
2020-07-08  1:34 ` [PATCH v4 18/25] x86: coral: Update the memory map Simon Glass
2020-07-08  1:34 ` [PATCH v4 19/25] x86: mtrr: Update MTRRs on all CPUs Simon Glass
2020-07-13  4:58   ` Bin Meng
2020-07-08  1:34 ` [PATCH v4 20/25] x86: mtrr: Add support for writing to MTRRs on any CPU Simon Glass
2020-07-08  1:34 ` [PATCH v4 21/25] x86: mtrr: Update the command to use the new mtrr calls Simon Glass
2020-07-08  1:34 ` [PATCH v4 22/25] x86: mtrr: Restructure so command execution is in one place Simon Glass
2020-07-08  1:34 ` [PATCH v4 23/25] x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU Simon Glass
2020-07-08  1:34 ` [PATCH v4 24/25] x86: mp: Add more comments to the module Simon Glass
2020-07-08  1:34 ` [PATCH v4 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU Simon Glass
2020-07-13  5:11   ` Bin Meng
2020-07-17  3:24 ` [PATCH v4 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
2020-07-17  4:50   ` Bin Meng

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=20200708013446.2600256-14-sjg@chromium.org \
    --to=sjg@chromium.org \
    --cc=u-boot@lists.denx.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 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.