Messages in this thread Patch in this message | | | Subject | [PATCH -mm2] ktimers rounding fix | From | Thomas Gleixner <> | Date | Wed, 23 Nov 2005 11:17:04 +0100 |
| |
The rounding for the 64bit scalar representation was taking only the lower 32bit into account, which is wrong because 2^32 is not a multiple of 10. The patch implements seperate ktime_modulo macros / functions for the hybrid and the scalar representation of ktime_t.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Index: linux-2.6.15-rc1-mm2/include/linux/ktime.h =================================================================== --- linux-2.6.15-rc1-mm2.orig/include/linux/ktime.h +++ linux-2.6.15-rc1-mm2/include/linux/ktime.h @@ -133,6 +133,14 @@ typedef s64 ktime_t; /* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */ #define ktime_to_ns(kt) (kt) +#if (BITS_PER_LONG == 64) +/* + * Calc ktime_t modulo div. + * div is less than NSEC_PER_SEC and (NSEC_PER_SEC % div) = 0 ! + */ +#define ktime_modulo(kt, div) (unsigned long)(kt % div) +#endif + #else /* @@ -341,6 +349,12 @@ static inline u64 ktime_to_ns(ktime_t kt return (u64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec; } +/* + * Calc ktime_t modulo div. + * div is less than NSEC_PER_SEC and (NSEC_PER_SEC % div) = 0 ! + */ +#define ktime_modulo(kt, div) ((unsigned long)kt.tv.nsec % div) + #endif /* Index: linux-2.6.15-rc1-mm2/kernel/ktimers.c =================================================================== --- linux-2.6.15-rc1-mm2.orig/kernel/ktimers.c +++ linux-2.6.15-rc1-mm2/kernel/ktimers.c @@ -243,8 +243,9 @@ lock_ktimer_base(struct ktimer *timer, u * Functions for the union type storage format of ktime_t which are * too large for inlining: */ -#if (BITS_PER_LONG < 64) && !defined(CONFIG_KTIME_SCALAR) +#if (BITS_PER_LONG < 64) +#ifndef CONFIG_KTIME_SCALAR /** * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable * @@ -267,6 +268,25 @@ ktime_t ktime_add_ns(ktime_t kt, u64 nse return ktime_add(kt, tmp); } + +#else + +/** + * ktime_modulo - Calc ktime_t modulo div + * + * @kt: dividend + * @div: divisor + * + * Return ktime_t modulo div. + * + * div is less than NSEC_PER_SEC and (NSEC_PER_SEC % div) = 0 ! + */ +static unsigned long ktime_modulo(ktime_t kt, unsigned long div) +{ + return do_div(kt, div); +} + +#endif #endif /* @@ -394,8 +414,7 @@ static int enqueue_ktimer(struct ktimer if (mode & KTIMER_ROUND) { unsigned long rem; - rem = ((unsigned long)ktime_get_low(timer->expires)) % - base->resolution; + rem = ktime_modulo(timer->expires, base->resolution); if (rem) timer->expires = ktime_add_ns(timer->expires, base->resolution - rem);
- 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/
| |