lkml.org 
[lkml]   [2009]   [Nov]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH -tip 3/3] define nsecs_to_jiffies()
    Use of msecs_to_jiffies() for nsecs_to_cputime() have some problems:

    - The type of msecs_to_jiffies()'s argument is unsigned int, so
    it cannot convert msecs greater than UINT_MAX = about 49.7 days.
    - msecs_to_jiffies() returns MAX_JIFFY_OFFSET if MSB of argument
    is set, assuming that input was negative value. So it cannot
    convert msecs greater than INT_MAX = about 24.8 days too.

    This patch defines a new function nsecs_to_jiffies() that can deal
    greater values, and that can deal all incoming values as unsigned.

    Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
    ---
    include/linux/jiffies.h | 1 +
    kernel/sched.c | 3 +--
    kernel/time.c | 30 ++++++++++++++++++++++++++++++
    3 files changed, 32 insertions(+), 2 deletions(-)

    diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
    index 1a9cf78..6811f4b 100644
    --- a/include/linux/jiffies.h
    +++ b/include/linux/jiffies.h
    @@ -307,6 +307,7 @@ extern clock_t jiffies_to_clock_t(long x);
    extern unsigned long clock_t_to_jiffies(unsigned long x);
    extern u64 jiffies_64_to_clock_t(u64 x);
    extern u64 nsec_to_clock_t(u64 x);
    +extern unsigned long nsecs_to_jiffies(u64 n);

    #define TIMESTAMP_SIZE 30

    diff --git a/kernel/sched.c b/kernel/sched.c
    index a7093c1..792b25e 100644
    --- a/kernel/sched.c
    +++ b/kernel/sched.c
    @@ -5156,8 +5156,7 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
    #else

    #ifndef nsecs_to_cputime
    -# define nsecs_to_cputime(__nsecs) \
    - msecs_to_cputime(div_u64((__nsecs), NSEC_PER_MSEC))
    +# define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs)
    #endif

    void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
    diff --git a/kernel/time.c b/kernel/time.c
    index 2e2e469..b30016c 100644
    --- a/kernel/time.c
    +++ b/kernel/time.c
    @@ -662,6 +662,36 @@ u64 nsec_to_clock_t(u64 x)
    #endif
    }

    +/**
    + * nsecs_to_jiffies - Convert nsecs in u64 to jiffies
    + *
    + * @n: nsecs in u64
    + *
    + * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64.
    + * And this doesn't return MAX_JIFFY_OFFSET since this function is designed
    + * for scheduler, not for use in device drivers to calculate timeout value.
    + *
    + * note:
    + * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
    + * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
    + */
    +unsigned long nsecs_to_jiffies(u64 n)
    +{
    +#if (NSEC_PER_SEC % HZ) == 0
    + /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */
    + return div_u64(n, NSEC_PER_SEC / HZ);
    +#elif (HZ % 512) == 0
    + /* overflow after 292 years if HZ = 1024 */
    + return div_u64(n * HZ / 512, NSEC_PER_SEC / 512);
    +#else
    + /*
    + * Generic case - optimized for cases where HZ is a multiple of 3.
    + * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc.
    + */
    + return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ);
    +#endif
    +}
    +
    #if (BITS_PER_LONG < 64)
    u64 get_jiffies_64(void)
    {
    --
    1.6.5.3


    \
     
     \ /
      Last update: 2009-11-26 06:53    [W:0.030 / U:0.432 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site