iwm schedules a separate task just for calling ieee80211_end_scan().
That function is safe to call in interrupt context.

This wrinkle was already part of the original driver from 2015 but with
a workq instead of a task. Back then, the driver had to run two separate
scan commands in succession (for 2 GHz and then 5 GHz). Which is why a task
was used, since sending another command requires a sleepable context.

Nowadays, with our current firmware, a single scan command is sufficient
so there is no code path which needs to sleep when the scan ends.

This gives me one less asynchronous task to worry about in this driver.

OK?

Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.204
diff -u -p -r1.204 if_iwm.c
--- if_iwm.c    23 Jul 2017 13:51:11 -0000      1.204
+++ if_iwm.c    12 Aug 2017 18:40:12 -0000
@@ -442,7 +442,7 @@ void        iwm_setrates(struct iwm_node *);
 int    iwm_media_change(struct ifnet *);
 void   iwm_newstate_task(void *);
 int    iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
-void   iwm_endscan_cb(void *);
+void   iwm_endscan(struct iwm_softc *);
 void   iwm_fill_sf_command(struct iwm_softc *, struct iwm_sf_cfg_cmd *,
            struct ieee80211_node *);
 int    iwm_sf_config(struct iwm_softc *, int);
@@ -5952,13 +5952,11 @@ iwm_newstate(struct ieee80211com *ic, en
 }
 
 void
-iwm_endscan_cb(void *arg)
+iwm_endscan(struct iwm_softc *sc)
 {
-       struct iwm_softc *sc = arg;
        struct ieee80211com *ic = &sc->sc_ic;
 
-       /* Check if device was reset while scanning. */
-       if (ic->ic_state != IEEE80211_S_SCAN)
+       if ((sc->sc_flags & IWM_FLAG_SCANNING) == 0)
                return;
 
        sc->sc_flags &= ~IWM_FLAG_SCANNING;
@@ -6442,7 +6440,6 @@ iwm_stop(struct ifnet *ifp, int disable)
 
        task_del(systq, &sc->init_task);
        task_del(sc->sc_nswq, &sc->newstate_task);
-       task_del(sc->sc_eswq, &sc->sc_eswk);
        task_del(systq, &sc->setrates_task);
        task_del(systq, &sc->ba_task);
        task_del(systq, &sc->htprot_task);
@@ -7003,22 +7000,21 @@ iwm_notif_intr(struct iwm_softc *sc)
                case IWM_SCAN_ITERATION_COMPLETE: {
                        struct iwm_lmac_scan_complete_notif *notif;
                        SYNC_RESP_STRUCT(notif, pkt);
-                       task_add(sc->sc_eswq, &sc->sc_eswk);
+                       iwm_endscan(sc);
                        break;
                }
 
                case IWM_SCAN_COMPLETE_UMAC: {
                        struct iwm_umac_scan_complete *notif;
                        SYNC_RESP_STRUCT(notif, pkt);
-                       task_add(sc->sc_eswq, &sc->sc_eswk);
+                       iwm_endscan(sc);
                        break;
                }
 
                case IWM_SCAN_ITERATION_COMPLETE_UMAC: {
                        struct iwm_umac_scan_iter_complete_notif *notif;
                        SYNC_RESP_STRUCT(notif, pkt);
-
-                       task_add(sc->sc_eswq, &sc->sc_eswk);
+                       iwm_endscan(sc);
                        break;
                }
 
@@ -7330,7 +7326,6 @@ iwm_attach(struct device *parent, struct
        sc->sc_pcitag = pa->pa_tag;
        sc->sc_dmat = pa->pa_dmat;
 
-       task_set(&sc->sc_eswk, iwm_endscan_cb, sc);
        rw_init(&sc->ioctl_rwl, "iwmioctl");
 
        err = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
@@ -7539,9 +7534,6 @@ iwm_attach(struct device *parent, struct
                goto fail4;
        }
 
-       sc->sc_eswq = taskq_create("iwmes", 1, IPL_NET, 0);
-       if (sc->sc_eswq == NULL)
-               goto fail4;
        sc->sc_nswq = taskq_create("iwmns", 1, IPL_NET, 0);
        if (sc->sc_nswq == NULL)
                goto fail4;
Index: if_iwmvar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwmvar.h,v
retrieving revision 1.31
diff -u -p -r1.31 if_iwmvar.h
--- if_iwmvar.h 16 Jul 2017 22:48:26 -0000      1.31
+++ if_iwmvar.h 12 Aug 2017 18:39:25 -0000
@@ -466,8 +466,7 @@ struct iwm_softc {
        int sc_wantresp;
        int sc_nic_locks;
 
-       struct taskq *sc_nswq, *sc_eswq;
-       struct task sc_eswk;
+       struct taskq *sc_nswq;
 
        struct iwm_rx_phy_info sc_last_phy_info;
        int sc_ampdu_ref;

Reply via email to