]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/round-jiffies-up
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / round-jiffies-up
1 Subject: Add round_jiffies_up and related routines
2 From: Alan Stern <stern@rowland.harvard.edu>
3 Date: Thu Nov 6 08:42:48 2008 +0100:
4 Git: 9c133c469d38043d5aadaa03f2fb840d88d1cf4f
5 References: bnc#464155
6
7 This patch (as1158b) adds round_jiffies_up() and friends. These
8 routines work like the analogous round_jiffies() functions, except
9 that they will never round down.
10
11 The new routines will be useful for timeouts where we don't care
12 exactly when the timer expires, provided it doesn't expire too soon.
13
14 Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
15 Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
16 Signed-off-by: Hannes Reinecke <hare@suse.de>
17
18 diff --git a/include/linux/timer.h b/include/linux/timer.h
19 index d4ba792..daf9685 100644
20 --- a/include/linux/timer.h
21 +++ b/include/linux/timer.h
22 @@ -186,4 +186,9 @@ unsigned long __round_jiffies_relative(unsigned long j, int cpu);
23 unsigned long round_jiffies(unsigned long j);
24 unsigned long round_jiffies_relative(unsigned long j);
25
26 +unsigned long __round_jiffies_up(unsigned long j, int cpu);
27 +unsigned long __round_jiffies_up_relative(unsigned long j, int cpu);
28 +unsigned long round_jiffies_up(unsigned long j);
29 +unsigned long round_jiffies_up_relative(unsigned long j);
30 +
31 #endif
32 diff --git a/kernel/timer.c b/kernel/timer.c
33 index 56becf3..dbd50fa 100644
34 --- a/kernel/timer.c
35 +++ b/kernel/timer.c
36 @@ -112,27 +112,8 @@ timer_set_base(struct timer_list *timer, struct tvec_base *new_base)
37 tbase_get_deferrable(timer->base));
38 }
39
40 -/**
41 - * __round_jiffies - function to round jiffies to a full second
42 - * @j: the time in (absolute) jiffies that should be rounded
43 - * @cpu: the processor number on which the timeout will happen
44 - *
45 - * __round_jiffies() rounds an absolute time in the future (in jiffies)
46 - * up or down to (approximately) full seconds. This is useful for timers
47 - * for which the exact time they fire does not matter too much, as long as
48 - * they fire approximately every X seconds.
49 - *
50 - * By rounding these timers to whole seconds, all such timers will fire
51 - * at the same time, rather than at various times spread out. The goal
52 - * of this is to have the CPU wake up less, which saves power.
53 - *
54 - * The exact rounding is skewed for each processor to avoid all
55 - * processors firing at the exact same time, which could lead
56 - * to lock contention or spurious cache line bouncing.
57 - *
58 - * The return value is the rounded version of the @j parameter.
59 - */
60 -unsigned long __round_jiffies(unsigned long j, int cpu)
61 +static unsigned long round_jiffies_common(unsigned long j, int cpu,
62 + bool force_up)
63 {
64 int rem;
65 unsigned long original = j;
66 @@ -154,8 +135,9 @@ unsigned long __round_jiffies(unsigned long j, int cpu)
67 * due to delays of the timer irq, long irq off times etc etc) then
68 * we should round down to the whole second, not up. Use 1/4th second
69 * as cutoff for this rounding as an extreme upper bound for this.
70 + * But never round down if @force_up is set.
71 */
72 - if (rem < HZ/4) /* round down */
73 + if (rem < HZ/4 && !force_up) /* round down */
74 j = j - rem;
75 else /* round up */
76 j = j - rem + HZ;
77 @@ -167,6 +149,31 @@ unsigned long __round_jiffies(unsigned long j, int cpu)
78 return original;
79 return j;
80 }
81 +
82 +/**
83 + * __round_jiffies - function to round jiffies to a full second
84 + * @j: the time in (absolute) jiffies that should be rounded
85 + * @cpu: the processor number on which the timeout will happen
86 + *
87 + * __round_jiffies() rounds an absolute time in the future (in jiffies)
88 + * up or down to (approximately) full seconds. This is useful for timers
89 + * for which the exact time they fire does not matter too much, as long as
90 + * they fire approximately every X seconds.
91 + *
92 + * By rounding these timers to whole seconds, all such timers will fire
93 + * at the same time, rather than at various times spread out. The goal
94 + * of this is to have the CPU wake up less, which saves power.
95 + *
96 + * The exact rounding is skewed for each processor to avoid all
97 + * processors firing at the exact same time, which could lead
98 + * to lock contention or spurious cache line bouncing.
99 + *
100 + * The return value is the rounded version of the @j parameter.
101 + */
102 +unsigned long __round_jiffies(unsigned long j, int cpu)
103 +{
104 + return round_jiffies_common(j, cpu, false);
105 +}
106 EXPORT_SYMBOL_GPL(__round_jiffies);
107
108 /**
109 @@ -191,13 +198,10 @@ EXPORT_SYMBOL_GPL(__round_jiffies);
110 */
111 unsigned long __round_jiffies_relative(unsigned long j, int cpu)
112 {
113 - /*
114 - * In theory the following code can skip a jiffy in case jiffies
115 - * increments right between the addition and the later subtraction.
116 - * However since the entire point of this function is to use approximate
117 - * timeouts, it's entirely ok to not handle that.
118 - */
119 - return __round_jiffies(j + jiffies, cpu) - jiffies;
120 + unsigned long j0 = jiffies;
121 +
122 + /* Use j0 because jiffies might change while we run */
123 + return round_jiffies_common(j + j0, cpu, false) - j0;
124 }
125 EXPORT_SYMBOL_GPL(__round_jiffies_relative);
126
127 @@ -218,7 +222,7 @@ EXPORT_SYMBOL_GPL(__round_jiffies_relative);
128 */
129 unsigned long round_jiffies(unsigned long j)
130 {
131 - return __round_jiffies(j, raw_smp_processor_id());
132 + return round_jiffies_common(j, raw_smp_processor_id(), false);
133 }
134 EXPORT_SYMBOL_GPL(round_jiffies);
135
136 @@ -243,6 +247,71 @@ unsigned long round_jiffies_relative(unsigned long j)
137 }
138 EXPORT_SYMBOL_GPL(round_jiffies_relative);
139
140 +/**
141 + * __round_jiffies_up - function to round jiffies up to a full second
142 + * @j: the time in (absolute) jiffies that should be rounded
143 + * @cpu: the processor number on which the timeout will happen
144 + *
145 + * This is the same as __round_jiffies() except that it will never
146 + * round down. This is useful for timeouts for which the exact time
147 + * of firing does not matter too much, as long as they don't fire too
148 + * early.
149 + */
150 +unsigned long __round_jiffies_up(unsigned long j, int cpu)
151 +{
152 + return round_jiffies_common(j, cpu, true);
153 +}
154 +EXPORT_SYMBOL_GPL(__round_jiffies_up);
155 +
156 +/**
157 + * __round_jiffies_up_relative - function to round jiffies up to a full second
158 + * @j: the time in (relative) jiffies that should be rounded
159 + * @cpu: the processor number on which the timeout will happen
160 + *
161 + * This is the same as __round_jiffies_relative() except that it will never
162 + * round down. This is useful for timeouts for which the exact time
163 + * of firing does not matter too much, as long as they don't fire too
164 + * early.
165 + */
166 +unsigned long __round_jiffies_up_relative(unsigned long j, int cpu)
167 +{
168 + unsigned long j0 = jiffies;
169 +
170 + /* Use j0 because jiffies might change while we run */
171 + return round_jiffies_common(j + j0, cpu, true) - j0;
172 +}
173 +EXPORT_SYMBOL_GPL(__round_jiffies_up_relative);
174 +
175 +/**
176 + * round_jiffies_up - function to round jiffies up to a full second
177 + * @j: the time in (absolute) jiffies that should be rounded
178 + *
179 + * This is the same as round_jiffies() except that it will never
180 + * round down. This is useful for timeouts for which the exact time
181 + * of firing does not matter too much, as long as they don't fire too
182 + * early.
183 + */
184 +unsigned long round_jiffies_up(unsigned long j)
185 +{
186 + return round_jiffies_common(j, raw_smp_processor_id(), true);
187 +}
188 +EXPORT_SYMBOL_GPL(round_jiffies_up);
189 +
190 +/**
191 + * round_jiffies_up_relative - function to round jiffies up to a full second
192 + * @j: the time in (relative) jiffies that should be rounded
193 + *
194 + * This is the same as round_jiffies_relative() except that it will never
195 + * round down. This is useful for timeouts for which the exact time
196 + * of firing does not matter too much, as long as they don't fire too
197 + * early.
198 + */
199 +unsigned long round_jiffies_up_relative(unsigned long j)
200 +{
201 + return __round_jiffies_up_relative(j, raw_smp_processor_id());
202 +}
203 +EXPORT_SYMBOL_GPL(round_jiffies_up_relative);
204 +
205
206 static inline void set_running_timer(struct tvec_base *base,
207 struct timer_list *timer)