From owner-svn-src-projects@FreeBSD.ORG Fri Jun 29 16:06:06 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C800A1065673; Fri, 29 Jun 2012 16:06:06 +0000 (UTC) (envelope-from davide@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B39B98FC18; Fri, 29 Jun 2012 16:06:06 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q5TG66SV055465; Fri, 29 Jun 2012 16:06:06 GMT (envelope-from davide@svn.freebsd.org) Received: (from davide@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5TG66nq055462; Fri, 29 Jun 2012 16:06:06 GMT (envelope-from davide@svn.freebsd.org) Message-Id: <201206291606.q5TG66nq055462@svn.freebsd.org> From: Davide Italiano Date: Fri, 29 Jun 2012 16:06:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237796 - in projects/calloutng/sys: kern sys X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Jun 2012 16:06:06 -0000 Author: davide Date: Fri Jun 29 16:06:06 2012 New Revision: 237796 URL: http://svn.freebsd.org/changeset/base/237796 Log: Experiment a new approach used for low-precision events, try to align them to some time borders on insert. This approach can make system load more bursty, but it is very cheap to be implemented and may be quite effective. Moreover, it can easily coexist with the previously implemented "real-time aggregation". Discussed with: mav Modified: projects/calloutng/sys/kern/kern_timeout.c projects/calloutng/sys/sys/callout.h Modified: projects/calloutng/sys/kern/kern_timeout.c ============================================================================== --- projects/calloutng/sys/kern/kern_timeout.c Fri Jun 29 15:57:25 2012 (r237795) +++ projects/calloutng/sys/kern/kern_timeout.c Fri Jun 29 16:06:06 2012 (r237796) @@ -497,8 +497,7 @@ callout_cc_add(struct callout *c, struct struct bintime to_bintime, void (*func)(void *), void *arg, int cpu, int flags) { - struct timeval tv; - int bucket; + int bucket, r_shift, r_val; CC_LOCK_ASSERT(cc); if (bintime_cmp(&to_bintime, &cc->cc_lastscan, <)) { @@ -510,25 +509,38 @@ callout_cc_add(struct callout *c, struct c->c_flags |= CALLOUT_DIRECT; c->c_flags &= ~CALLOUT_PROCESSED; c->c_func = func; - c->c_time = to_bintime; - tv.tv_sec = 0; - if (flags & C_10US) { - tv.tv_usec = 10; - timeval2bintime(&tv, &c->c_precision); - } - else if (flags & C_100US) { - tv.tv_usec = 100; - timeval2bintime(&tv, &c->c_precision); - } - else if (flags & C_1MS) { - tv.tv_usec = 1000; - timeval2bintime(&tv, &c->c_precision); + c->c_time = to_bintime; + bintime_clear(&c->c_precision); + if (flags & 0x2) { + 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; + } + } + c->c_precision.frac = r_val; + CTR6(KTR_CALLOUT, "rounding %d.%u%u to %d.%u%u", + 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)); } - else { - c->c_precision.sec = 0; - c->c_precision.frac = 0; - } - bucket = get_bucket(&c->c_time); + bucket = get_bucket(&c->c_time); TAILQ_INSERT_TAIL(&cc->cc_callwheel[bucket & callwheelmask], c, c_links.tqe); /* @@ -536,10 +548,10 @@ callout_cc_add(struct callout *c, struct * that has been inserted. */ if (callout_new_inserted != NULL && - (bintime_cmp(&to_bintime, &cc->cc_firstevent, <) || + (bintime_cmp(&c->c_time, &cc->cc_firstevent, <) || (cc->cc_firstevent.sec == 0 && cc->cc_firstevent.frac == 0))) { - cc->cc_firstevent = to_bintime; - (*callout_new_inserted)(cpu, to_bintime); + cc->cc_firstevent = c->c_time; + (*callout_new_inserted)(cpu, c->c_time); } } Modified: projects/calloutng/sys/sys/callout.h ============================================================================== --- projects/calloutng/sys/sys/callout.h Fri Jun 29 15:57:25 2012 (r237795) +++ projects/calloutng/sys/sys/callout.h Fri Jun 29 16:06:06 2012 (r237796) @@ -51,9 +51,28 @@ #define CALLOUT_DIRECT 0x1000 /* allow exec from hw int context */ #define C_DIRECT_EXEC 0x0001 /* direct execution of callout */ -#define C_10US 0x0002 /* precision field */ -#define C_100US 0x0004 /* precision field */ -#define C_1MS 0x0008 /* precision field */ +#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 PRECISION_RANGE ((1 << PRECISION_BITS) - 1) struct callout_handle { struct callout *callout;