Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Feb 2019 01:34:14 +0000 (UTC)
From:      Andriy Voskoboinyk <avos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r343815 - head/sys/dev/iwn
Message-ID:  <201902060134.x161YEp4084493@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902060134.x161YEp4084493>