Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src-draft/trunk]: src/sys/dev/usb Fix resource leak in rx/tx free lists.



details:   https://anonhg.NetBSD.org/src-all/rev/25c757c686bf
branches:  trunk
changeset: 989550:25c757c686bf
user:      nat <nat%NetBSD.org@localhost>
date:      Mon Apr 27 07:37:01 2020 +0000

description:
Fix resource leak in rx/tx free lists.

diffstat:

 sys/dev/usb/if_urtwn.c |  20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diffs (57 lines):

diff -r ec6cda689143 -r 25c757c686bf sys/dev/usb/if_urtwn.c
--- a/sys/dev/usb/if_urtwn.c    Mon Apr 27 07:38:25 2020 +0000
+++ b/sys/dev/usb/if_urtwn.c    Mon Apr 27 07:37:01 2020 +0000
@@ -823,19 +823,23 @@
 static void
 urtwn_free_rx_list(struct urtwn_softc *sc)
 {
+       struct urtwn_rx_data *data = NULL;
        struct usbd_xfer *xfer;
-       size_t i;
 
        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
        /* NB: Caller must abort pipe first. */
        for (size_t j = 0; j < sc->rx_npipe; j++) {
-               for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
+               mutex_enter(&sc->sc_rx_mtx); 
+               while (!TAILQ_EMPTY(&sc->rx_free_list[j])) {
+                       data = TAILQ_FIRST(&sc->rx_free_list[j]);
+                       TAILQ_REMOVE(&sc->rx_free_list[j], data, next);
                        CTASSERT(sizeof(xfer) == sizeof(void *));
-                       xfer = atomic_swap_ptr(&sc->rx_data[j][i].xfer, NULL);
+                       xfer = atomic_swap_ptr(&data->xfer, NULL);
                        if (xfer != NULL)
                                usbd_destroy_xfer(xfer);
                }
+               mutex_exit(&sc->sc_rx_mtx);
        }
 }
 
@@ -884,19 +888,23 @@
 static void
 urtwn_free_tx_list(struct urtwn_softc *sc)
 {
+       struct urtwn_tx_data *data = NULL;
        struct usbd_xfer *xfer;
-       size_t i;
 
        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
        /* NB: Caller must abort pipe first. */
        for (size_t j = 0; j < sc->tx_npipe; j++) {
-               for (i = 0; i < URTWN_TX_LIST_COUNT; i++) {
+               mutex_enter(&sc->sc_tx_mtx); 
+               while (!TAILQ_EMPTY(&sc->tx_free_list[j])) {
+                       data = TAILQ_FIRST(&sc->tx_free_list[j]);
+                       TAILQ_REMOVE(&sc->tx_free_list[j], data, next);
                        CTASSERT(sizeof(xfer) == sizeof(void *));
-                       xfer = atomic_swap_ptr(&sc->tx_data[j][i].xfer, NULL);
+                       xfer = atomic_swap_ptr(&data->xfer, NULL);
                        if (xfer != NULL)
                                usbd_destroy_xfer(xfer);
                }
+               mutex_exit(&sc->sc_tx_mtx);
        }
 }
 



Home | Main Index | Thread Index | Old Index