Changeset View
Changeset View
Standalone View
Standalone View
sys/net/netisr.c
Show First 20 Lines • Show All 914 Lines • ▼ Show 20 Lines | |||||
* SWI handler for netisr -- processes packets in a set of workstreams that | * SWI handler for netisr -- processes packets in a set of workstreams that | ||||
* it owns, woken up by calls to NWS_SIGNAL(). If this workstream is already | * it owns, woken up by calls to NWS_SIGNAL(). If this workstream is already | ||||
* being direct dispatched, go back to sleep and wait for the dispatching | * being direct dispatched, go back to sleep and wait for the dispatching | ||||
* thread to wake us up again. | * thread to wake us up again. | ||||
*/ | */ | ||||
static void | static void | ||||
swi_net(void *arg) | swi_net(void *arg) | ||||
{ | { | ||||
struct epoch_tracker et; | |||||
#ifdef NETISR_LOCKING | #ifdef NETISR_LOCKING | ||||
struct rm_priotracker tracker; | struct rm_priotracker tracker; | ||||
#endif | #endif | ||||
struct netisr_workstream *nwsp; | struct netisr_workstream *nwsp; | ||||
u_int bits, prot; | u_int bits, prot; | ||||
nwsp = arg; | nwsp = arg; | ||||
NET_EPOCH_ENTER(et); | |||||
#ifdef DEVICE_POLLING | #ifdef DEVICE_POLLING | ||||
KASSERT(nws_count == 1, | KASSERT(nws_count == 1, | ||||
("%s: device_polling but nws_count != 1", __func__)); | ("%s: device_polling but nws_count != 1", __func__)); | ||||
netisr_poll(); | netisr_poll(); | ||||
#endif | #endif | ||||
#ifdef NETISR_LOCKING | #ifdef NETISR_LOCKING | ||||
NETISR_RLOCK(&tracker); | NETISR_RLOCK(&tracker); | ||||
kib: Is it safe ? (I am not sure if the netisr rmlock is sleepable). | |||||
Done Inline ActionsFrom what I can read from the code Gleb's patches put this under epoch aswell. I will try to give this a spin with WITNESS enabled. hselasky: From what I can read from the code Gleb's patches put this under epoch aswell.
I will try to… | |||||
Done Inline ActionsCurrently NETISR_LOCKING is not defined, so the read lock is inactive. /usr/src/sys/net/netisr.c:/* #define NETISR_LOCKING */ In general I think it is more clever to apply the EPOCH() after any read locks and mutexes, so I'm pushing an update here. hselasky: Currently NETISR_LOCKING is not defined, so the read lock is inactive.
/usr/src/sys/net/netisr. | |||||
#endif | #endif | ||||
NWS_LOCK(nwsp); | NWS_LOCK(nwsp); | ||||
KASSERT(!(nwsp->nws_flags & NWS_RUNNING), ("swi_net: running")); | KASSERT(!(nwsp->nws_flags & NWS_RUNNING), ("swi_net: running")); | ||||
if (nwsp->nws_flags & NWS_DISPATCHING) | if (nwsp->nws_flags & NWS_DISPATCHING) | ||||
goto out; | goto out; | ||||
nwsp->nws_flags |= NWS_RUNNING; | nwsp->nws_flags |= NWS_RUNNING; | ||||
nwsp->nws_flags &= ~NWS_SCHEDULED; | nwsp->nws_flags &= ~NWS_SCHEDULED; | ||||
while ((bits = nwsp->nws_pendingbits) != 0) { | while ((bits = nwsp->nws_pendingbits) != 0) { | ||||
while ((prot = ffs(bits)) != 0) { | while ((prot = ffs(bits)) != 0) { | ||||
prot--; | prot--; | ||||
bits &= ~(1 << prot); | bits &= ~(1 << prot); | ||||
(void)netisr_process_workstream_proto(nwsp, prot); | (void)netisr_process_workstream_proto(nwsp, prot); | ||||
} | } | ||||
} | } | ||||
nwsp->nws_flags &= ~NWS_RUNNING; | nwsp->nws_flags &= ~NWS_RUNNING; | ||||
out: | out: | ||||
NWS_UNLOCK(nwsp); | NWS_UNLOCK(nwsp); | ||||
#ifdef NETISR_LOCKING | #ifdef NETISR_LOCKING | ||||
NETISR_RUNLOCK(&tracker); | NETISR_RUNLOCK(&tracker); | ||||
#endif | #endif | ||||
#ifdef DEVICE_POLLING | #ifdef DEVICE_POLLING | ||||
netisr_pollmore(); | netisr_pollmore(); | ||||
#endif | #endif | ||||
NET_EPOCH_EXIT(et); | |||||
} | } | ||||
static int | static int | ||||
netisr_queue_workstream(struct netisr_workstream *nwsp, u_int proto, | netisr_queue_workstream(struct netisr_workstream *nwsp, u_int proto, | ||||
struct netisr_work *npwp, struct mbuf *m, int *dosignalp) | struct netisr_work *npwp, struct mbuf *m, int *dosignalp) | ||||
{ | { | ||||
NWS_LOCK_ASSERT(nwsp); | NWS_LOCK_ASSERT(nwsp); | ||||
▲ Show 20 Lines • Show All 567 Lines • Show Last 20 Lines |
Is it safe ? (I am not sure if the netisr rmlock is sleepable).