Hit a witness panic during boot yesterday.  Can't repro, have never
seen it before.  The photo is a mess (ask if you want it) but the
backtrace is:

panic
witness_checkorder
rw_enter_write
solock
route input
ieee80211_set_link_state
ieee80211_recv_4way_msg3
ieee80211_eapol_key_input
ieee80211_decap
ieee80211_input_ba_flush
ieee80211_input_ba_gap_timeout
timeout_run
softclock_process_tick_timeout
sotclock

We're not allowed to take sleeping locks during the execution of a
timeout, hence the witness panic.

The backtrace omits that ieee80211_set_link_state() calls
rtm_80211info(), which calls route_input().

The guilty call is in ieee80211_proto.c, line 1327:

  1295  void
  1296  ieee80211_set_link_state(struct ieee80211com *ic, int nstate)
  1297  {
  1298          struct ifnet *ifp = &ic->ic_if;
  1299  
  1300          switch (ic->ic_opmode) {

/* ... */

  1312          }
  1313          if (nstate != ifp->if_link_state) {
  1314                  ifp->if_link_state = nstate;
  1315                  if (LINK_STATE_IS_UP(nstate)) {
  1316                          struct if_ieee80211_data ifie;
  1317                          memset(&ifie, 0, sizeof(ifie));
  1318                          ifie.ifie_nwid_len = ic->ic_bss->ni_esslen;
  1319                          memcpy(ifie.ifie_nwid, ic->ic_bss->ni_essid,
  1320                              sizeof(ifie.ifie_nwid));
  1321                          memcpy(ifie.ifie_addr, ic->ic_bss->ni_bssid,
  1322                              sizeof(ifie.ifie_addr));
  1323                          ifie.ifie_channel = ieee80211_chan2ieee(ic,
  1324                              ic->ic_bss->ni_chan);
  1325                          ifie.ifie_flags = ic->ic_flags;
  1326                          ifie.ifie_xflags = ic->ic_xflags;
  1327                          rtm_80211info(&ic->ic_if, &ifie);
  1328                  }
  1329                  if_link_state_change(ifp);
  1330          }
  1331  }

So if the link state is changing from not-up to up we send a routing
info message to userspace.

Typical solution would be to postpone the rtm_80211info() call to a
task, but I'm not familiar with this stack so maybe we can't do that?

Reply via email to