Author: avos
Date: Wed Feb  6 01:34:14 2019
New Revision: 343815
URL: https://svnweb.freebsd.org/changeset/base/343815

Log:
  iwn(4): plug initialization path vs interrupt handler races
  
  There are few places in interrupt handler where the driver
  lock is dropped; ensure that device is still running before
  processing remaining ring entries.
  
  PR:           192641
  MFC after:    5 days

Modified:
  head/sys/dev/iwn/if_iwn.c

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c   Tue Feb  5 22:53:36 2019        (r343814)
+++ head/sys/dev/iwn/if_iwn.c   Wed Feb  6 01:34:14 2019        (r343815)
@@ -3990,6 +3990,7 @@ iwn_notif_intr(struct iwn_softc *sc)
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
        uint16_t hw;
+       int is_stopped;
 
        bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
            BUS_DMASYNC_POSTREAD);
@@ -4021,6 +4022,11 @@ iwn_notif_intr(struct iwn_softc *sc)
                case IWN_MPDU_RX_DONE:
                        /* An 802.11 frame has been received. */
                        iwn_rx_done(sc, desc, data);
+
+                       is_stopped = (sc->sc_flags & IWN_FLAG_RUNNING) == 0;
+                       if (__predict_false(is_stopped))
+                               return;
+
                        break;
 
                case IWN_RX_COMPRESSED_BA:
@@ -4061,6 +4067,11 @@ iwn_notif_intr(struct iwn_softc *sc)
                                        IWN_UNLOCK(sc);
                                        ieee80211_beacon_miss(ic);
                                        IWN_LOCK(sc);
+
+                                       is_stopped = (sc->sc_flags &
+                                           IWN_FLAG_RUNNING) == 0;
+                                       if (__predict_false(is_stopped))
+                                               return;
                                }
                        }
                        break;
@@ -4127,6 +4138,11 @@ iwn_notif_intr(struct iwn_softc *sc)
                        IWN_UNLOCK(sc);
                        ieee80211_scan_next(vap);
                        IWN_LOCK(sc);
+
+                       is_stopped = (sc->sc_flags & IWN_FLAG_RUNNING) == 0;
+                       if (__predict_false(is_stopped))  
+                               return;
+
                        break;
                }
                case IWN5000_CALIBRATION_RESULT:
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to