ARM: smp: export pending IPI state

Record and export if an IPI is pending on the current CPU. Knowing if an
IPI is pending helps make better idle state determinations.

Change-Id: I92ab0aaeb3162cd312aa00a4e3eb978be2ad8efc
Signed-off-by: Lina Iyer <ilina@codeaurora.org>
This commit is contained in:
Lina Iyer 2019-07-24 15:37:21 -06:00 • committed by Maulik Shah
commit 2f5cb5c667
3 changed files with 60 additions and 0 deletions

View file

@ -52,6 +52,11 @@
#define CREATE_TRACE_POINTS
#include <trace/events/ipi.h>
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
DEFINE_PER_CPU(bool, pending_ipi);
EXPORT_PER_CPU_SYMBOL(pending_ipi);
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@ -521,6 +526,13 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
{
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
unsigned int cpu;
for_each_cpu(cpu, target)
per_cpu(pending_ipi, cpu) = true;
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
trace_ipi_raise_rcuidle(target, ipi_types[ipinr]);
__smp_cross_call(target, ipinr);
}
@ -695,6 +707,11 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
if ((unsigned)ipinr < NR_IPI)
trace_ipi_exit_rcuidle(ipi_types[ipinr]);
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
this_cpu_write(pending_ipi, false);
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
set_irq_regs(old_regs);
}

View file

@ -57,6 +57,11 @@
DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
EXPORT_PER_CPU_SYMBOL(cpu_number);
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
DEFINE_PER_CPU(bool, pending_ipi);
EXPORT_PER_CPU_SYMBOL(pending_ipi);
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@ -772,6 +777,13 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
{
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
unsigned int cpu;
for_each_cpu(cpu, target)
per_cpu(pending_ipi, cpu) = true;
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
trace_ipi_raise(target, ipi_types[ipinr]);
__smp_cross_call(target, ipinr);
}
@ -957,6 +969,11 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
if ((unsigned)ipinr < NR_IPI)
trace_ipi_exit_rcuidle(ipi_types[ipinr]);
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
this_cpu_write(pending_ipi, false);
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
set_irq_regs(old_regs);
}

View file

@ -136,6 +136,27 @@ static inline int get_boot_cpu_id(void)
return __boot_cpu_id;
}
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
DECLARE_PER_CPU(bool, pending_ipi);
static inline bool is_IPI_pending(const struct cpumask *mask)
{
unsigned int cpu;
for_each_cpu(cpu, mask) {
if (per_cpu(pending_ipi, cpu))
return true;
}
return false;
}
#else
static inline bool is_IPI_pending(const struct cpumask *mask)
{
return false;
}
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
#else /* !SMP */
static inline void smp_send_stop(void) { }
@ -178,6 +199,11 @@ static inline int get_boot_cpu_id(void)
return 0;
}
static inline bool is_IPI_pending(const struct cpumask *mask)
{
return false;
}
#endif /* !SMP */
/**