diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/hardirq.h | 12 | ||||
-rw-r--r-- | include/linux/hrtimer.h | 6 | ||||
-rw-r--r-- | include/linux/tick.h | 71 |
3 files changed, 86 insertions, 3 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 6f657d7f2d04..7803014f3a11 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -106,6 +106,16 @@ static inline void account_system_vtime(struct task_struct *tsk) | |||
106 | * always balanced, so the interrupted value of ->hardirq_context | 106 | * always balanced, so the interrupted value of ->hardirq_context |
107 | * will always be restored. | 107 | * will always be restored. |
108 | */ | 108 | */ |
109 | #define __irq_enter() \ | ||
110 | do { \ | ||
111 | account_system_vtime(current); \ | ||
112 | add_preempt_count(HARDIRQ_OFFSET); \ | ||
113 | trace_hardirq_enter(); \ | ||
114 | } while (0) | ||
115 | |||
116 | /* | ||
117 | * Enter irq context (on NO_HZ, update jiffies): | ||
118 | */ | ||
109 | extern void irq_enter(void); | 119 | extern void irq_enter(void); |
110 | 120 | ||
111 | /* | 121 | /* |
@@ -123,7 +133,7 @@ extern void irq_enter(void); | |||
123 | */ | 133 | */ |
124 | extern void irq_exit(void); | 134 | extern void irq_exit(void); |
125 | 135 | ||
126 | #define nmi_enter() do { lockdep_off(); irq_enter(); } while (0) | 136 | #define nmi_enter() do { lockdep_off(); __irq_enter(); } while (0) |
127 | #define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) | 137 | #define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) |
128 | 138 | ||
129 | #endif /* LINUX_HARDIRQ_H */ | 139 | #endif /* LINUX_HARDIRQ_H */ |
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index a759636fd09f..e95c96c971c0 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -201,4 +201,10 @@ extern void hrtimer_run_queues(void); | |||
201 | /* Bootup initialization: */ | 201 | /* Bootup initialization: */ |
202 | extern void __init hrtimers_init(void); | 202 | extern void __init hrtimers_init(void); |
203 | 203 | ||
204 | #if BITS_PER_LONG < 64 | ||
205 | extern unsigned long ktime_divns(const ktime_t kt, s64 div); | ||
206 | #else /* BITS_PER_LONG < 64 */ | ||
207 | # define ktime_divns(kt, div) (unsigned long)((kt).tv64 / (div)) | ||
208 | #endif | ||
209 | |||
204 | #endif | 210 | #endif |
diff --git a/include/linux/tick.h b/include/linux/tick.h index e5c0a4e22706..cf435e459598 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
@@ -20,12 +20,79 @@ struct tick_device { | |||
20 | enum tick_device_mode mode; | 20 | enum tick_device_mode mode; |
21 | }; | 21 | }; |
22 | 22 | ||
23 | enum tick_nohz_mode { | ||
24 | NOHZ_MODE_INACTIVE, | ||
25 | NOHZ_MODE_LOWRES, | ||
26 | NOHZ_MODE_HIGHRES, | ||
27 | }; | ||
28 | |||
29 | /** | ||
30 | * struct tick_sched - sched tick emulation and no idle tick control/stats | ||
31 | * @sched_timer: hrtimer to schedule the periodic tick in high | ||
32 | * resolution mode | ||
33 | * @idle_tick: Store the last idle tick expiry time when the tick | ||
34 | * timer is modified for idle sleeps. This is necessary | ||
35 | * to resume the tick timer operation in the timeline | ||
36 | * when the CPU returns from idle | ||
37 | * @tick_stopped: Indicator that the idle tick has been stopped | ||
38 | * @idle_jiffies: jiffies at the entry to idle for idle time accounting | ||
39 | * @idle_calls: Total number of idle calls | ||
40 | * @idle_sleeps: Number of idle calls, where the sched tick was stopped | ||
41 | * @idle_entrytime: Time when the idle call was entered | ||
42 | * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped | ||
43 | */ | ||
44 | struct tick_sched { | ||
45 | struct hrtimer sched_timer; | ||
46 | unsigned long check_clocks; | ||
47 | enum tick_nohz_mode nohz_mode; | ||
48 | ktime_t idle_tick; | ||
49 | int tick_stopped; | ||
50 | unsigned long idle_jiffies; | ||
51 | unsigned long idle_calls; | ||
52 | unsigned long idle_sleeps; | ||
53 | ktime_t idle_entrytime; | ||
54 | ktime_t idle_sleeptime; | ||
55 | unsigned long last_jiffies; | ||
56 | unsigned long next_jiffies; | ||
57 | ktime_t idle_expires; | ||
58 | }; | ||
59 | |||
23 | extern void __init tick_init(void); | 60 | extern void __init tick_init(void); |
61 | extern int tick_is_oneshot_available(void); | ||
62 | |||
63 | # ifdef CONFIG_HIGH_RES_TIMERS | ||
64 | extern int tick_init_highres(void); | ||
65 | extern int tick_program_event(ktime_t expires, int force); | ||
66 | extern void tick_setup_sched_timer(void); | ||
67 | extern void tick_cancel_sched_timer(int cpu); | ||
68 | # else | ||
69 | static inline void tick_cancel_sched_timer(int cpu) { } | ||
70 | # endif /* HIGHRES */ | ||
24 | 71 | ||
25 | #else | 72 | # ifdef CONFIG_TICK_ONESHOT |
73 | extern void tick_clock_notify(void); | ||
74 | extern int tick_check_oneshot_change(int allow_nohz); | ||
75 | extern struct tick_sched *tick_get_tick_sched(int cpu); | ||
76 | # else | ||
77 | static inline void tick_clock_notify(void) { } | ||
78 | static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } | ||
79 | # endif | ||
26 | 80 | ||
81 | #else /* CONFIG_GENERIC_CLOCKEVENTS */ | ||
27 | static inline void tick_init(void) { } | 82 | static inline void tick_init(void) { } |
83 | static inline void tick_cancel_sched_timer(int cpu) { } | ||
84 | static inline void tick_clock_notify(void) { } | ||
85 | static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } | ||
86 | #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ | ||
28 | 87 | ||
29 | #endif | 88 | # ifdef CONFIG_NO_HZ |
89 | extern void tick_nohz_stop_sched_tick(void); | ||
90 | extern void tick_nohz_restart_sched_tick(void); | ||
91 | extern void tick_nohz_update_jiffies(void); | ||
92 | # else | ||
93 | static inline void tick_nohz_stop_sched_tick(void) { } | ||
94 | static inline void tick_nohz_restart_sched_tick(void) { } | ||
95 | static inline void tick_nohz_update_jiffies(void) { } | ||
96 | # endif /* !NO_HZ */ | ||
30 | 97 | ||
31 | #endif | 98 | #endif |