[PATCH 1/3] smp: Introduce a weak helper function to check for pending IPIs

Ulf Hansson
2025-10-03T15:03:11Z

When governors used during cpuidle, tries to find the most optimal
idlestate for a CPU or a group of CPUs, they are known to quite often fail.
One reason for this, is that we are not taking into account whether there
has been an IPI scheduled for any of the CPUs that are affected by the
selected idlestate.

To enable pending IPIs to be taken into account for cpuidle decisions,
let's introduce a new helper function, cpus_has_pending_ipi(). Moreover,
let's use the __weak attribute for the default implementation, to allow
this to be implemented on a per architecture basis.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
include/linux/smp.h | 5 +++++
kernel/smp.c | 18 ++++++++++++++++++
2 files changed, 23 insertions(+)

diff --git a/include/linux/smp.h b/include/linux/smp.h
index 18e9c918325e..476186e5e69c 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -168,6 +168,7 @@ int smp_call_function_any(const struct cpumask *mask,

void kick_all_cpus_sync(void);
void wake_up_all_idle_cpus(void);
+bool cpus_has_pending_ipi(const struct cpumask *mask);

/*
* Generic and arch helpers
@@ -216,6 +217,10 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func,

static inline void kick_all_cpus_sync(void) { }
static inline void wake_up_all_idle_cpus(void) { }
+static inline bool cpus_has_pending_ipi(const struct cpumask *mask)
+{
+ return false;
+}

#define setup_max_cpus 0

diff --git a/kernel/smp.c b/kernel/smp.c
index 56f83aa58ec8..ec524db501b5 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -1088,6 +1088,24 @@ void wake_up_all_idle_cpus(void)
}
EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);

+/**
+ * cpus_has_pending_ipi - Check for pending IPIs for CPUs
+ * @mask: The CPU mask for the CPUs to check.
+ *
+ * This function may be overriden by an arch specific implementation, which
+ * should walk through the CPU-mask and check if there are any pending IPIs
+ * being scheduled for any of the CPUs in the CPU-mask.
+ *
+ * Note, the default implementation below doesn't have the capability to check
+ * for IPIs, hence it must return false.
+ *
+ * Returns true if there is a pending IPI scheduled.
+ */
+bool __weak cpus_has_pending_ipi(const struct cpumask *mask)
+{
+ return false;
+}
+
/**
* struct smp_call_on_cpu_struct - Call a function on a specific CPU
* @work: &work_struct
--
2.43.0