diff --git a/ath/if_ath.c b/ath/if_ath.c index a353e97..bdeb976 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -2834,6 +2834,7 @@ internal_take_txbuf_locked(struct ath_softc *sc, int for_management) #endif /* #ifdef IEEE80211_DEBUG_REFCNT */ { struct ath_buf* bf = NULL; + ATH_TXBUF_LOCK_ASSERT(sc); /* Reserve at least ATH_TXBUF_MGT_RESERVED buffers for management frames */ if (ath_get_buffers_available() <= ATH_TXBUF_MGT_RESERVED) { /* Stop the queue, we are full */ @@ -11654,6 +11655,7 @@ ath_return_txbuf_locked(struct ath_softc *sc, struct ath_buf **buf) #endif /* #ifdef IEEE80211_DEBUG_REFCNT */ { void *bufaddr; + ATH_TXBUF_LOCK_ASSERT(sc); if ((buf == NULL) || ((*buf) == NULL)) return; @@ -11740,6 +11742,7 @@ ath_return_txbuf_list_locked_debug(struct ath_softc *sc, ath_bufhead *bfhead, co ath_return_txbuf_list_locked(struct ath_softc *sc, ath_bufhead *bfhead) #endif /* #ifdef IEEE80211_DEBUG_REFCNT */ { + ATH_TXBUF_LOCK_ASSERT(sc); if (!bfhead) return; diff --git a/ath/if_ath_hal_macros.h b/ath/if_ath_hal_macros.h index a28be19..c1b1072 100644 --- a/ath/if_ath_hal_macros.h +++ b/ath/if_ath_hal_macros.h @@ -53,12 +53,26 @@ #define ATH_HAL_LOCK_INIT(_sc) spin_lock_init(&(_sc)->sc_hal_lock) #define ATH_HAL_LOCK_DESTROY(_sc) #define ATH_HAL_LOCK_IRQ(_sc) do { \ - unsigned long __sc_halLockflags; \ + unsigned long __sc_halLockflags; \ + ATH_HAL_UNLOCK_ASSERT(_sc); \ spin_lock_irqsave(&(_sc)->sc_hal_lock, __sc_halLockflags); #define ATH_HAL_UNLOCK_IRQ(_sc) \ + ATH_HAL_LOCK_ASSERT(_sc); \ spin_unlock_irqrestore(&(_sc)->sc_hal_lock, __sc_halLockflags); \ } while(0) #define ATH_HAL_UNLOCK_IRQ_EARLY(_sc) \ + ATH_HAL_LOCK_ASSERT(_sc); \ spin_unlock_irqrestore(&(_sc)->sc_hal_lock, __sc_halLockflags); +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) +#define ATH_HAL_LOCK_ASSERT(_sc) \ + KASSERT(spin_is_locked(&(_sc)->sc_hal_lock), ("hal not locked!")) +#define ATH_HAL_UNLOCK_ASSERT(_sc) \ + KASSERT(!spin_is_locked(&(_sc)->sc_hal_lock), ("hal locked!")) +#else +#define ATH_HAL_LOCK_ASSERT(_sc) +#define ATH_HAL_UNLOCK_ASSERT(_sc) +#endif + + #endif /* #ifndef _IF_ATH_HAL_MACROS_H_ */ diff --git a/ath/if_athvar.h b/ath/if_athvar.h index 46a2f86..736ff48 100644 --- a/ath/if_athvar.h +++ b/ath/if_athvar.h @@ -365,15 +365,30 @@ struct ath_node { #define ATH_NODE(_n) ((struct ath_node *)(_n)) #define ATH_NODE_CONST(ni) ((const struct ath_node *)(ni)) #define ATH_NODE_UAPSD_LOCK_INIT(_an) spin_lock_init(&(_an)->an_uapsd_lock) -#define ATH_NODE_UAPSD_LOCK_IRQ(_an) do { \ - unsigned long __an_uapsd_lockflags; \ +#define ATH_NODE_UAPSD_LOCK_IRQ(_an) do { \ + unsigned long __an_uapsd_lockflags; \ + ATH_NODE_UAPSD_UNLOCK_ASSERT(_an); \ spin_lock_irqsave(&(_an)->an_uapsd_lock, __an_uapsd_lockflags); -#define ATH_NODE_UAPSD_UNLOCK_IRQ(_an) \ + +#define ATH_NODE_UAPSD_UNLOCK_IRQ(_an) \ + ATH_NODE_UAPSD_LOCK_ASSERT(_an); \ spin_unlock_irqrestore(&(_an)->an_uapsd_lock, __an_uapsd_lockflags); \ } while (0) -#define ATH_NODE_UAPSD_UNLOCK_IRQ_EARLY(_an) \ + +#define ATH_NODE_UAPSD_UNLOCK_IRQ_EARLY(_an) \ + ATH_NODE_UAPSD_LOCK_ASSERT(_an); \ spin_unlock_irqrestore(&(_an)->an_uapsd_lock, __an_uapsd_lockflags); +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) +#define ATH_NODE_UAPSD_LOCK_ASSERT(_an) \ + KASSERT(spin_is_locked(&(_an)->an_uapsd_lock), ("uapsd not locked!")) + +#define ATH_NODE_UAPSD_UNLOCK_ASSERT(_an) \ + KASSERT(!spin_is_locked(&(_an)->an_uapsd_lock), ("uapsd locked!")) +#else +#define ATH_NODE_UAPSD_LOCK_ASSERT(_an) +#define ATH_NODE_UAPSD_UNLOCK_ASSERT(_an) +#endif #define ATH_RSSI_LPF_LEN 10 #define ATH_RSSI_DUMMY_MARKER 0x127 @@ -465,7 +480,7 @@ struct ath_txq { spinlock_t axq_lock; /* lock on q and link */ int axq_depth; /* queue depth */ u_int32_t axq_totalqueued; /* total ever queued */ - u_int axq_intrcnt; /* count to determine if descriptor + u_int axq_intrcnt; /* count to determine if descriptor * should generate int on this txq. */ /* @@ -501,17 +516,33 @@ struct ath_vap { #define ATH_TXQ_LOCK_DESTROY(_tq) #define ATH_TXQ_LOCK_IRQ(_tq) do { \ unsigned long __axq_lockflags; \ + ATH_TXQ_UNLOCK_ASSERT(_tq); \ spin_lock_irqsave(&(_tq)->axq_lock, __axq_lockflags); #define ATH_TXQ_UNLOCK_IRQ(_tq) \ + ATH_TXQ_LOCK_ASSERT(_tq); \ spin_unlock_irqrestore(&(_tq)->axq_lock, __axq_lockflags); \ } while (0) #define ATH_TXQ_UNLOCK_IRQ_EARLY(_tq) \ + ATH_TXQ_LOCK_ASSERT(_tq); \ spin_unlock_irqrestore(&(_tq)->axq_lock, __axq_lockflags); -#define ATH_TXQ_LOCK_IRQ_INSIDE(_tq) spin_lock(&(_tq)->axq_lock); -#define ATH_TXQ_UNLOCK_IRQ_INSIDE(_tq) spin_unlock(&(_tq)->axq_lock); +#define ATH_TXQ_LOCK_IRQ_INSIDE(_tq) do { \ + ATH_TXQ_UNLOCK_ASSERT(_tq); \ + spin_lock(&(_tq)->axq_lock); \ +} while(0) +#define ATH_TXQ_UNLOCK_IRQ_INSIDE(_tq) do { \ + ATH_TXQ_LOCK_ASSERT(_tq); \ + spin_unlock(&(_tq)->axq_lock); \ +} while(0) +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) #define ATH_TXQ_LOCK_ASSERT(_tq) \ KASSERT(spin_is_locked(&(_tq)->axq_lock), ("txq not locked!")) +#define ATH_TXQ_UNLOCK_ASSERT(_tq) \ + KASSERT(!spin_is_locked(&(_tq)->axq_lock), ("txq locked!")) +#else +#define ATH_TXQ_LOCK_ASSERT(_tq) +#define ATH_TXQ_UNLOCK_ASSERT(_tq) +#endif #define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field) do { \ STAILQ_INSERT_TAIL( &(_tq)->axq_q, (_elm), _field); \ @@ -726,28 +757,51 @@ typedef void (*ath_callback) (struct ath_softc *); #define ATH_TXBUF_LOCK_DESTROY(_sc) #define ATH_TXBUF_LOCK_IRQ(_sc) do { \ unsigned long __txbuflockflags; \ + ATH_TXBUF_UNLOCK_ASSERT(_sc); \ spin_lock_irqsave(&(_sc)->sc_txbuflock, __txbuflockflags); #define ATH_TXBUF_UNLOCK_IRQ(_sc) \ + ATH_TXBUF_LOCK_ASSERT(_sc); \ spin_unlock_irqrestore(&(_sc)->sc_txbuflock, __txbuflockflags); \ } while (0) #define ATH_TXBUF_UNLOCK_IRQ_EARLY(_sc) \ + ATH_TXBUF_LOCK_ASSERT(_sc); \ spin_unlock_irqrestore(&(_sc)->sc_txbuflock, __txbuflockflags); +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) #define ATH_TXBUF_LOCK_ASSERT(_sc) \ KASSERT(spin_is_locked(&(_sc)->sc_txbuflock), ("txbuf not locked!")) +#define ATH_TXBUF_UNLOCK_ASSERT(_sc) \ + KASSERT(!spin_is_locked(&(_sc)->sc_txbuflock), ("txbuf locked!")) +#else +#define ATH_TXBUF_LOCK_ASSERT(_sc) +#define ATH_TXBUF_UNLOCK_ASSERT(_sc) +#endif #define ATH_RXBUF_LOCK_INIT(_sc) spin_lock_init(&(_sc)->sc_rxbuflock) #define ATH_RXBUF_LOCK_DESTROY(_sc) #define ATH_RXBUF_LOCK_IRQ(_sc) do { \ unsigned long __rxbuflockflags; \ + ATH_RXBUF_UNLOCK_ASSERT(_sc); \ spin_lock_irqsave(&(_sc)->sc_rxbuflock, __rxbuflockflags); #define ATH_RXBUF_UNLOCK_IRQ(_sc) \ + ATH_RXBUF_LOCK_ASSERT(_sc); \ spin_unlock_irqrestore(&(_sc)->sc_rxbuflock, __rxbuflockflags); \ } while (0) #define ATH_RXBUF_UNLOCK_IRQ_EARLY(_sc) \ + ATH_RXBUF_LOCK_ASSERT(_sc); \ spin_unlock_irqrestore(&(_sc)->sc_rxbuflock, __rxbuflockflags); +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) +#define ATH_RXBUF_LOCK_ASSERT(_sc) \ + KASSERT(spin_is_locked(&(_sc)->sc_rxbuflock), ("rxbuf not locked!")) +#define ATH_RXBUF_UNLOCK_ASSERT(_sc) \ + KASSERT(!spin_is_locked(&(_sc)->sc_rxbuflock), ("rxbuf locked!")) +#else +#define ATH_RXBUF_LOCK_ASSERT(_sc) +#define ATH_RXBUF_UNLOCK_ASSERT(_sc) +#endif + /* Protects the device from concurrent accesses */ #define ATH_LOCK_INIT(_sc) init_MUTEX(&(_sc)->sc_lock) #define ATH_LOCK_DESTROY(_sc) diff --git a/net80211/ieee80211_acl.c b/net80211/ieee80211_acl.c index cc851c1..b4234f1 100644 --- a/net80211/ieee80211_acl.c +++ b/net80211/ieee80211_acl.c @@ -180,7 +180,7 @@ acl_add(struct ieee80211vap *vap, const u_int8_t mac[IEEE80211_ADDR_LEN]) hash = ACL_HASH(mac); LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) { if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) { - ACL_UNLOCK(as); + ACL_UNLOCK_EARLY(as); FREE(new, M_80211_ACL); IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, "ACL: add %s failed, already present\n", diff --git a/net80211/ieee80211_linux.h b/net80211/ieee80211_linux.h index f831884..9d5d304 100644 --- a/net80211/ieee80211_linux.h +++ b/net80211/ieee80211_linux.h @@ -126,38 +126,53 @@ typedef void *IEEE80211_TQUEUE_ARG; * UAPSD locking */ typedef spinlock_t ieee80211com_lock_t; -#define IEEE80211_LOCK_INIT(_ic, _name) \ +#define IEEE80211_LOCK_INIT(_ic, _name) \ spin_lock_init(&(_ic)->ic_comlock) #define IEEE80211_LOCK_DESTROY(_ic) -#define IEEE80211_LOCK_IRQ(_ic) do { \ - unsigned long __ilockflags; \ +#define IEEE80211_LOCK_IRQ(_ic) do { \ + unsigned long __ilockflags; \ + IEEE80211_UNLOCK_ASSERT(_ic); \ spin_lock_irqsave(&(_ic)->ic_comlock, __ilockflags); #define IEEE80211_UNLOCK_IRQ(_ic) \ + IEEE80211_LOCK_ASSERT(_ic); \ spin_unlock_irqrestore(&(_ic)->ic_comlock, __ilockflags); \ } while (0) #define IEEE80211_UNLOCK_IRQ_EARLY(_ic) \ + IEEE80211_LOCK_ASSERT(_ic); \ spin_unlock_irqrestore(&(_ic)->ic_comlock, __ilockflags); #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) #define IEEE80211_LOCK_ASSERT(_ic) \ KASSERT(spin_is_locked(&(_ic)->ic_comlock), ("ieee80211com not locked!")) +#define IEEE80211_UNLOCK_ASSERT(_ic) \ + KASSERT(!spin_is_locked(&(_ic)->ic_comlock), ("ieee80211com locked!")) #else #define IEEE80211_LOCK_ASSERT(_ic) +#define IEEE80211_UNLOCK_ASSERT(_ic) #endif #define IEEE80211_VAPS_LOCK_INIT(_ic, _name) \ spin_lock_init(&(_ic)->ic_vapslock) #define IEEE80211_VAPS_LOCK_DESTROY(_ic) -#define IEEE80211_VAPS_LOCK_BH(_ic) spin_lock_bh(&(_ic)->ic_vapslock); -#define IEEE80211_VAPS_UNLOCK_BH(_ic) spin_unlock_bh(&(_ic)->ic_vapslock); +#define IEEE80211_VAPS_LOCK_BH(_ic) do { \ + IEEE80211_VAPS_UNLOCK_ASSERT(_ic); \ + spin_lock_bh(&(_ic)->ic_vapslock); +#define IEEE80211_VAPS_UNLOCK_BH(_ic) \ + IEEE80211_VAPS_LOCK_ASSERT(_ic); \ + spin_unlock_bh(&(_ic)->ic_vapslock); \ +} while (0) #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) #define IEEE80211_VAPS_LOCK_ASSERT(_ic) \ KASSERT(spin_is_locked(&(_ic)->ic_vapslock), \ ("ieee80211com_vaps not locked!")) +#define IEEE80211_VAPS_UNLOCK_ASSERT(_ic) \ + KASSERT(!spin_is_locked(&(_ic)->ic_vapslock), \ + ("ieee80211com_vaps locked!")) #else #define IEEE80211_VAPS_LOCK_ASSERT(_ic) +#define IEEE80211_VAPS_UNLOCK_ASSERT(_ic) #endif @@ -171,19 +186,26 @@ typedef spinlock_t ieee80211_node_lock_t; #define IEEE80211_NODE_LOCK_DESTROY(_ni) #define IEEE80211_NODE_LOCK_IRQ(_ni) do { \ unsigned long __node_lockflags; \ + IEEE80211_NODE_UNLOCK_ASSERT(_ni); \ spin_lock_irqsave(&(_ni)->ni_nodelock, __node_lockflags); -#define IEEE80211_NODE_UNLOCK_IRQ(_ni) \ +#define IEEE80211_NODE_UNLOCK_IRQ(_ni) \ + IEEE80211_NODE_LOCK_ASSERT(_ni); \ spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags); \ } while (0) #define IEEE80211_NODE_UNLOCK_IRQ_EARLY(_ni) \ + IEEE80211_NODE_LOCK_ASSERT(_ni); \ spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags); #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) -#define IEEE80211_NODE_LOCK_ASSERT(_nt) \ +#define IEEE80211_NODE_LOCK_ASSERT(_ni) \ KASSERT(spin_is_locked(&(_ni)->ni_nodelock), \ ("802.11 node not locked!")) +#define IEEE80211_NODE_UNLOCK_ASSERT(_ni) \ + KASSERT(!spin_is_locked(&(_ni)->ni_nodelock), \ + ("802.11 node locked!")) #else #define IEEE80211_NODE_LOCK_ASSERT(_ni) +#define IEEE80211_NODE_UNLOCK_ASSERT(_ni) #endif #endif /* node lock */ @@ -245,14 +267,25 @@ typedef spinlock_t ieee80211_scan_lock_t; typedef spinlock_t acl_lock_t; #define ACL_LOCK_INIT(_as, _name) spin_lock_init(&(_as)->as_lock) #define ACL_LOCK_DESTROY(_as) -#define ACL_LOCK(_as) spin_lock(&(_as)->as_lock) -#define ACL_UNLOCK(_as) spin_unlock(&(_as)->as_lock) +#define ACL_LOCK(_as) do { \ + ACL_UNLOCK_ASSERT(_as); \ + spin_lock(&(_as)->as_lock); +#define ACL_UNLOCK(_as) \ + ACL_LOCK_ASSERT(_as); \ + spin_unlock(&(_as)->as_lock); \ +} while(0) +#define ACL_UNLOCK_EARLY(_as) \ + ACL_LOCK_ASSERT(_as); \ + spin_unlock(&(_as)->as_lock); #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) #define ACL_LOCK_ASSERT(_as) \ KASSERT(spin_is_locked(&(_as)->as_lock), ("ACL not locked!")) +#define ACL_UNLOCK_ASSERT(_as) \ + KASSERT(!spin_is_locked(&(_as)->as_lock), ("ACL locked!")) #else #define ACL_LOCK_ASSERT(_as) +#define ACL_UNLOCK_ASSERT(_as) #endif /* __skb_append got a third parameter in 2.6.14 */ @@ -271,13 +304,28 @@ typedef spinlock_t acl_lock_t; #define IEEE80211_NODE_SAVEQ_QLEN(_ni) skb_queue_len(&(_ni)->ni_savedq) #define IEEE80211_NODE_SAVEQ_LOCK_IRQ(_ni) do { \ unsigned long __qlockflags; \ + IEEE80211_NODE_SAVEQ_UNLOCK_ASSERT(_ni); \ spin_lock_irqsave(&(_ni)->ni_savedq.lock, __qlockflags); -#define IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(_ni) \ +#define IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(_ni) \ + IEEE80211_NODE_SAVEQ_LOCK_ASSERT(_ni); \ spin_unlock_irqrestore(&(_ni)->ni_savedq.lock, __qlockflags); \ } while (0) #define IEEE80211_NODE_SAVEQ_UNLOCK_IRQ_EARLY(_ni) \ + IEEE80211_NODE_SAVEQ_LOCK_ASSERT(_ni); \ spin_unlock_irqrestore(&(_ni)->ni_savedq.lock, __qlockflags); +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) +#define IEEE80211_NODE_SAVEQ_LOCK_ASSERT(_ni) \ + KASSERT(spin_is_locked(&(_ni)->ni_savedq.lock), \ + ("node saveq not locked!")) +#define IEEE80211_NODE_SAVEQ_UNLOCK_ASSERT(_ni) \ + KASSERT(!spin_is_locked(&(_ni)->ni_savedq.lock), \ + ("node saveq locked!")) +#else +#define IEEE80211_NODE_SAVEQ_LOCK_ASSERT(_ic) +#define IEEE80211_NODE_SAVEQ_UNLOCK_ASSERT(_ic) +#endif + /* caller MUST lock IEEE80211_NODE_SAVEQ */ #define IEEE80211_NODE_SAVEQ_DEQUEUE(_ni, _skb, _qlen) do { \ _skb = __skb_dequeue(&(_ni)->ni_savedq); \ diff --git a/net80211/ieee80211_proto.c b/net80211/ieee80211_proto.c index 74e7ad4..d692510 100644 --- a/net80211/ieee80211_proto.c +++ b/net80211/ieee80211_proto.c @@ -816,6 +816,8 @@ ieee80211_wme_updateparams_locked(struct ieee80211vap *vap) enum ieee80211_phymode mode; int i; + IEEE80211_LOCK_ASSERT(vap->iv_ic); + /* set up the channel access parameters for the physical device */ for (i = 0; i < WME_NUM_AC; i++) {