wireless drivers (specifically wpi, also others)

Alex Hornung ahornung at gmail.com
Sun Nov 7 03:15:49 PST 2010


Hi,

I've had some trouble the with the wpi driver regarding several
assertions being hit in code outside of wpi. One that I hit was "pending
prepended mbuf" which *seems* to go away with the patch at the end of
this mail.

The other one, though, is way more tricky and actually seems to be due
to bad refcounting. Upon looking at our and FreeBSD's code, I noticed
that there are some horribly hacks in other wireless drivers such as iwn
and ral that call

ieee80211_ratectl_node_deinit(ni);

before the actual call to

ieee80211_ratectl_node_init(ni);

that just aren't there in FreeBSD. deinit() isn't supposed to be called
from any driver, but rather upon garbage collection (i.e. when it loses
all references) of the ni ieee80211_node. Since this doesn't seem to be
happening, I really think the refcounting is horribly wrong. One sure
way to trigger this problem is to reconnect several times, or even run
several times

ifconfig wlan0 scan .

This bug has been confirmed but several attendees to the BSDday
Argentina who are also running DragonFly on laptops with wpi cards.

So I guess my actual question is, does anyone actually know what is
going on with the refcounting? Hackish workarounds like calling deinit()
before init() just don't cut it.

Regards,
Alex Hornung



diff --git a/sys/dev/netif/wpi/if_wpi.c b/sys/dev/netif/wpi/if_wpi.c
index f83aefb..17147c3 100644
--- a/sys/dev/netif/wpi/if_wpi.c
+++ b/sys/dev/netif/wpi/if_wpi.c
@@ -2034,13 +2034,13 @@ wpi_start_locked(struct ifnet *ifp)
 	}

 	for (;;) {
-		IF_DEQUEUE(&ifp->if_snd, m);
+		m = ifq_dequeue(&ifp->if_snd, NULL);
 		if (m == NULL)
 			break;
 		ac = M_WME_GETAC(m);
 		if (sc->txq[ac].queued > sc->txq[ac].count - 8) {
 			/* there is no place left in this ring */
-			ifq_prepend(&ifp->if_snd, m);
 			ifp->if_flags |= IFF_OACTIVE;
+			ifq_prepend(&ifp->if_snd, m);
 			break;
 		}







More information about the Kernel mailing list