Commit 9c133c469d38043d5aadaa03f2fb840d88d1cf4f

Authored by Alan Stern
Committed by Jens Axboe
1 parent 89f97496e8

Add round_jiffies_up and related routines

This patch (as1158b) adds round_jiffies_up() and friends.  These
routines work like the analogous round_jiffies() functions, except
that they will never round down.

The new routines will be useful for timeouts where we don't care
exactly when the timer expires, provided it doesn't expire too soon.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

Showing 2 changed files with 104 additions and 30 deletions Side-by-side Diff

include/linux/timer.h
... ... @@ -186,5 +186,10 @@
186 186 unsigned long round_jiffies(unsigned long j);
187 187 unsigned long round_jiffies_relative(unsigned long j);
188 188  
  189 +unsigned long __round_jiffies_up(unsigned long j, int cpu);
  190 +unsigned long __round_jiffies_up_relative(unsigned long j, int cpu);
  191 +unsigned long round_jiffies_up(unsigned long j);
  192 +unsigned long round_jiffies_up_relative(unsigned long j);
  193 +
189 194 #endif
... ... @@ -112,27 +112,8 @@
112 112 tbase_get_deferrable(timer->base));
113 113 }
114 114  
115   -/**
116   - * __round_jiffies - function to round jiffies to a full second
117   - * @j: the time in (absolute) jiffies that should be rounded
118   - * @cpu: the processor number on which the timeout will happen
119   - *
120   - * __round_jiffies() rounds an absolute time in the future (in jiffies)
121   - * up or down to (approximately) full seconds. This is useful for timers
122   - * for which the exact time they fire does not matter too much, as long as
123   - * they fire approximately every X seconds.
124   - *
125   - * By rounding these timers to whole seconds, all such timers will fire
126   - * at the same time, rather than at various times spread out. The goal
127   - * of this is to have the CPU wake up less, which saves power.
128   - *
129   - * The exact rounding is skewed for each processor to avoid all
130   - * processors firing at the exact same time, which could lead
131   - * to lock contention or spurious cache line bouncing.
132   - *
133   - * The return value is the rounded version of the @j parameter.
134   - */
135   -unsigned long __round_jiffies(unsigned long j, int cpu)
  115 +static unsigned long round_jiffies_common(unsigned long j, int cpu,
  116 + bool force_up)
136 117 {
137 118 int rem;
138 119 unsigned long original = j;
139 120  
... ... @@ -154,8 +135,9 @@
154 135 * due to delays of the timer irq, long irq off times etc etc) then
155 136 * we should round down to the whole second, not up. Use 1/4th second
156 137 * as cutoff for this rounding as an extreme upper bound for this.
  138 + * But never round down if @force_up is set.
157 139 */
158   - if (rem < HZ/4) /* round down */
  140 + if (rem < HZ/4 && !force_up) /* round down */
159 141 j = j - rem;
160 142 else /* round up */
161 143 j = j - rem + HZ;
... ... @@ -167,6 +149,31 @@
167 149 return original;
168 150 return j;
169 151 }
  152 +
  153 +/**
  154 + * __round_jiffies - function to round jiffies to a full second
  155 + * @j: the time in (absolute) jiffies that should be rounded
  156 + * @cpu: the processor number on which the timeout will happen
  157 + *
  158 + * __round_jiffies() rounds an absolute time in the future (in jiffies)
  159 + * up or down to (approximately) full seconds. This is useful for timers
  160 + * for which the exact time they fire does not matter too much, as long as
  161 + * they fire approximately every X seconds.
  162 + *
  163 + * By rounding these timers to whole seconds, all such timers will fire
  164 + * at the same time, rather than at various times spread out. The goal
  165 + * of this is to have the CPU wake up less, which saves power.
  166 + *
  167 + * The exact rounding is skewed for each processor to avoid all
  168 + * processors firing at the exact same time, which could lead
  169 + * to lock contention or spurious cache line bouncing.
  170 + *
  171 + * The return value is the rounded version of the @j parameter.
  172 + */
  173 +unsigned long __round_jiffies(unsigned long j, int cpu)
  174 +{
  175 + return round_jiffies_common(j, cpu, false);
  176 +}
170 177 EXPORT_SYMBOL_GPL(__round_jiffies);
171 178  
172 179 /**
... ... @@ -191,13 +198,10 @@
191 198 */
192 199 unsigned long __round_jiffies_relative(unsigned long j, int cpu)
193 200 {
194   - /*
195   - * In theory the following code can skip a jiffy in case jiffies
196   - * increments right between the addition and the later subtraction.
197   - * However since the entire point of this function is to use approximate
198   - * timeouts, it's entirely ok to not handle that.
199   - */
200   - return __round_jiffies(j + jiffies, cpu) - jiffies;
  201 + unsigned long j0 = jiffies;
  202 +
  203 + /* Use j0 because jiffies might change while we run */
  204 + return round_jiffies_common(j + j0, cpu, false) - j0;
201 205 }
202 206 EXPORT_SYMBOL_GPL(__round_jiffies_relative);
203 207  
... ... @@ -218,7 +222,7 @@
218 222 */
219 223 unsigned long round_jiffies(unsigned long j)
220 224 {
221   - return __round_jiffies(j, raw_smp_processor_id());
  225 + return round_jiffies_common(j, raw_smp_processor_id(), false);
222 226 }
223 227 EXPORT_SYMBOL_GPL(round_jiffies);
224 228  
... ... @@ -242,6 +246,71 @@
242 246 return __round_jiffies_relative(j, raw_smp_processor_id());
243 247 }
244 248 EXPORT_SYMBOL_GPL(round_jiffies_relative);
  249 +
  250 +/**
  251 + * __round_jiffies_up - function to round jiffies up to a full second
  252 + * @j: the time in (absolute) jiffies that should be rounded
  253 + * @cpu: the processor number on which the timeout will happen
  254 + *
  255 + * This is the same as __round_jiffies() except that it will never
  256 + * round down. This is useful for timeouts for which the exact time
  257 + * of firing does not matter too much, as long as they don't fire too
  258 + * early.
  259 + */
  260 +unsigned long __round_jiffies_up(unsigned long j, int cpu)
  261 +{
  262 + return round_jiffies_common(j, cpu, true);
  263 +}
  264 +EXPORT_SYMBOL_GPL(__round_jiffies_up);
  265 +
  266 +/**
  267 + * __round_jiffies_up_relative - function to round jiffies up to a full second
  268 + * @j: the time in (relative) jiffies that should be rounded
  269 + * @cpu: the processor number on which the timeout will happen
  270 + *
  271 + * This is the same as __round_jiffies_relative() except that it will never
  272 + * round down. This is useful for timeouts for which the exact time
  273 + * of firing does not matter too much, as long as they don't fire too
  274 + * early.
  275 + */
  276 +unsigned long __round_jiffies_up_relative(unsigned long j, int cpu)
  277 +{
  278 + unsigned long j0 = jiffies;
  279 +
  280 + /* Use j0 because jiffies might change while we run */
  281 + return round_jiffies_common(j + j0, cpu, true) - j0;
  282 +}
  283 +EXPORT_SYMBOL_GPL(__round_jiffies_up_relative);
  284 +
  285 +/**
  286 + * round_jiffies_up - function to round jiffies up to a full second
  287 + * @j: the time in (absolute) jiffies that should be rounded
  288 + *
  289 + * This is the same as round_jiffies() except that it will never
  290 + * round down. This is useful for timeouts for which the exact time
  291 + * of firing does not matter too much, as long as they don't fire too
  292 + * early.
  293 + */
  294 +unsigned long round_jiffies_up(unsigned long j)
  295 +{
  296 + return round_jiffies_common(j, raw_smp_processor_id(), true);
  297 +}
  298 +EXPORT_SYMBOL_GPL(round_jiffies_up);
  299 +
  300 +/**
  301 + * round_jiffies_up_relative - function to round jiffies up to a full second
  302 + * @j: the time in (relative) jiffies that should be rounded
  303 + *
  304 + * This is the same as round_jiffies_relative() except that it will never
  305 + * round down. This is useful for timeouts for which the exact time
  306 + * of firing does not matter too much, as long as they don't fire too
  307 + * early.
  308 + */
  309 +unsigned long round_jiffies_up_relative(unsigned long j)
  310 +{
  311 + return __round_jiffies_up_relative(j, raw_smp_processor_id());
  312 +}
  313 +EXPORT_SYMBOL_GPL(round_jiffies_up_relative);
245 314  
246 315  
247 316 static inline void set_running_timer(struct tvec_base *base,