On Thu, Apr 02, 2020 at 06:21:27PM +0100, Raf Czlonka wrote:
> On Thu, Apr 02, 2020 at 12:51:45PM BST, Stefan Sperling wrote:
> Hi Stefan,
>
> After I got it to timeout, I ran /etc/netstart and unplugged it,
> then plugged it again - no panic. I had to poke it a bit to get it
> working again but, even when it was up and I unplugged it then,
> still no panic.
>
> Thanks a lot for your help! :^)
Great, I'm glad this problem could be fixed!
> Now, is there anything that can be done regarding the timeouts?
I don't know. It's hard to tell why it's failing. We don't know whether
the root cause is a problem with the device itself, or with the USB
subsystem, or with the driver.
The driver uses a fairly simple approach of only pulling one packet
off the network stack's queue at a time, and waiting for the packet's
USB transaction to finish before it pulls another packet off the queue.
In fact, the driver's internal Tx queue has only one element!
If a frame fails to transmit, the driver just gives up. There's no code
to retry a failed transmission as far as I can see, nor is there code to
put the driver back into a state where it would continue to send packets.
As a workaround ifconfig down/up should unwedge it.
This would require someone with a bit of time to invest into working on
this driver. I'm glad I could fix the panic but I don't have enough spare
time to fix performance issues in this driver.
A lot of our wifi drivers are in a state where they are 90% done, and
working out the remaining 10% will usually turn into another 90%...
> zyd0: HMAC ZD1211, FW 46.05, RF RFMD, PA 0, address [...]
> splassert: ieee80211_free_node: want 7 have 4
The splassert warning should be prevented by this diff.
But I believe it's just a cosmetic issue since there's no way this
code could race against interrupts at IPL_NET.
diff 9d8a60ff1dae84d5c890bdc5040be018a3bdd3dc /usr/src
blob - 9c235cb159e6c4c1ee51fa265f39b10dfe065165 (staged)
file + sys/dev/usb/if_zyd.c
--- sys/dev/usb/if_zyd.c
+++ sys/dev/usb/if_zyd.c
@@ -569,7 +569,7 @@ void
zyd_free_tx_list(struct zyd_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
- int i;
+ int i, s;
for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
struct zyd_tx_data *data = &sc->tx_data[i];
@@ -579,7 +579,9 @@ zyd_free_tx_list(struct zyd_softc *sc)
data->xfer = NULL;
}
if (data->ni != NULL) {
+ s = splnet();
ieee80211_release_node(ic, data->ni);
+ splx(s);
data->ni = NULL;
}
}