.. would people please try this on hostap/ap/etc modes with the
atheros driver on -HEAD? I'd really like to make sure I haven't broken
things. :(

It does fix panics for me, but I'm worried I've broken other things.

Thanks!


-adrian

---------- Forwarded message ----------
From: Adrian Chadd <adr...@freebsd.org>
Date: 13 November 2014 20:26
Subject: svn commit: r274493 - head/sys/dev/ath
To: src-committ...@freebsd.org, svn-src-...@freebsd.org,
svn-src-h...@freebsd.org


Author: adrian
Date: Fri Nov 14 04:26:26 2014
New Revision: 274493
URL: https://svnweb.freebsd.org/changeset/base/274493

Log:
  Migrate the callouts from using mutex locks to being mpsafe with
  the locks being held by the callers.

  Kill callout_drain() and use callout_stop().

Modified:
  head/sys/dev/ath/if_ath.c

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c   Fri Nov 14 00:25:10 2014        (r274492)
+++ head/sys/dev/ath/if_ath.c   Fri Nov 14 04:26:26 2014        (r274493)
@@ -669,8 +669,8 @@ ath_attach(u_int16_t devid, struct ath_s
                goto bad;
        }

-       callout_init_mtx(&sc->sc_cal_ch, &sc->sc_mtx, 0);
-       callout_init_mtx(&sc->sc_wd_ch, &sc->sc_mtx, 0);
+       callout_init(&sc->sc_cal_ch, 1);        /* MPSAFE */
+       callout_init(&sc->sc_wd_ch, 1);         /* MPSAFE */

        ATH_TXBUF_LOCK_INIT(sc);

@@ -1812,7 +1812,10 @@ ath_suspend(struct ath_softc *sc)
         */
        ath_hal_intrset(sc->sc_ah, 0);
        taskqueue_block(sc->sc_tq);
-       callout_drain(&sc->sc_cal_ch);
+
+       ATH_LOCK(sc);
+       callout_stop(&sc->sc_cal_ch);
+       ATH_UNLOCK(sc);

        /*
         * XXX ensure sc_invalid is 1
@@ -5599,6 +5602,10 @@ ath_calibrate(void *arg)
        HAL_BOOL aniCal, shortCal = AH_FALSE;
        int nextcal;

+       ATH_UNLOCK_ASSERT(sc);
+
+       ATH_LOCK(sc);
+
        /*
         * Force the hardware awake for ANI work.
         */
@@ -5638,6 +5645,7 @@ ath_calibrate(void *arg)
                        taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask);
                        callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc);
                        ath_power_restore_power_state(sc);
+                       ATH_UNLOCK(sc);
                        return;
                }
                /*
@@ -5713,6 +5721,7 @@ restart:
         * Restore power state now that we're done.
         */
        ath_power_restore_power_state(sc);
+       ATH_UNLOCK(sc);
 }

 static void
@@ -5888,12 +5897,17 @@ ath_newstate(struct ieee80211vap *vap, e
         * Now, wake the thing up.
         */
        ath_power_set_power_state(sc, HAL_PM_AWAKE);
+
+       /*
+        * And stop the calibration callout whilst we have
+        * ATH_LOCK held.
+        */
+       callout_stop(&sc->sc_cal_ch);
        ATH_UNLOCK(sc);

        if (ostate == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
                csa_run_transition = 1;

-       callout_drain(&sc->sc_cal_ch);
        ath_hal_setledstate(ah, leds[nstate]);  /* set LED */

        if (nstate == IEEE80211_S_SCAN) {
@@ -6084,7 +6098,6 @@ ath_newstate(struct ieee80211vap *vap, e
                ATH_LOCK(sc);
                ath_power_setselfgen(sc, HAL_PM_AWAKE);
                ath_power_setpower(sc, HAL_PM_AWAKE);
-               ATH_UNLOCK(sc);

                /*
                 * Finally, start any timers and the task q thread
@@ -6097,6 +6110,7 @@ ath_newstate(struct ieee80211vap *vap, e
                        DPRINTF(sc, ATH_DEBUG_CALIBRATE,
                            "%s: calibration disabled\n", __func__);
                }
+               ATH_UNLOCK(sc);

                taskqueue_unblock(sc->sc_tq);
        } else if (nstate == IEEE80211_S_INIT) {
@@ -6457,13 +6471,13 @@ ath_watchdog(void *arg)
        struct ath_softc *sc = arg;
        int do_reset = 0;

+       ATH_LOCK(sc);
+
        if (sc->sc_wd_timer != 0 && --sc->sc_wd_timer == 0) {
                struct ifnet *ifp = sc->sc_ifp;
                uint32_t hangs;

-               ATH_LOCK(sc);
                ath_power_set_power_state(sc, HAL_PM_AWAKE);
-               ATH_UNLOCK(sc);

                if (ath_hal_gethangstate(sc->sc_ah, 0xffff, &hangs) &&
                    hangs != 0) {
@@ -6475,9 +6489,7 @@ ath_watchdog(void *arg)
                if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
                sc->sc_stats.ast_watchdog++;

-               ATH_LOCK(sc);
                ath_power_restore_power_state(sc);
-               ATH_UNLOCK(sc);
        }

        /*
@@ -6491,6 +6503,8 @@ ath_watchdog(void *arg)
        }

        callout_schedule(&sc->sc_wd_ch, hz);
+
+       ATH_UNLOCK(sc);
 }

 /*
_______________________________________________
freebsd-wireless@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-wireless
To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"

Reply via email to