[PATCH 1/2] Add round_jiffies_up and related routines - Kernel

This is a discussion on [PATCH 1/2] Add round_jiffies_up and related routines - Kernel ; This patch (as1158) 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 ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: [PATCH 1/2] Add round_jiffies_up and related routines

  1. [PATCH 1/2] Add round_jiffies_up and related routines

    This patch (as1158) 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

    ---

    Jens:

    This doesn't have anything to do with the block layer. But the second
    patch in this series does, and it uses round_jiffies_up(). Therefore I
    thought it would be appropriate to submit this through you.

    Alan Stern


    Index: usb-2.6/include/linux/timer.h
    ================================================== =================
    --- usb-2.6.orig/include/linux/timer.h
    +++ usb-2.6/include/linux/timer.h
    @@ -186,4 +186,9 @@ unsigned long __round_jiffies_relative(u
    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
    Index: usb-2.6/kernel/timer.c
    ================================================== =================
    --- usb-2.6.orig/kernel/timer.c
    +++ usb-2.6/kernel/timer.c
    @@ -112,27 +112,8 @@ timer_set_base(struct timer_list *timer,
    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 l
    * 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 l
    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;
    +
    + barrier(); /* Prevent the compiler from aliasing j0 and jiffies */
    + return round_jiffies_common(j + j0, cpu, false) - j0;
    }
    EXPORT_SYMBOL_GPL(__round_jiffies_relative);

    @@ -218,7 +222,7 @@ EXPORT_SYMBOL_GPL(__round_jiffies_relati
    */
    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(uns
    }
    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;
    +
    + barrier(); /* Prevent the compiler from aliasing j0 and jiffies */
    + 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)

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [PATCH 1/2] Add round_jiffies_up and related routines

    Alan Stern wrote:
    > This patch (as1158) 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


    Heh... I have exactly the same patches but mines were named
    round_up_jiffies().

    > + unsigned long j0 = jiffies;
    > +
    > + barrier(); /* Prevent the compiler from aliasing j0 and jiffies */
    > + return round_jiffies_common(j + j0, cpu, false) - j0;


    jiffies is volatile. No need for explicit barrier, but this part is
    necessary for correct operation as if jiffies go up by two the
    calculation will wrap and the returned value will be very large. I
    think this fix deserves a separate patch and proper explanation.

    Thanks.

    --
    tejun
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. Re: [PATCH 1/2] Add round_jiffies_up and related routines

    On Wed, 5 Nov 2008, Tejun Heo wrote:

    > Alan Stern wrote:
    > > This patch (as1158) 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

    >
    > Heh... I have exactly the same patches but mines were named
    > round_up_jiffies().


    To an American, "round_up_jiffies" sounds like something a cowboy might
    do. :-)

    I haven't bothered to look throughout the kernel to see where
    round_jiffies_up() could be used. Have you done this?

    > > + unsigned long j0 = jiffies;
    > > +
    > > + barrier(); /* Prevent the compiler from aliasing j0 and jiffies */
    > > + return round_jiffies_common(j + j0, cpu, false) - j0;

    >
    > jiffies is volatile. No need for explicit barrier,


    I didn't realize that. Good, it makes things easier.

    > but this part is
    > necessary for correct operation as if jiffies go up by two the
    > calculation will wrap and the returned value will be very large. I
    > think this fix deserves a separate patch and proper explanation.


    How about if I remove the barrier() call? Should this new code still
    go in a separate patch?

    Alan Stern

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. Re: [PATCH 1/2] Add round_jiffies_up and related routines

    On Wed, Nov 05 2008, Alan Stern wrote:
    > On Wed, 5 Nov 2008, Tejun Heo wrote:
    >
    > > Alan Stern wrote:
    > > > This patch (as1158) 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

    > >
    > > Heh... I have exactly the same patches but mines were named
    > > round_up_jiffies().

    >
    > To an American, "round_up_jiffies" sounds like something a cowboy might
    > do. :-)
    >
    > I haven't bothered to look throughout the kernel to see where
    > round_jiffies_up() could be used. Have you done this?


    Heh, I do agree :-)

    > > > + unsigned long j0 = jiffies;
    > > > +
    > > > + barrier(); /* Prevent the compiler from aliasing j0 and jiffies */
    > > > + return round_jiffies_common(j + j0, cpu, false) - j0;

    > >
    > > jiffies is volatile. No need for explicit barrier,

    >
    > I didn't realize that. Good, it makes things easier.
    >
    > > but this part is
    > > necessary for correct operation as if jiffies go up by two the
    > > calculation will wrap and the returned value will be very large. I
    > > think this fix deserves a separate patch and proper explanation.

    >
    > How about if I remove the barrier() call? Should this new code still
    > go in a separate patch?


    I think it's fine as-is without the barrier. Can you resend it as such,
    makes it easier to merge up (plus, it does need a new signed-off-by).

    --
    Jens Axboe

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. [PATCH 1/2 ver 2] 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

    ---

    No barriers this time.


    Index: usb-2.6/include/linux/timer.h
    ================================================== =================
    --- usb-2.6.orig/include/linux/timer.h
    +++ usb-2.6/include/linux/timer.h
    @@ -186,4 +186,9 @@ unsigned long __round_jiffies_relative(u
    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
    Index: usb-2.6/kernel/timer.c
    ================================================== =================
    --- usb-2.6.orig/kernel/timer.c
    +++ usb-2.6/kernel/timer.c
    @@ -112,27 +112,8 @@ timer_set_base(struct timer_list *timer,
    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 l
    * 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 l
    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_relati
    */
    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(uns
    }
    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)

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. Re: [PATCH 1/2 ver 2] Add round_jiffies_up and related routines

    On Wed, Nov 05 2008, Alan Stern wrote:
    > 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.


    Thanks Alan, applied 1-2 for 2.6.28.

    --
    Jens Axboe

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread