Index: sys/sys/callout.h =================================================================== --- sys/sys/callout.h (revision 242707) +++ sys/sys/callout.h (working copy) @@ -51,29 +51,20 @@ #define CALLOUT_DIRECT 0x0100 /* allow exec from hw int context */ #define C_DIRECT_EXEC 0x0001 /* direct execution of callout */ -#define C_P1S 0x0002 /* fields related to precision */ -#define C_P500MS 0x0006 -#define C_P250MS 0x000a -#define C_P125MS 0x000e -#define C_P64MS 0x0012 -#define C_P32MS 0x0016 -#define C_P16MS 0x001a -#define C_P8MS 0x001e -#define C_P4MS 0x0022 -#define C_P2MS 0x0026 -#define C_P1MS 0x002a -#define C_P500US 0x002e -#define C_P250US 0x0032 -#define C_P125US 0x0036 -#define C_P64US 0x003a -#define C_P32US 0x003e -#define C_P16US 0x0042 -#define C_P8US 0x0046 -#define C_P4US 0x004a -#define C_P2US 0x004e -#define PRECISION_BITS 7 +#define C_PRECISION 0x0002 /* precision for callout specified */ +#define PRECISION_BITS 24 #define PRECISION_RANGE ((1 << PRECISION_BITS) - 1) +#define PRECISION_MASK (1 << ((32 - PRECISION_BITS) - 1)) +#define T2PRECFLAGS(x) ((x) * 4294) & PRECISION_MASK) +#define PRECBTGET(x) ((uint64_t)(flags & PRECISION_MASK) << 32) +/* + * Common values specified for precision. + */ +#define C_P1MS T2PRECFLAGS(1000) +#define C_P10MS T2PRECFLAGS(10000) +#define C_P100MS T2PRECFLAGS(100000) + struct callout_handle { struct callout *callout; }; Index: sys/kern/kern_timeout.c =================================================================== --- sys/kern/kern_timeout.c (revision 242707) +++ sys/kern/kern_timeout.c (working copy) @@ -170,7 +170,6 @@ struct callout_cpu cc_cpu; #define CC_LOCK(cc) mtx_lock_spin(&(cc)->cc_lock) #define CC_UNLOCK(cc) mtx_unlock_spin(&(cc)->cc_lock) #define CC_LOCK_ASSERT(cc) mtx_assert(&(cc)->cc_lock, MA_OWNED) -#define C_PRECISION 0x2 #define FREQ2BT(freq, bt) \ { \ @@ -576,8 +575,8 @@ callout_cc_add(struct callout *c, struct callout_c { struct bintime bt; uint64_t r_val; - int bucket, r_shift; - + int bucket; + CC_LOCK_ASSERT(cc); if (bintime_cmp(&to_bintime, &cc->cc_lastscan, <)) to_bintime = cc->cc_lastscan; @@ -590,33 +589,10 @@ callout_cc_add(struct callout *c, struct callout_c c->c_time = to_bintime; bintime_clear(&c->c_precision); if (flags & C_PRECISION) { - r_shift = ((flags >> 2) & PRECISION_RANGE); - r_val = (r_shift != 0) ? (uint64_t)1 << (64 - r_shift) : 0; - /* - * Round as far as precision specified is coarse (up to 8ms). - * In order to play safe, round to to half of the interval and - * set half precision. - */ - if (r_shift < 6) { - r_val = (r_shift != 0) ? r_val >> 2 : - ((uint64_t)1 << (64 - 1)) - 1; - /* - * Round only if c_time is not a multiple of the - * rounding factor. - */ - if ((c->c_time.frac & r_val) != r_val) { - c->c_time.frac |= r_val - 1; - c->c_time.frac += 1; - if (c->c_time.frac == 0) - c->c_time.sec += 1; - } - } + r_val = PRECBTGET(flags); c->c_precision.frac = r_val; - CTR6(KTR_CALLOUT, "rounding %d.%08x%08x to %d.%08x%08x", - to_bintime.sec, (u_int) (to_bintime.frac >> 32), - (u_int) (to_bintime.frac & 0xffffffff), c->c_time.sec, - (u_int) (c->c_time.frac >> 32), - (u_int) (c->c_time.frac & 0xffffffff)); + CTR3(KTR_CALLOUT, "precision set for %p: 0.%08x%08", + c, (u_int) (r_val >> 32), (u_int) (r_val & 0xffffffff)); } bucket = get_bucket(&c->c_time); TAILQ_INSERT_TAIL(&cc->cc_callwheel[bucket], c, c_links.tqe);