> 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).

Reply via email to