Stefan Sperling wrote:
> Replace the ioctl tsleep/wakeup BUSY flag dance with an rwlock.

This does the same change for the other intel wifi drivers.

Mechanical change, but I don't have hardware to test.

Index: if_ipw.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ipw.c,v
retrieving revision 1.115
diff -u -p -r1.115 if_ipw.c
--- if_ipw.c    13 Apr 2016 10:34:32 -0000      1.115
+++ if_ipw.c    4 Sep 2016 19:14:28 -0000
@@ -28,6 +28,7 @@
 #include <sys/task.h>
 #include <sys/mbuf.h>
 #include <sys/kernel.h>
+#include <sys/rwlock.h>
 #include <sys/socket.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
@@ -203,6 +204,7 @@ ipw_attach(struct device *parent, struct
        }
        printf(": %s", intrstr);
 
+       rw_init(&sc->sc_rwlock, "ipwlock");
        task_set(&sc->sc_scantask, ipw_scan, sc);
        task_set(&sc->sc_authandassoctask, ipw_auth_and_assoc, sc);
 
@@ -318,17 +320,14 @@ ipw_wakeup(struct ipw_softc *sc)
        data &= ~0x0000ff00;
        pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
 
+       rw_enter_write(&sc->sc_rwlock);
        s = splnet();
-       while (sc->sc_flags & IPW_FLAG_BUSY)
-               tsleep(&sc->sc_flags, PZERO, "ipwpwr", 0);
-       sc->sc_flags |= IPW_FLAG_BUSY;
 
        if (ifp->if_flags & IFF_UP)
                ipw_init(ifp);
 
-       sc->sc_flags &= ~IPW_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
 }
 
 int
@@ -1359,18 +1358,10 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd,
        struct ifreq *ifr;
        int s, error = 0;
 
-       s = splnet();
-       /*
-        * Prevent processes from entering this function while another
-        * process is tsleep'ing in it.
-        */
-       while ((sc->sc_flags & IPW_FLAG_BUSY) && error == 0)
-               error = tsleep(&sc->sc_flags, PCATCH, "ipwioc", 0);
-       if (error != 0) {
-               splx(s);
+       error = rw_enter(&sc->sc_rwlock, RW_ENTER | RW_INTR);
+       if (error)
                return error;
-       }
-       sc->sc_flags |= IPW_FLAG_BUSY;
+       s = splnet();
 
        switch (cmd) {
        case SIOCSIFADDR:
@@ -1419,9 +1410,8 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd,
                error = 0;
        }
 
-       sc->sc_flags &= ~IPW_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
        return error;
 }
 
@@ -1483,8 +1473,6 @@ ipw_stop_master(struct ipw_softc *sc)
 
        tmp = CSR_READ_4(sc, IPW_CSR_RST);
        CSR_WRITE_4(sc, IPW_CSR_RST, tmp | IPW_RST_PRINCETON_RESET);
-
-       sc->sc_flags &= ~IPW_FLAG_FW_INITED;
 }
 
 int
@@ -2004,7 +1992,6 @@ ipw_init(struct ifnet *ifp)
                printf("%s: could not load firmware\n", sc->sc_dev.dv_xname);
                goto fail2;
        }
-       sc->sc_flags |= IPW_FLAG_FW_INITED;
        free(fw.data, M_DEVBUF, fw.size);
        fw.data = NULL;
 
Index: if_ipwvar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ipwvar.h,v
retrieving revision 1.25
diff -u -p -r1.25 if_ipwvar.h
--- if_ipwvar.h 1 Sep 2015 07:09:55 -0000       1.25
+++ if_ipwvar.h 4 Sep 2016 19:13:22 -0000
@@ -82,7 +82,7 @@ struct ipw_softc {
        int                             (*sc_newstate)(struct ieee80211com *,
                                            enum ieee80211_state, int);
 
-       uint32_t                        sc_flags;
+       struct rwlock                   sc_rwlock;
 #define IPW_FLAG_FW_INITED     (1 << 0)
 #define IPW_FLAG_BUSY          (1 << 1)
 
Index: if_iwi.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwi.c,v
retrieving revision 1.132
diff -u -p -r1.132 if_iwi.c
--- if_iwi.c    13 Apr 2016 10:34:32 -0000      1.132
+++ if_iwi.c    4 Sep 2016 19:16:00 -0000
@@ -27,6 +27,7 @@
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
 #include <sys/kernel.h>
+#include <sys/rwlock.h>
 #include <sys/socket.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
@@ -317,6 +318,7 @@ iwi_attach(struct device *parent, struct
        sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
 #endif
 
+       rw_init(&sc->sc_rwlock, "iwilock");
        task_set(&sc->init_task, iwi_init_task, sc);
        return;
 
@@ -364,17 +366,14 @@ iwi_init_task(void *arg1)
        struct ifnet *ifp = &sc->sc_ic.ic_if;
        int s;
 
+       rw_enter_write(&sc->sc_rwlock);
        s = splnet();
-       while (sc->sc_flags & IWI_FLAG_BUSY)
-               tsleep(&sc->sc_flags, 0, "iwipwr", 0);
-       sc->sc_flags |= IWI_FLAG_BUSY;
 
        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
                iwi_init(ifp);
 
-       sc->sc_flags &= ~IWI_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
 }
 
 int
@@ -1451,18 +1450,10 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd,
        struct ifreq *ifr;
        int s, error = 0;
 
-       s = splnet();
-       /*
-        * Prevent processes from entering this function while another
-        * process is tsleep'ing in it.
-        */
-       while ((sc->sc_flags & IWI_FLAG_BUSY) && error == 0)
-               error = tsleep(&sc->sc_flags, PCATCH, "iwiioc", 0);
-       if (error != 0) {
-               splx(s);
+       error = rw_enter(&sc->sc_rwlock, RW_WRITE | RW_INTR);
+       if (error)
                return error;
-       }
-       sc->sc_flags |= IWI_FLAG_BUSY;
+       s = splnet();
 
        switch (cmd) {
        case SIOCSIFADDR:
@@ -1511,9 +1502,8 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd,
                error = 0;
        }
 
-       sc->sc_flags &= ~IWI_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
        return error;
 }
 
@@ -1539,8 +1529,6 @@ iwi_stop_master(struct iwi_softc *sc)
 
        tmp = CSR_READ_4(sc, IWI_CSR_RST);
        CSR_WRITE_4(sc, IWI_CSR_RST, tmp | IWI_RST_PRINCETON_RESET);
-
-       sc->sc_flags &= ~IWI_FLAG_FW_INITED;
 }
 
 int
@@ -2282,7 +2270,6 @@ iwi_init(struct ifnet *ifp)
        }
 
        free(data, M_DEVBUF, size);
-       sc->sc_flags |= IWI_FLAG_FW_INITED;
 
        if ((error = iwi_config(sc)) != 0) {
                printf("%s: device configuration failed\n",
Index: if_iwivar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwivar.h,v
retrieving revision 1.25
diff -u -p -r1.25 if_iwivar.h
--- if_iwivar.h 3 Dec 2013 22:37:24 -0000       1.25
+++ if_iwivar.h 4 Sep 2016 19:13:41 -0000
@@ -91,7 +91,7 @@ struct iwi_softc {
        int                     (*sc_newstate)(struct ieee80211com *,
                                    enum ieee80211_state, int);
 
-       uint32_t                sc_flags;
+       struct rwlock           sc_rwlock;
 #define IWI_FLAG_FW_INITED     (1 << 0)
 #define IWI_FLAG_BUSY          (1 << 1)
 
Index: if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.171
diff -u -p -r1.171 if_iwn.c
--- if_iwn.c    2 Sep 2016 17:10:48 -0000       1.171
+++ if_iwn.c    4 Sep 2016 19:18:03 -0000
@@ -27,6 +27,7 @@
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
 #include <sys/kernel.h>
+#include <sys/rwlock.h>
 #include <sys/socket.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
@@ -537,6 +538,7 @@ iwn_attach(struct device *parent, struct
        iwn_radiotap_attach(sc);
 #endif
        timeout_set(&sc->calib_to, iwn_calib_timeout, sc);
+       rw_init(&sc->sc_rwlock, "iwnlock");
        task_set(&sc->init_task, iwn_init_task, sc);
        return;
 
@@ -776,17 +778,14 @@ iwn_init_task(void *arg1)
        struct ifnet *ifp = &sc->sc_ic.ic_if;
        int s;
 
+       rw_enter_write(&sc->sc_rwlock);
        s = splnet();
-       while (sc->sc_flags & IWN_FLAG_BUSY)
-               tsleep(&sc->sc_flags, 0, "iwnpwr", 0);
-       sc->sc_flags |= IWN_FLAG_BUSY;
 
        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
                iwn_init(ifp);
 
-       sc->sc_flags &= ~IWN_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
 }
 
 int
@@ -3212,18 +3211,10 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd,
        struct ifreq *ifr;
        int s, error = 0;
 
-       s = splnet();
-       /*
-        * Prevent processes from entering this function while another
-        * process is tsleep'ing in it.
-        */
-       while ((sc->sc_flags & IWN_FLAG_BUSY) && error == 0)
-               error = tsleep(&sc->sc_flags, PCATCH, "iwnioc", 0);
-       if (error != 0) {
-               splx(s);
+       error = rw_enter(&sc->sc_rwlock, RW_WRITE | RW_INTR);
+       if (error)
                return error;
-       }
-       sc->sc_flags |= IWN_FLAG_BUSY;
+       s = splnet();
 
        switch (cmd) {
        case SIOCSIFADDR:
@@ -3279,9 +3270,8 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd,
                }
        }
 
-       sc->sc_flags &= ~IWN_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
        return error;
 }
 
Index: if_iwnvar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwnvar.h,v
retrieving revision 1.30
diff -u -p -r1.30 if_iwnvar.h
--- if_iwnvar.h 5 Jan 2016 18:41:15 -0000       1.30
+++ if_iwnvar.h 4 Sep 2016 19:15:22 -0000
@@ -190,6 +190,7 @@ struct iwn_softc {
 
        bus_dma_tag_t           sc_dmat;
 
+       struct rwlock           sc_rwlock;
        u_int                   sc_flags;
 #define IWN_FLAG_HAS_5GHZ      (1 << 0)
 #define IWN_FLAG_HAS_OTPROM    (1 << 1)
Index: if_wpi.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_wpi.c,v
retrieving revision 1.134
diff -u -p -r1.134 if_wpi.c
--- if_wpi.c    17 Aug 2016 11:08:08 -0000      1.134
+++ if_wpi.c    4 Sep 2016 19:18:20 -0000
@@ -27,6 +27,7 @@
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
 #include <sys/kernel.h>
+#include <sys/rwlock.h>
 #include <sys/socket.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
@@ -323,6 +324,7 @@ wpi_attach(struct device *parent, struct
        wpi_radiotap_attach(sc);
 #endif
        timeout_set(&sc->calib_to, wpi_calib_timeout, sc);
+       rw_init(&sc->sc_rwlock, "wpilock");
        task_set(&sc->init_task, wpi_init_task, sc);
        return;
 
@@ -421,17 +423,14 @@ wpi_init_task(void *arg1)
        struct ifnet *ifp = &sc->sc_ic.ic_if;
        int s;
 
+       rw_enter_write(&sc->sc_rwlock);
        s = splnet();
-       while (sc->sc_flags & WPI_FLAG_BUSY)
-               tsleep(&sc->sc_flags, 0, "wpipwr", 0);
-       sc->sc_flags |= WPI_FLAG_BUSY;
 
        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
                wpi_init(ifp);
 
-       sc->sc_flags &= ~WPI_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
 }
 
 int
@@ -1968,18 +1967,10 @@ wpi_ioctl(struct ifnet *ifp, u_long cmd,
        struct ifreq *ifr;
        int s, error = 0;
 
-       s = splnet();
-       /*
-        * Prevent processes from entering this function while another
-        * process is tsleep'ing in it.
-        */
-       while ((sc->sc_flags & WPI_FLAG_BUSY) && error == 0)
-               error = tsleep(&sc->sc_flags, PCATCH, "wpiioc", 0);
-       if (error != 0) {
-               splx(s);
+       error = rw_enter(&sc->sc_rwlock, RW_WRITE | RW_INTR);
+       if (error)
                return error;
-       }
-       sc->sc_flags |= WPI_FLAG_BUSY;
+       s = splnet();
 
        switch (cmd) {
        case SIOCSIFADDR:
@@ -2034,9 +2025,8 @@ wpi_ioctl(struct ifnet *ifp, u_long cmd,
                }
        }
 
-       sc->sc_flags &= ~WPI_FLAG_BUSY;
-       wakeup(&sc->sc_flags);
        splx(s);
+       rw_exit_write(&sc->sc_rwlock);
        return error;
 }
 
Index: if_wpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_wpivar.h,v
retrieving revision 1.25
diff -u -p -r1.25 if_wpivar.h
--- if_wpivar.h 28 Nov 2013 20:07:32 -0000      1.25
+++ if_wpivar.h 4 Sep 2016 19:15:38 -0000
@@ -140,6 +140,7 @@ struct wpi_softc {
 
        bus_dma_tag_t           sc_dmat;
 
+       struct rwlock           sc_rwlock;
        u_int                   sc_flags;
 #define WPI_FLAG_HAS_5GHZ      (1 << 0)
 #define WPI_FLAG_BUSY          (1 << 1)

Reply via email to