Loading drivers/cpuidle/cpuidle.c +7 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/ktime.h> #include <linux/hrtimer.h> #include "cpuidle.h" Loading Loading @@ -60,6 +61,12 @@ static void cpuidle_idle_call(void) return; } /* * run any timers that can be run now, at this point * before calculating the idle duration etc. */ hrtimer_peek_ahead_timers(); /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(dev); if (need_resched()) Loading include/linux/hrtimer.h +7 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,8 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) return timer->base->cpu_base->hres_active; } extern void hrtimer_peek_ahead_timers(void); /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an Loading @@ -305,6 +307,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) * is expired in the next softirq when the clock was advanced. */ static inline void clock_was_set(void) { } static inline void hrtimer_peek_ahead_timers(void) { } static inline void hres_timers_resume(void) { } Loading @@ -326,6 +329,10 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) extern ktime_t ktime_get(void); extern ktime_t ktime_get_real(void); DECLARE_PER_CPU(struct tick_device, tick_cpu_device); /* Exported timer functions: */ /* Initialize timers: */ Loading kernel/futex.c +5 −1 Original line number Diff line number Diff line Loading @@ -1296,10 +1296,14 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, if (!abs_time) schedule(); else { unsigned long slack; slack = current->timer_slack_ns; if (rt_task(current)) slack = 0; hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); hrtimer_init_sleeper(&t, current); hrtimer_set_expires(&t.timer, *abs_time); hrtimer_set_expires_range_ns(&t.timer, *abs_time, slack); hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS); if (!hrtimer_active(&t.timer)) Loading kernel/hrtimer.c +36 −1 Original line number Diff line number Diff line Loading @@ -1381,6 +1381,36 @@ void hrtimer_interrupt(struct clock_event_device *dev) raise_softirq(HRTIMER_SOFTIRQ); } /** * hrtimer_peek_ahead_timers -- run soft-expired timers now * * hrtimer_peek_ahead_timers will peek at the timer queue of * the current cpu and check if there are any timers for which * the soft expires time has passed. If any such timers exist, * they are run immediately and then removed from the timer queue. * */ void hrtimer_peek_ahead_timers(void) { unsigned long flags; struct tick_device *td; struct clock_event_device *dev; if (hrtimer_hres_active()) return; local_irq_save(flags); td = &__get_cpu_var(tick_cpu_device); if (!td) goto out; dev = td->evtdev; if (!dev) goto out; hrtimer_interrupt(dev); out: local_irq_restore(flags); } static void run_hrtimer_softirq(struct softirq_action *h) { run_hrtimer_pending(&__get_cpu_var(hrtimer_bases)); Loading Loading @@ -1563,9 +1593,14 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, struct restart_block *restart; struct hrtimer_sleeper t; int ret = 0; unsigned long slack; slack = current->timer_slack_ns; if (rt_task(current)) slack = 0; hrtimer_init_on_stack(&t.timer, clockid, mode); hrtimer_set_expires(&t.timer, timespec_to_ktime(*rqtp)); hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack); if (do_nanosleep(&t, mode)) goto out; Loading Loading
drivers/cpuidle/cpuidle.c +7 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/ktime.h> #include <linux/hrtimer.h> #include "cpuidle.h" Loading Loading @@ -60,6 +61,12 @@ static void cpuidle_idle_call(void) return; } /* * run any timers that can be run now, at this point * before calculating the idle duration etc. */ hrtimer_peek_ahead_timers(); /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(dev); if (need_resched()) Loading
include/linux/hrtimer.h +7 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,8 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) return timer->base->cpu_base->hres_active; } extern void hrtimer_peek_ahead_timers(void); /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an Loading @@ -305,6 +307,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) * is expired in the next softirq when the clock was advanced. */ static inline void clock_was_set(void) { } static inline void hrtimer_peek_ahead_timers(void) { } static inline void hres_timers_resume(void) { } Loading @@ -326,6 +329,10 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) extern ktime_t ktime_get(void); extern ktime_t ktime_get_real(void); DECLARE_PER_CPU(struct tick_device, tick_cpu_device); /* Exported timer functions: */ /* Initialize timers: */ Loading
kernel/futex.c +5 −1 Original line number Diff line number Diff line Loading @@ -1296,10 +1296,14 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, if (!abs_time) schedule(); else { unsigned long slack; slack = current->timer_slack_ns; if (rt_task(current)) slack = 0; hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); hrtimer_init_sleeper(&t, current); hrtimer_set_expires(&t.timer, *abs_time); hrtimer_set_expires_range_ns(&t.timer, *abs_time, slack); hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS); if (!hrtimer_active(&t.timer)) Loading
kernel/hrtimer.c +36 −1 Original line number Diff line number Diff line Loading @@ -1381,6 +1381,36 @@ void hrtimer_interrupt(struct clock_event_device *dev) raise_softirq(HRTIMER_SOFTIRQ); } /** * hrtimer_peek_ahead_timers -- run soft-expired timers now * * hrtimer_peek_ahead_timers will peek at the timer queue of * the current cpu and check if there are any timers for which * the soft expires time has passed. If any such timers exist, * they are run immediately and then removed from the timer queue. * */ void hrtimer_peek_ahead_timers(void) { unsigned long flags; struct tick_device *td; struct clock_event_device *dev; if (hrtimer_hres_active()) return; local_irq_save(flags); td = &__get_cpu_var(tick_cpu_device); if (!td) goto out; dev = td->evtdev; if (!dev) goto out; hrtimer_interrupt(dev); out: local_irq_restore(flags); } static void run_hrtimer_softirq(struct softirq_action *h) { run_hrtimer_pending(&__get_cpu_var(hrtimer_bases)); Loading Loading @@ -1563,9 +1593,14 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, struct restart_block *restart; struct hrtimer_sleeper t; int ret = 0; unsigned long slack; slack = current->timer_slack_ns; if (rt_task(current)) slack = 0; hrtimer_init_on_stack(&t.timer, clockid, mode); hrtimer_set_expires(&t.timer, timespec_to_ktime(*rqtp)); hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack); if (do_nanosleep(&t, mode)) goto out; Loading