Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

smp: Introduce a helper function to check for pending IPIs

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>

+27
+5
include/linux/smp.h
··· 168 168 169 169 void kick_all_cpus_sync(void); 170 170 void wake_up_all_idle_cpus(void); 171 + bool cpus_peek_for_pending_ipi(const struct cpumask *mask); 171 172 172 173 /* 173 174 * Generic and arch helpers ··· 217 216 218 217 static inline void kick_all_cpus_sync(void) { } 219 218 static inline void wake_up_all_idle_cpus(void) { } 219 + static inline bool cpus_peek_for_pending_ipi(const struct cpumask *mask) 220 + { 221 + return false; 222 + } 220 223 221 224 #define setup_max_cpus 0 222 225
+22
kernel/smp.c
··· 1088 1088 EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus); 1089 1089 1090 1090 /** 1091 + * cpus_peek_for_pending_ipi - Check for pending IPI for CPUs 1092 + * @mask: The CPU mask for the CPUs to check. 1093 + * 1094 + * This function walks through the @mask to check if there are any pending IPIs 1095 + * scheduled, for any of the CPUs in the @mask. It does not guarantee 1096 + * correctness as it only provides a racy snapshot. 1097 + * 1098 + * Returns true if there is a pending IPI scheduled and false otherwise. 1099 + */ 1100 + bool cpus_peek_for_pending_ipi(const struct cpumask *mask) 1101 + { 1102 + unsigned int cpu; 1103 + 1104 + for_each_cpu(cpu, mask) { 1105 + if (!llist_empty(per_cpu_ptr(&call_single_queue, cpu))) 1106 + return true; 1107 + } 1108 + 1109 + return false; 1110 + } 1111 + 1112 + /** 1091 1113 * struct smp_call_on_cpu_struct - Call a function on a specific CPU 1092 1114 * @work: &work_struct 1093 1115 * @done: &completion to signal