svn commit: r302183 - head/sys/dev/urtwn

Andriy Voskoboinyk avos at FreeBSD.org
Fri Jun 24 23:36:23 UTC 2016


Author: avos
Date: Fri Jun 24 23:36:22 2016
New Revision: 302183
URL: https://svnweb.freebsd.org/changeset/base/302183

Log:
  urtwn: fix memory leak on device restart
  
  Free data buffers every time when device is stopped, not when
  it is detached; they are allocated at the initialization stage.
  
  How-to-reproduce:
  1) ifconfig wlan0 create wlandev urtwn0 up
  2) vmstat -m | grep USBdev
  3) service netif restart
  4) vmstat -m | grep USBdev
  
  Also, remove usbd_transfer_drain() call; it is already called by
  usbd_transfer_unsetup().
  
  Tested with RTL8188CUS, STA mode.
  
  Approved by:	re (marius)

Modified:
  head/sys/dev/urtwn/if_urtwn.c

Modified: head/sys/dev/urtwn/if_urtwn.c
==============================================================================
--- head/sys/dev/urtwn/if_urtwn.c	Fri Jun 24 23:22:42 2016	(r302182)
+++ head/sys/dev/urtwn/if_urtwn.c	Fri Jun 24 23:36:22 2016	(r302183)
@@ -683,7 +683,6 @@ urtwn_detach(device_t self)
 {
 	struct urtwn_softc *sc = device_get_softc(self);
 	struct ieee80211com *ic = &sc->sc_ic;
-	unsigned int x;
 
 	/* Prevent further ioctls. */
 	URTWN_LOCK(sc);
@@ -698,26 +697,6 @@ urtwn_detach(device_t self)
 	/* stop all USB transfers */
 	usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER);
 
-	/* Prevent further allocations from RX/TX data lists. */
-	URTWN_LOCK(sc);
-	STAILQ_INIT(&sc->sc_tx_active);
-	STAILQ_INIT(&sc->sc_tx_inactive);
-	STAILQ_INIT(&sc->sc_tx_pending);
-
-	STAILQ_INIT(&sc->sc_rx_active);
-	STAILQ_INIT(&sc->sc_rx_inactive);
-	URTWN_UNLOCK(sc);
-
-	/* drain USB transfers */
-	for (x = 0; x != URTWN_N_TRANSFER; x++)
-		usbd_transfer_drain(sc->sc_xfer[x]);
-
-	/* Free data buffers. */
-	URTWN_LOCK(sc);
-	urtwn_free_tx_list(sc);
-	urtwn_free_rx_list(sc);
-	URTWN_UNLOCK(sc);
-
 	if (ic->ic_softc == sc) {
 		ieee80211_draintask(ic, &sc->cmdq_task);
 		ieee80211_ifdetach(ic);
@@ -1359,12 +1338,19 @@ static void
 urtwn_free_rx_list(struct urtwn_softc *sc)
 {
 	urtwn_free_list(sc, sc->sc_rx, URTWN_RX_LIST_COUNT);
+
+	STAILQ_INIT(&sc->sc_rx_active);
+	STAILQ_INIT(&sc->sc_rx_inactive);
 }
 
 static void
 urtwn_free_tx_list(struct urtwn_softc *sc)
 {
 	urtwn_free_list(sc, sc->sc_tx, URTWN_TX_LIST_COUNT);
+
+	STAILQ_INIT(&sc->sc_tx_active);
+	STAILQ_INIT(&sc->sc_tx_inactive);
+	STAILQ_INIT(&sc->sc_tx_pending);
 }
 
 static void
@@ -5579,6 +5565,8 @@ urtwn_stop(struct urtwn_softc *sc)
 
 	urtwn_abort_xfers(sc);
 	urtwn_drain_mbufq(sc);
+	urtwn_free_tx_list(sc);
+	urtwn_free_rx_list(sc);
 	urtwn_power_off(sc);
 	URTWN_UNLOCK(sc);
 }


More information about the svn-src-all mailing list