Skip to content

Commit

Permalink
ath9k: Fix deadlock while updating p2p beacon timer
Browse files Browse the repository at this point in the history
pm_lock is taken twice while syncing HW TSF of p2p vif.
Fix this by taking the lock at caller side.

Cc: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Rajkumar Manoharan authored and John W. Linville committed May 29, 2014
1 parent 52f98a5 commit 60ccc10
Showing 1 changed file with 8 additions and 10 deletions.
18 changes: 8 additions & 10 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1757,7 +1757,6 @@ void ath9k_p2p_ps_timer(void *priv)
void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
{
struct ath_vif *avp = (void *)vif->drv_priv;
unsigned long flags;
u32 tsf;

if (!sc->p2p_ps_timer)
Expand All @@ -1767,14 +1766,9 @@ void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
return;

sc->p2p_ps_vif = avp;

spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (!(sc->ps_flags & PS_BEACON_SYNC)) {
tsf = ath9k_hw_gettsf32(sc->sc_ah);
ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
ath9k_update_p2p_ps_timer(sc, avp);
}
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
tsf = ath9k_hw_gettsf32(sc->sc_ah);
ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
ath9k_update_p2p_ps_timer(sc, avp);
}

static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
Expand All @@ -1791,6 +1785,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath_vif *avp = (void *)vif->drv_priv;
unsigned long flags;
int slottime;

ath9k_ps_wakeup(sc);
Expand Down Expand Up @@ -1853,7 +1848,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,

if (changed & BSS_CHANGED_P2P_PS) {
spin_lock_bh(&sc->sc_pcu_lock);
ath9k_update_p2p_ps(sc, vif);
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (!(sc->ps_flags & PS_BEACON_SYNC))
ath9k_update_p2p_ps(sc, vif);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
spin_unlock_bh(&sc->sc_pcu_lock);
}

Expand Down

0 comments on commit 60ccc10

Please sign in to comment.