summaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg2010-11-29 11:09:16 +0100
committerJohn W. Linville2010-11-29 21:30:30 +0100
commitdd318575ff0aae91ac4cbcc5b60c184e59267212 (patch)
tree140a0104b99b8edef7b961b4de9182e092782cf9 /net/mac80211/rx.c
parentath9k: fix software retry counter tracking (diff)
downloadkernel-qcow2-linux-dd318575ff0aae91ac4cbcc5b60c184e59267212.tar.gz
kernel-qcow2-linux-dd318575ff0aae91ac4cbcc5b60c184e59267212.tar.xz
kernel-qcow2-linux-dd318575ff0aae91ac4cbcc5b60c184e59267212.zip
mac80211: fix RX aggregation locking
The RX aggregation locking documentation was wrong, which led Christian to also code the timer timeout handling for it somewhat wrongly. Fix the documentation, the two places that need to hold the reorder lock across accesses to the structure, and the debugfs code that should just use RCU. Also, remove acquiring the sta->lock across reorder timeouts since it isn't necessary, and change a few places to GFP_KERNEL because the code path here doesn't need atomic allocations as I noticed when reviewing all this. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Acked-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d2fcd22ab06d..fdeabb19943c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -538,6 +538,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
{
struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
+ lockdep_assert_held(&tid_agg_rx->reorder_lock);
+
if (!skb)
goto no_frame;
@@ -557,6 +559,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
{
int index;
+ lockdep_assert_held(&tid_agg_rx->reorder_lock);
+
while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
@@ -581,6 +585,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
{
int index, j;
+ lockdep_assert_held(&tid_agg_rx->reorder_lock);
+
/* release the buffer until next missing frame */
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
@@ -683,10 +689,11 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
int index;
bool ret = true;
+ spin_lock(&tid_agg_rx->reorder_lock);
+
buf_size = tid_agg_rx->buf_size;
head_seq_num = tid_agg_rx->head_seq_num;
- spin_lock(&tid_agg_rx->reorder_lock);
/* frame with out of date sequence number */
if (seq_less(mpdu_seq_num, head_seq_num)) {
dev_kfree_skb(skb);
@@ -1921,9 +1928,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
mod_timer(&tid_agg_rx->session_timer,
TU_TO_EXP_TIME(tid_agg_rx->timeout));
+ spin_lock(&tid_agg_rx->reorder_lock);
/* release stored frames up to start of BAR */
ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
frames);
+ spin_unlock(&tid_agg_rx->reorder_lock);
+
kfree_skb(skb);
return RX_QUEUED;
}
@@ -2515,9 +2525,8 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
}
/*
- * This function makes calls into the RX path. Therefore the
- * caller must hold the sta_info->lock and everything has to
- * be under rcu_read_lock protection as well.
+ * This function makes calls into the RX path, therefore
+ * it has to be invoked under RCU read lock.
*/
void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
{