aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2007-02-16 04:28:03 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:13:59 -0500
commit79bf2bb335b85db25d27421c798595a2fa2a0e82 (patch)
tree550ec2654ae1dd65b871de7fe9c890108c6e86d8 /include/linux
parentf8381cba04ba8173fd5a2b8e5cd8b3290ee13a98 (diff)
[PATCH] tick-management: dyntick / highres functionality
With Ingo Molnar <mingo@elte.hu> Add functions to provide dynamic ticks and high resolution timers. The code which keeps track of jiffies and handles the long idle periods is shared between tick based and high resolution timer based dynticks. The dyntick functionality can be disabled on the kernel commandline. Provide also the infrastructure to support high resolution timers. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/hardirq.h12
-rw-r--r--include/linux/hrtimer.h6
-rw-r--r--include/linux/tick.h71
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 */
109extern void irq_enter(void); 119extern void irq_enter(void);
110 120
111/* 121/*
@@ -123,7 +133,7 @@ extern void irq_enter(void);
123 */ 133 */
124extern void irq_exit(void); 134extern 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: */
202extern void __init hrtimers_init(void); 202extern void __init hrtimers_init(void);
203 203
204#if BITS_PER_LONG < 64
205extern 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
23enum 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 */
44struct 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
23extern void __init tick_init(void); 60extern void __init tick_init(void);
61extern int tick_is_oneshot_available(void);
62
63# ifdef CONFIG_HIGH_RES_TIMERS
64extern int tick_init_highres(void);
65extern int tick_program_event(ktime_t expires, int force);
66extern void tick_setup_sched_timer(void);
67extern void tick_cancel_sched_timer(int cpu);
68# else
69static inline void tick_cancel_sched_timer(int cpu) { }
70# endif /* HIGHRES */
24 71
25#else 72# ifdef CONFIG_TICK_ONESHOT
73extern void tick_clock_notify(void);
74extern int tick_check_oneshot_change(int allow_nohz);
75extern struct tick_sched *tick_get_tick_sched(int cpu);
76# else
77static inline void tick_clock_notify(void) { }
78static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
79# endif
26 80
81#else /* CONFIG_GENERIC_CLOCKEVENTS */
27static inline void tick_init(void) { } 82static inline void tick_init(void) { }
83static inline void tick_cancel_sched_timer(int cpu) { }
84static inline void tick_clock_notify(void) { }
85static 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
89extern void tick_nohz_stop_sched_tick(void);
90extern void tick_nohz_restart_sched_tick(void);
91extern void tick_nohz_update_jiffies(void);
92# else
93static inline void tick_nohz_stop_sched_tick(void) { }
94static inline void tick_nohz_restart_sched_tick(void) { }
95static inline void tick_nohz_update_jiffies(void) { }
96# endif /* !NO_HZ */
30 97
31#endif 98#endif