Skip to content

Commit ccde652

Browse files
author
Ulf Hansson
committed
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>
1 parent 80ed617 commit ccde652

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

include/linux/smp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ int smp_call_function_any(const struct cpumask *mask,
168168

169169
void kick_all_cpus_sync(void);
170170
void wake_up_all_idle_cpus(void);
171+
bool cpus_peek_for_pending_ipi(const struct cpumask *mask);
171172

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

217218
static inline void kick_all_cpus_sync(void) { }
218219
static inline void wake_up_all_idle_cpus(void) { }
220+
static inline bool cpus_peek_for_pending_ipi(const struct cpumask *mask)
221+
{
222+
return false;
223+
}
219224

220225
#define setup_max_cpus 0
221226

kernel/smp.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,28 @@ void wake_up_all_idle_cpus(void)
10871087
}
10881088
EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
10891089

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+
10901112
/**
10911113
* struct smp_call_on_cpu_struct - Call a function on a specific CPU
10921114
* @work: &work_struct

0 commit comments

Comments
 (0)