svn commit: r192347 - projects/pnet/sys/net
Robert Watson
rwatson at FreeBSD.org
Mon May 18 22:16:51 UTC 2009
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 <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/proc.h>
-#include <sys/rwlock.h>
+#include <sys/rmlock.h>
#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/socket.h>
@@ -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);
}
More information about the svn-src-projects
mailing list