]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
smp: Introduce a helper function to check for pending IPIs
authorUlf Hansson <ulf.hansson@linaro.org>
Wed, 5 Nov 2025 09:54:07 +0000 (10:54 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 19 Nov 2025 17:06:50 +0000 (18:06 +0100)
When governors used during cpuidle try to find the most optimal idle state
for a CPU or a group of CPUs, they are known to quite often fail. One
reason for this is, that they are not taking into account whether there has
been an IPI scheduled for any of the CPUs that are affected by the selected
idle state.

To enable pending IPIs to be taken into account for cpuidle decisions,
introduce a new helper function, cpus_peek_for_pending_ipi().

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
include/linux/smp.h
kernel/smp.c

index 18e9c918325e5e1d47ec48369db5df2197634aea..91d0ecf3b8d3bfb42cbad90ac7383a174547e99f 100644 (file)
@@ -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_peek_for_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_peek_for_pending_ipi(const struct cpumask *mask)
+{
+       return false;
+}
 
 #define setup_max_cpus 0
 
index 02f52291fae4255e35caacec90339612615d031e..f349960f79cad961100899998da368e38df7f48e 100644 (file)
@@ -1087,6 +1087,28 @@ void wake_up_all_idle_cpus(void)
 }
 EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
 
+/**
+ * cpus_peek_for_pending_ipi - Check for pending IPI for CPUs
+ * @mask: The CPU mask for the CPUs to check.
+ *
+ * This function walks through the @mask to check if there are any pending IPIs
+ * scheduled, for any of the CPUs in the @mask. It does not guarantee
+ * correctness as it only provides a racy snapshot.
+ *
+ * Returns true if there is a pending IPI scheduled and false otherwise.
+ */
+bool cpus_peek_for_pending_ipi(const struct cpumask *mask)
+{
+       unsigned int cpu;
+
+       for_each_cpu(cpu, mask) {
+               if (!llist_empty(per_cpu_ptr(&call_single_queue, cpu)))
+                       return true;
+       }
+
+       return false;
+}
+
 /**
  * struct smp_call_on_cpu_struct - Call a function on a specific CPU
  * @work: &work_struct