From owner-svn-src-projects@FreeBSD.ORG Mon May 18 22:16:51 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6A9E5106564A; Mon, 18 May 2009 22:16:51 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5928F8FC0C; Mon, 18 May 2009 22:16:51 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4IMGpIo076544; Mon, 18 May 2009 22:16:51 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4IMGpuX076543; Mon, 18 May 2009 22:16:51 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <200905182216.n4IMGpuX076543@svn.freebsd.org> From: Robert Watson Date: Mon, 18 May 2009 22:16:51 +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: r192347 - projects/pnet/sys/net 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: Mon, 18 May 2009 22:16:51 -0000 Author: rwatson Date: Mon May 18 22:16:51 2009 New Revision: 192347 URL: http://svn.freebsd.org/changeset/base/192347 Log: Use rmlocks for netisr2 and enable read-locking in the dispatch path. Despite deeply upsetting WITNESS, this should actually be safe as the rmlock is always acquired read-locked in any processing path that could otherwise lead to a lock order reversal, so we'll want to supress these warnings as with pfil lock warnings. Modified: projects/pnet/sys/net/netisr2.c Modified: projects/pnet/sys/net/netisr2.c ============================================================================== --- projects/pnet/sys/net/netisr2.c Mon May 18 21:58:57 2009 (r192346) +++ projects/pnet/sys/net/netisr2.c Mon May 18 22:16:51 2009 (r192347) @@ -63,7 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -93,22 +93,18 @@ __FBSDID("$FreeBSD$"); * - The np array, including all fields of struct netisr_proto. * - The nws array, including all fields of struct netisr_worker. * - The nws_array array. - * - * XXXRW: This should use an rmlock. */ -static struct rwlock netisr_rwlock; -#define NETISR_LOCK_INIT() rw_init(&netisr_rwlock, "netisr") -#ifdef NETISR_LOCKING -#define NETISR_LOCK_ASSERT() rw_assert(&netisr_rwlock, RW_LOCKED) -#define NETISR_RLOCK() rw_rlock(&netisr_rwlock) -#define NETISR_RUNLOCK() rw_runlock(&netisr_rwlock) +static struct rmlock netisr_rmlock; +#define NETISR_LOCK_INIT() rm_init(&netisr_rmlock, "netisr", 0) +#if 0 +#define NETISR_LOCK_ASSERT() rm_assert(&netisr_rmlock, RW_LOCKED) #else #define NETISR_LOCK_ASSERT() -#define NETISR_RLOCK() -#define NETISR_RUNLOCK() #endif -#define NETISR_WLOCK() rw_wlock(&netisr_rwlock) -#define NETISR_WUNLOCK() rw_wunlock(&netisr_rwlock) +#define NETISR_RLOCK(tracker) rm_rlock(&netisr_rmlock, (tracker)) +#define NETISR_RUNLOCK(tracker) rm_runlock(&netisr_rmlock, (tracker)) +#define NETISR_WLOCK() rm_wlock(&netisr_rmlock) +#define NETISR_WUNLOCK() rm_wunlock(&netisr_rmlock) SYSCTL_NODE(_net, OID_AUTO, isr2, CTLFLAG_RW, 0, "netisr2"); @@ -277,7 +273,7 @@ u_int netisr2_default_flow2cpu(u_int flowid) { - return (netisr2_get_cpuid(flowid % nws_count)); + return (nws_array[flowid % nws_count]); } /* @@ -388,6 +384,7 @@ void netisr2_getqdrops(const struct netisr_handler *nhp, u_int64_t *qdropp) { struct netisr_work *npwp; + struct rm_priotracker tracker; #ifdef INVARIANTS const char *name; #endif @@ -400,7 +397,7 @@ netisr2_getqdrops(const struct netisr_ha #endif KASSERT(proto < NETISR_MAXPROT, ("netisr_getqdrops(%d): protocol too big for %s", proto, name)); - NETISR_RLOCK(); + NETISR_RLOCK(&tracker); KASSERT(np[proto].np_handler != NULL, ("netisr_getqdrops(%d): protocol not registered for %s", proto, name)); @@ -409,7 +406,7 @@ netisr2_getqdrops(const struct netisr_ha npwp = &nws[i].nws_work[proto]; *qdropp += npwp->nw_qdrops; } - NETISR_RUNLOCK(); + NETISR_RUNLOCK(&tracker); } /* @@ -418,6 +415,7 @@ netisr2_getqdrops(const struct netisr_ha void netisr2_getqlimit(const struct netisr_handler *nhp, u_int *qlimitp) { + struct rm_priotracker tracker; #ifdef INVARIANTS const char *name; #endif @@ -429,12 +427,12 @@ netisr2_getqlimit(const struct netisr_ha #endif KASSERT(proto < NETISR_MAXPROT, ("netisr_getqlimit(%d): protocol too big for %s", proto, name)); - NETISR_RLOCK(); + NETISR_RLOCK(&tracker); KASSERT(np[proto].np_handler != NULL, ("netisr_getqlimit(%d): protocol not registered for %s", proto, name)); *qlimitp = np[proto].np_qlimit; - NETISR_RUNLOCK(); + NETISR_RUNLOCK(&tracker); } /* @@ -684,18 +682,19 @@ netisr2_process_workstream(struct netisr static void swi_net(void *arg) { + struct rm_priotracker tracker; struct netisr_workstream *nwsp; nwsp = arg; - NETISR_RLOCK(); + NETISR_RLOCK(&tracker); NWS_LOCK(nwsp); nwsp->nws_flags |= NWS_RUNNING; while (nwsp->nws_pendingwork != 0) netisr2_process_workstream(nwsp, NETISR_ALLPROT); nwsp->nws_flags &= ~(NWS_SIGNALED | NWS_RUNNING); NWS_UNLOCK(nwsp); - NETISR_RUNLOCK(); + NETISR_RUNLOCK(&tracker); } static int @@ -745,12 +744,13 @@ netisr2_queue_internal(u_int proto, stru int netisr2_queue_src(u_int proto, uintptr_t source, struct mbuf *m) { + struct rm_priotracker tracker; u_int cpuid, error; KASSERT(proto < NETISR_MAXPROT, ("netisr2_queue_src: invalid proto %d", proto)); - NETISR_RLOCK(); + NETISR_RLOCK(&tracker); KASSERT(np[proto].np_handler != NULL, ("netisr2_queue_src: invalid proto %d", proto)); @@ -759,7 +759,7 @@ netisr2_queue_src(u_int proto, uintptr_t error = netisr2_queue_internal(proto, m, cpuid); else error = ENOBUFS; - NETISR_RUNLOCK(); + NETISR_RUNLOCK(&tracker); return (error); } @@ -782,6 +782,7 @@ netisr_queue(int proto, struct mbuf *m) int netisr2_dispatch_src(u_int proto, uintptr_t source, struct mbuf *m) { + struct rm_priotracker tracker; struct netisr_workstream *nwsp; struct netisr_work *npwp; @@ -790,7 +791,7 @@ netisr2_dispatch_src(u_int proto, uintpt KASSERT(proto < NETISR_MAXPROT, ("netisr2_dispatch_src: invalid proto %u", proto)); - NETISR_RLOCK(); + NETISR_RLOCK(&tracker); KASSERT(np[proto].np_handler != NULL, ("netisr2_dispatch_src: invalid proto %u", proto)); @@ -802,7 +803,7 @@ netisr2_dispatch_src(u_int proto, uintpt npwp->nw_dispatched++; npwp->nw_handled++; np[proto].np_handler(m); - NETISR_RUNLOCK(); + NETISR_RUNLOCK(&tracker); return (0); }