]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blobdiff - 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
diff --git a/src/patches/suse-2.6.27.31/patches.fixes/round-jiffies-up b/src/patches/suse-2.6.27.31/patches.fixes/round-jiffies-up
new file mode 100644 (file)
index 0000000..9362296
--- /dev/null
@@ -0,0 +1,207 @@
+Subject: Add round_jiffies_up and related routines
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu Nov 6 08:42:48 2008 +0100:
+Git: 9c133c469d38043d5aadaa03f2fb840d88d1cf4f
+References: bnc#464155
+
+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>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/include/linux/timer.h b/include/linux/timer.h
+index d4ba792..daf9685 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -186,4 +186,9 @@ unsigned long __round_jiffies_relative(unsigned long j, int cpu);
+ unsigned long round_jiffies(unsigned long j);
+ unsigned long round_jiffies_relative(unsigned long j);
++unsigned long __round_jiffies_up(unsigned long j, int cpu);
++unsigned long __round_jiffies_up_relative(unsigned long j, int cpu);
++unsigned long round_jiffies_up(unsigned long j);
++unsigned long round_jiffies_up_relative(unsigned long j);
++
+ #endif
+diff --git a/kernel/timer.c b/kernel/timer.c
+index 56becf3..dbd50fa 100644
+--- a/kernel/timer.c
++++ b/kernel/timer.c
+@@ -112,27 +112,8 @@ timer_set_base(struct timer_list *timer, struct tvec_base *new_base)
+                                     tbase_get_deferrable(timer->base));
+ }
+-/**
+- * __round_jiffies - function to round jiffies to a full second
+- * @j: the time in (absolute) jiffies that should be rounded
+- * @cpu: the processor number on which the timeout will happen
+- *
+- * __round_jiffies() rounds an absolute time in the future (in jiffies)
+- * up or down to (approximately) full seconds. This is useful for timers
+- * for which the exact time they fire does not matter too much, as long as
+- * they fire approximately every X seconds.
+- *
+- * By rounding these timers to whole seconds, all such timers will fire
+- * at the same time, rather than at various times spread out. The goal
+- * of this is to have the CPU wake up less, which saves power.
+- *
+- * The exact rounding is skewed for each processor to avoid all
+- * processors firing at the exact same time, which could lead
+- * to lock contention or spurious cache line bouncing.
+- *
+- * The return value is the rounded version of the @j parameter.
+- */
+-unsigned long __round_jiffies(unsigned long j, int cpu)
++static unsigned long round_jiffies_common(unsigned long j, int cpu,
++              bool force_up)
+ {
+       int rem;
+       unsigned long original = j;
+@@ -154,8 +135,9 @@ unsigned long __round_jiffies(unsigned long j, int cpu)
+        * due to delays of the timer irq, long irq off times etc etc) then
+        * we should round down to the whole second, not up. Use 1/4th second
+        * as cutoff for this rounding as an extreme upper bound for this.
++       * But never round down if @force_up is set.
+        */
+-      if (rem < HZ/4) /* round down */
++      if (rem < HZ/4 && !force_up) /* round down */
+               j = j - rem;
+       else /* round up */
+               j = j - rem + HZ;
+@@ -167,6 +149,31 @@ unsigned long __round_jiffies(unsigned long j, int cpu)
+               return original;
+       return j;
+ }
++
++/**
++ * __round_jiffies - function to round jiffies to a full second
++ * @j: the time in (absolute) jiffies that should be rounded
++ * @cpu: the processor number on which the timeout will happen
++ *
++ * __round_jiffies() rounds an absolute time in the future (in jiffies)
++ * up or down to (approximately) full seconds. This is useful for timers
++ * for which the exact time they fire does not matter too much, as long as
++ * they fire approximately every X seconds.
++ *
++ * By rounding these timers to whole seconds, all such timers will fire
++ * at the same time, rather than at various times spread out. The goal
++ * of this is to have the CPU wake up less, which saves power.
++ *
++ * The exact rounding is skewed for each processor to avoid all
++ * processors firing at the exact same time, which could lead
++ * to lock contention or spurious cache line bouncing.
++ *
++ * The return value is the rounded version of the @j parameter.
++ */
++unsigned long __round_jiffies(unsigned long j, int cpu)
++{
++      return round_jiffies_common(j, cpu, false);
++}
+ EXPORT_SYMBOL_GPL(__round_jiffies);
+ /**
+@@ -191,13 +198,10 @@ EXPORT_SYMBOL_GPL(__round_jiffies);
+  */
+ unsigned long __round_jiffies_relative(unsigned long j, int cpu)
+ {
+-      /*
+-       * In theory the following code can skip a jiffy in case jiffies
+-       * increments right between the addition and the later subtraction.
+-       * However since the entire point of this function is to use approximate
+-       * timeouts, it's entirely ok to not handle that.
+-       */
+-      return  __round_jiffies(j + jiffies, cpu) - jiffies;
++      unsigned long j0 = jiffies;
++
++      /* Use j0 because jiffies might change while we run */
++      return round_jiffies_common(j + j0, cpu, false) - j0;
+ }
+ EXPORT_SYMBOL_GPL(__round_jiffies_relative);
+@@ -218,7 +222,7 @@ EXPORT_SYMBOL_GPL(__round_jiffies_relative);
+  */
+ unsigned long round_jiffies(unsigned long j)
+ {
+-      return __round_jiffies(j, raw_smp_processor_id());
++      return round_jiffies_common(j, raw_smp_processor_id(), false);
+ }
+ EXPORT_SYMBOL_GPL(round_jiffies);
+@@ -243,6 +247,71 @@ unsigned long round_jiffies_relative(unsigned long j)
+ }
+ EXPORT_SYMBOL_GPL(round_jiffies_relative);
++/**
++ * __round_jiffies_up - function to round jiffies up to a full second
++ * @j: the time in (absolute) jiffies that should be rounded
++ * @cpu: the processor number on which the timeout will happen
++ *
++ * This is the same as __round_jiffies() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long __round_jiffies_up(unsigned long j, int cpu)
++{
++      return round_jiffies_common(j, cpu, true);
++}
++EXPORT_SYMBOL_GPL(__round_jiffies_up);
++
++/**
++ * __round_jiffies_up_relative - function to round jiffies up to a full second
++ * @j: the time in (relative) jiffies that should be rounded
++ * @cpu: the processor number on which the timeout will happen
++ *
++ * This is the same as __round_jiffies_relative() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long __round_jiffies_up_relative(unsigned long j, int cpu)
++{
++      unsigned long j0 = jiffies;
++
++      /* Use j0 because jiffies might change while we run */
++      return round_jiffies_common(j + j0, cpu, true) - j0;
++}
++EXPORT_SYMBOL_GPL(__round_jiffies_up_relative);
++
++/**
++ * round_jiffies_up - function to round jiffies up to a full second
++ * @j: the time in (absolute) jiffies that should be rounded
++ *
++ * This is the same as round_jiffies() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long round_jiffies_up(unsigned long j)
++{
++      return round_jiffies_common(j, raw_smp_processor_id(), true);
++}
++EXPORT_SYMBOL_GPL(round_jiffies_up);
++
++/**
++ * round_jiffies_up_relative - function to round jiffies up to a full second
++ * @j: the time in (relative) jiffies that should be rounded
++ *
++ * This is the same as round_jiffies_relative() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long round_jiffies_up_relative(unsigned long j)
++{
++      return __round_jiffies_up_relative(j, raw_smp_processor_id());
++}
++EXPORT_SYMBOL_GPL(round_jiffies_up_relative);
++
+ static inline void set_running_timer(struct tvec_base *base,
+                                       struct timer_list *timer)