aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tick.h7
-rw-r--r--kernel/softirq.c10
-rw-r--r--kernel/time/tick-sched.c13
3 files changed, 18 insertions, 12 deletions
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 98921a3e1aa8..b6ec8189ac0c 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -96,9 +96,11 @@ extern cpumask_t *tick_get_broadcast_oneshot_mask(void);
96extern void tick_clock_notify(void); 96extern void tick_clock_notify(void);
97extern int tick_check_oneshot_change(int allow_nohz); 97extern int tick_check_oneshot_change(int allow_nohz);
98extern struct tick_sched *tick_get_tick_sched(int cpu); 98extern struct tick_sched *tick_get_tick_sched(int cpu);
99extern void tick_check_idle(int cpu);
99# else 100# else
100static inline void tick_clock_notify(void) { } 101static inline void tick_clock_notify(void) { }
101static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } 102static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
103static inline void tick_check_idle(int cpu) { }
102# endif 104# endif
103 105
104#else /* CONFIG_GENERIC_CLOCKEVENTS */ 106#else /* CONFIG_GENERIC_CLOCKEVENTS */
@@ -106,26 +108,23 @@ static inline void tick_init(void) { }
106static inline void tick_cancel_sched_timer(int cpu) { } 108static inline void tick_cancel_sched_timer(int cpu) { }
107static inline void tick_clock_notify(void) { } 109static inline void tick_clock_notify(void) { }
108static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } 110static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
111static inline void tick_check_idle(int cpu) { }
109#endif /* !CONFIG_GENERIC_CLOCKEVENTS */ 112#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
110 113
111# ifdef CONFIG_NO_HZ 114# ifdef CONFIG_NO_HZ
112extern void tick_nohz_stop_sched_tick(int inidle); 115extern void tick_nohz_stop_sched_tick(int inidle);
113extern void tick_nohz_restart_sched_tick(void); 116extern void tick_nohz_restart_sched_tick(void);
114extern void tick_nohz_update_jiffies(void);
115extern ktime_t tick_nohz_get_sleep_length(void); 117extern ktime_t tick_nohz_get_sleep_length(void);
116extern void tick_nohz_stop_idle(int cpu);
117extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); 118extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
118# else 119# else
119static inline void tick_nohz_stop_sched_tick(int inidle) { } 120static inline void tick_nohz_stop_sched_tick(int inidle) { }
120static inline void tick_nohz_restart_sched_tick(void) { } 121static inline void tick_nohz_restart_sched_tick(void) { }
121static inline void tick_nohz_update_jiffies(void) { }
122static inline ktime_t tick_nohz_get_sleep_length(void) 122static inline ktime_t tick_nohz_get_sleep_length(void)
123{ 123{
124 ktime_t len = { .tv64 = NSEC_PER_SEC/HZ }; 124 ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
125 125
126 return len; 126 return len;
127} 127}
128static inline void tick_nohz_stop_idle(int cpu) { }
129static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } 128static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
130# endif /* !NO_HZ */ 129# endif /* !NO_HZ */
131 130
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 37d67aa2d56f..d410014279e7 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -265,16 +265,12 @@ asmlinkage void do_softirq(void)
265 */ 265 */
266void irq_enter(void) 266void irq_enter(void)
267{ 267{
268#ifdef CONFIG_NO_HZ
269 int cpu = smp_processor_id(); 268 int cpu = smp_processor_id();
269
270 if (idle_cpu(cpu) && !in_interrupt()) 270 if (idle_cpu(cpu) && !in_interrupt())
271 tick_nohz_stop_idle(cpu); 271 tick_check_idle(cpu);
272#endif 272
273 __irq_enter(); 273 __irq_enter();
274#ifdef CONFIG_NO_HZ
275 if (idle_cpu(cpu))
276 tick_nohz_update_jiffies();
277#endif
278} 274}
279 275
280#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED 276#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index b711ffcb106c..fdcf3f93bb8d 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -155,7 +155,7 @@ void tick_nohz_update_jiffies(void)
155 touch_softlockup_watchdog(); 155 touch_softlockup_watchdog();
156} 156}
157 157
158void tick_nohz_stop_idle(int cpu) 158static void tick_nohz_stop_idle(int cpu)
159{ 159{
160 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 160 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
161 161
@@ -559,6 +559,17 @@ static inline void tick_nohz_switch_to_nohz(void) { }
559#endif /* NO_HZ */ 559#endif /* NO_HZ */
560 560
561/* 561/*
562 * Called from irq_enter to notify about the possible interruption of idle()
563 */
564void tick_check_idle(int cpu)
565{
566#ifdef CONFIG_NO_HZ
567 tick_nohz_stop_idle(cpu);
568 tick_nohz_update_jiffies();
569#endif
570}
571
572/*
562 * High resolution timer specific code 573 * High resolution timer specific code
563 */ 574 */
564#ifdef CONFIG_HIGH_RES_TIMERS 575#ifdef CONFIG_HIGH_RES_TIMERS