From owner-p4-projects@FreeBSD.ORG Wed Sep 12 08:31:19 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B688A16A41A; Wed, 12 Sep 2007 08:31:19 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 717D616A418 for ; Wed, 12 Sep 2007 08:31:19 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 5DFDC13C465 for ; Wed, 12 Sep 2007 08:31:19 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l8C8VJgX085598 for ; Wed, 12 Sep 2007 08:31:19 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l8C8VJAP085595 for perforce@freebsd.org; Wed, 12 Sep 2007 08:31:19 GMT (envelope-from kmacy@freebsd.org) Date: Wed, 12 Sep 2007 08:31:19 GMT Message-Id: <200709120831.l8C8VJAP085595@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to kmacy@freebsd.org using -f From: Kip Macy To: Perforce Change Reviews Cc: Subject: PERFORCE change 126329 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Sep 2007 08:31:20 -0000 http://perforce.freebsd.org/chv.cgi?CH=126329 Change 126329 by kmacy@kmacy_home:ethng on 2007/09/12 08:30:25 Add callout_init_rwlock Affected files ... .. //depot/projects/ethng/src/sys/kern/kern_timeout.c#3 edit .. //depot/projects/ethng/src/sys/sys/callout.h#2 edit Differences ... ==== //depot/projects/ethng/src/sys/kern/kern_timeout.c#3 (text+ko) ==== @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,9 @@ static int avg_mtxcalls; SYSCTL_INT(_debug, OID_AUTO, to_avg_mtxcalls, CTLFLAG_RD, &avg_mtxcalls, 0, "Average number of mtx callouts made per softclock call. Units = 1/1000"); +static int avg_rwcalls; +SYSCTL_INT(_debug, OID_AUTO, to_avg_rwcalls, CTLFLAG_RD, &avg_rwcalls, 0, + "Average number of rw callouts made per softclock call. Units = 1/1000"); static int avg_mpcalls; SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0, "Average number of MP callouts made per softclock call. Units = 1/1000"); @@ -171,6 +175,7 @@ int depth; int mpcalls; int mtxcalls; + int rwcalls; int gcalls; #ifdef DIAGNOSTIC struct bintime bt1, bt2; @@ -185,6 +190,7 @@ mpcalls = 0; mtxcalls = 0; + rwcalls = 0; gcalls = 0; depth = 0; steps = 0; @@ -216,6 +222,7 @@ void (*c_func)(void *); void *c_arg; struct mtx *c_mtx; + struct rwlock *c_rwlock; int c_flags; nextsoftcheck = TAILQ_NEXT(c, c_links.tqe); @@ -223,6 +230,7 @@ c_func = c->c_func; c_arg = c->c_arg; c_mtx = c->c_mtx; + c_rwlock = c->c_rwlock; c_flags = c->c_flags; if (c->c_flags & CALLOUT_LOCAL_ALLOC) { c->c_func = NULL; @@ -237,7 +245,19 @@ } curr_cancelled = 0; mtx_unlock_spin(&callout_lock); - if (c_mtx != NULL) { + if (c_rwlock != NULL) { + rw_wlock(c_rwlock); + if (curr_cancelled) { + rw_wunlock(c_rwlock); + goto skip; + } + curr_cancelled = 1; + rwcalls++; + + CTR3(KTR_CALLOUT, "callout mtx" + " %p func %p arg %p", + c, c_func, c_arg); + } else if (c_mtx != NULL) { if (c_flags & CALLOUT_NETGIANT) { mtx_lock(&Giant); gcalls++; @@ -297,8 +317,10 @@ lastfunc = c_func; } #endif - if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0) + if (c_mtx != NULL && (c_flags & CALLOUT_RETURNUNLOCKED) == 0) mtx_unlock(c_mtx); + if (c_rwlock != NULL && (c_flags & CALLOUT_RETURNUNLOCKED_RW) == 0) + rw_wunlock(c_rwlock); if (c_flags & CALLOUT_NETGIANT) mtx_unlock(&Giant); skip: @@ -322,6 +344,7 @@ avg_depth += (depth * 1000 - avg_depth) >> 8; avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8; avg_mtxcalls += (mtxcalls * 1000 - avg_mtxcalls) >> 8; + avg_rwcalls += (rwcalls * 1000 - avg_rwcalls) >> 8; avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8; nextsoftcheck = NULL; mtx_unlock_spin(&callout_lock); @@ -623,7 +646,6 @@ { bzero(c, sizeof *c); if (mpsafe) { - c->c_mtx = NULL; c->c_flags = CALLOUT_RETURNUNLOCKED; } else { c->c_mtx = &Giant; @@ -639,6 +661,7 @@ { bzero(c, sizeof *c); c->c_mtx = mtx; + c->c_rwlock = NULL; KASSERT((flags & ~(CALLOUT_RETURNUNLOCKED|CALLOUT_NETGIANT)) == 0, ("callout_init_mtx: bad flags %d", flags)); /* CALLOUT_RETURNUNLOCKED makes no sense without a mutex. */ @@ -647,6 +670,17 @@ c->c_flags = flags & (CALLOUT_RETURNUNLOCKED|CALLOUT_NETGIANT); } +void +callout_init_rwlock(struct callout *c, struct rwlock *rw, int flags) +{ + bzero(c, sizeof *c); + c->c_mtx = NULL; + c->c_rwlock = rw; + KASSERT((flags & ~CALLOUT_RETURNUNLOCKED_RW) == 0, + ("callout_init_rwlock: bad flags %d", flags)); + c->c_flags = flags & CALLOUT_RETURNUNLOCKED_RW; +} + #ifdef APM_FIXUP_CALLTODO /* * Adjust the kernel calltodo timeout list. This routine is used after ==== //depot/projects/ethng/src/sys/sys/callout.h#2 (text+ko) ==== @@ -54,6 +54,7 @@ void *c_arg; /* function argument */ void (*c_func)(void *); /* function to call */ struct mtx *c_mtx; /* mutex to lock */ + struct rwlock *c_rwlock; /* rwlock to lock */ int c_flags; /* state of this entry */ }; @@ -63,6 +64,7 @@ #define CALLOUT_MPSAFE 0x0008 /* callout handler is mp safe */ #define CALLOUT_RETURNUNLOCKED 0x0010 /* handler returns with mtx unlocked */ #define CALLOUT_NETGIANT 0x0020 /* XXX: obtain Giant before mutex */ +#define CALLOUT_RETURNUNLOCKED_RW 0x0040 /* handler returns with rwlock unlocked */ struct callout_handle { struct callout *callout; @@ -81,6 +83,7 @@ #define callout_drain(c) _callout_stop_safe(c, 1) void callout_init(struct callout *, int); void callout_init_mtx(struct callout *, struct mtx *, int); +void callout_init_rwlock(struct callout *, struct rwlock *, int); #define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING) int callout_reset(struct callout *, int, void (*)(void *), void *); #define callout_stop(c) _callout_stop_safe(c, 0)