> Date: Fri, 13 Jul 2012 10:42:02 +0200 > From: Stefan Sperling <s...@openbsd.org> > > On Thu, Jul 12, 2012 at 05:51:32PM +0200, Stefan Sperling wrote: > > Running "ifconfig ral0 debug down up" can leave slow systems, such > > as edd@'s soekris, with an unusable wireless interface until reboot. > > > > The net80211 layer will run a scan when the interface comes up. > > The scan hops from channel to channel every 200msec. This hopping is > > controlled via a timeout that runs at IPL_SOFTCLOCK. When the scan > > reaches the last channel it terminates. > > > > The problem with soekris is that, in noisy environments, they take so > > much time printing debug messsages about received frames from > > ieee80211_input() to the serial console that another RX interrupt > > will run next at IPL_NET. This prevents the scan from running its 200msc > > timeout handler at IPL_SOFTCLOCK, and the scan never finishes. > > > > With the diff below, we print the message from a work queue at IPL_TTY > > instead (idea from guenther@). This allows the soekris to finish the scan. > > The box is still hardly responsive during the scan but at least concurrent > > SSH sessions remain somewhat responsive and eventually the soekris recovers > > completely. > > > > Improved diff after clue-stick from blambert about how work queues and > IPLs really interact.
But doing the printf from spltty() doesn't make an awful lot of sense. We already protect printf(9) by a mutex at IPL_HIGH. Also... > Index: ieee80211_input.c > =================================================================== > RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v > retrieving revision 1.119 > diff -u -p -r1.119 ieee80211_input.c > --- ieee80211_input.c 5 Apr 2011 11:48:28 -0000 1.119 > +++ ieee80211_input.c 13 Jul 2012 08:37:13 -0000 > @@ -42,6 +42,7 @@ > #include <sys/errno.h> > #include <sys/proc.h> > #include <sys/sysctl.h> > +#include <sys/workq.h> > > #include <net/if.h> > #include <net/if_dl.h> > @@ -131,6 +132,9 @@ void ieee80211_recv_bar(struct ieee80211 > void ieee80211_bar_tid(struct ieee80211com *, struct ieee80211_node *, > u_int8_t, u_int16_t); > #endif > +void ieee80211_input_print(struct ieee80211com *, struct ifnet *, > + struct ieee80211_frame *, struct ieee80211_rxinfo *); > +void ieee80211_input_print_task(void *, void *); > > /* > * Retrieve the length in bytes of an 802.11 header. > @@ -152,6 +156,69 @@ ieee80211_get_hdrlen(const struct ieee80 > return size; > } > > +/* Work queue task that prints a received frame. Avoids printf() from > + * interrupt context at IPL_NET making slow machines unusable when many > + * frames are received and the interface is put in debug mode. */ ...this comment isn't properly formatted: see style(9).