ANDROID: GKI: kernel: tick-sched: Add an API for wakeup callbacks

Some modules perform actions on wake, as checked in tick-sched. Add a
function to register callbacks and export it.

Bug: 161415027
Bug: 161414381
Signed-off-by: J. Avila <elavila@google.com>
Change-Id: I7e1da4aea9e78ad2a7f0c407d4162fabc0e368a7
This commit is contained in:
J. Avila
2020-07-20 19:30:36 +00:00
parent f35f6c6746
commit 4c3d3d24dd
2 changed files with 23 additions and 1 deletions

View File

@@ -111,6 +111,8 @@ enum tick_dep_bits {
#define TICK_DEP_MASK_SCHED (1 << TICK_DEP_BIT_SCHED) #define TICK_DEP_MASK_SCHED (1 << TICK_DEP_BIT_SCHED)
#define TICK_DEP_MASK_CLOCK_UNSTABLE (1 << TICK_DEP_BIT_CLOCK_UNSTABLE) #define TICK_DEP_MASK_CLOCK_UNSTABLE (1 << TICK_DEP_BIT_CLOCK_UNSTABLE)
extern void register_tick_sched_wakeup_callback(void (*cb)(void));
#ifdef CONFIG_NO_HZ_COMMON #ifdef CONFIG_NO_HZ_COMMON
extern bool tick_nohz_enabled; extern bool tick_nohz_enabled;
extern bool tick_nohz_tick_stopped(void); extern bool tick_nohz_tick_stopped(void);

View File

@@ -26,6 +26,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/irq_work.h> #include <linux/irq_work.h>
#include <linux/posix-timers.h> #include <linux/posix-timers.h>
#include <linux/timer.h>
#include <linux/context_tracking.h> #include <linux/context_tracking.h>
#include <linux/mm.h> #include <linux/mm.h>
@@ -1258,6 +1259,9 @@ void tick_irq_enter(void)
* High resolution timer specific code * High resolution timer specific code
*/ */
#ifdef CONFIG_HIGH_RES_TIMERS #ifdef CONFIG_HIGH_RES_TIMERS
static void (*wake_callback)(void);
/* /*
* We rearm the timer until we get disabled by the idle code. * We rearm the timer until we get disabled by the idle code.
* Called with interrupts disabled. * Called with interrupts disabled.
@@ -1275,8 +1279,15 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
* Do not call, when we are not in irq context and have * Do not call, when we are not in irq context and have
* no valid regs pointer * no valid regs pointer
*/ */
if (regs) if (regs) {
tick_sched_handle(ts, regs); tick_sched_handle(ts, regs);
if (wake_callback && tick_do_timer_cpu == smp_processor_id()) {
/*
* wakeup user if needed
*/
wake_callback();
}
}
else else
ts->next_tick = 0; ts->next_tick = 0;
@@ -1393,6 +1404,15 @@ int tick_check_oneshot_change(int allow_nohz)
return 0; return 0;
} }
void register_tick_sched_wakeup_callback(void (*cb)(void))
{
if (!wake_callback)
wake_callback = cb;
else
pr_warn("tick-sched wake cb already exists; skipping.\n");
}
EXPORT_SYMBOL_GPL(register_tick_sched_wakeup_callback);
ktime_t *get_next_event_cpu(unsigned int cpu) ktime_t *get_next_event_cpu(unsigned int cpu)
{ {
return &(per_cpu(tick_cpu_device, cpu).evtdev->next_event); return &(per_cpu(tick_cpu_device, cpu).evtdev->next_event);