diff options
author | wpaul <wpaul@FreeBSD.org> | 2004-04-22 07:08:39 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2004-04-22 07:08:39 +0000 |
commit | 6bc1da1c05748794ddfba4b35ad43a0752b9d9ce (patch) | |
tree | d7c8788b2df34a961795a4183df16cf79dd6cf16 /sys/compat | |
parent | ea882c9688f650396d1f4b076c564a13bb55b025 (diff) | |
download | FreeBSD-src-6bc1da1c05748794ddfba4b35ad43a0752b9d9ce.zip FreeBSD-src-6bc1da1c05748794ddfba4b35ad43a0752b9d9ce.tar.gz |
Ok, _really_ fix the Intel 2100B Centrino deadlock problems this time.
(I hope.)
My original instinct to make ndis_return_packet() asynchronous was correct.
Making ndis_rxeof() submit packets to the stack asynchronously fixes
one recursive spinlock acquisition, but it's also possible for it to
happen via the ndis_txeof() path too. So:
- In if_ndis.c, revert ndis_rxeof() to its old behavior (and don't bother
putting ndis_rxeof_serial() back since we don't need it anymore).
- In kern_ndis.c, make ndis_return_packet() submit the call to the
MiniportReturnPacket() function to the "ndis swi" thread so that
it always happens in another context no matter who calls it.
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/ndis/kern_ndis.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index 6e5d35a..51b2d17 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -99,6 +99,7 @@ struct ndisproc { int np_state; }; +static void ndis_return(void *); static int ndis_create_kthreads(void); static void ndis_destroy_kthreads(void); static void ndis_stop_thread(int); @@ -724,17 +725,38 @@ ndis_flush_sysctls(arg) return(0); } -void -ndis_return_packet(buf, arg) - void *buf; /* not used */ +static void +ndis_return(arg) void *arg; { struct ndis_softc *sc; + __stdcall ndis_return_handler returnfunc; ndis_handle adapter; ndis_packet *p; - __stdcall ndis_return_handler returnfunc; uint8_t irql; + p = arg; + sc = p->np_softc; + adapter = sc->ndis_block.nmb_miniportadapterctx; + + if (adapter == NULL) + return; + + returnfunc = sc->ndis_chars.nmc_return_packet_func; + irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL); + returnfunc(adapter, p); + FASTCALL1(hal_lower_irql, irql); + + return; +} + +void +ndis_return_packet(buf, arg) + void *buf; /* not used */ + void *arg; +{ + ndis_packet *p; + if (arg == NULL) return; @@ -747,14 +769,7 @@ ndis_return_packet(buf, arg) if (p->np_refcnt) return; - sc = p->np_softc; - returnfunc = sc->ndis_chars.nmc_return_packet_func; - adapter = sc->ndis_block.nmb_miniportadapterctx; - if (adapter != NULL) { - irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL); - returnfunc(adapter, p); - FASTCALL1(hal_lower_irql, irql); - } + ndis_sched(ndis_return, p, NDIS_SWI); return; } |