Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 314743
b: refs/heads/master
c: 0faf745
h: refs/heads/master
i:
  314741: 7189b94
  314739: 071f1d4
  314735: 1c46a4d
v: v3
  • Loading branch information
Vasanthakumar Thiagarajan authored and Kalle Valo committed Jun 11, 2012
1 parent 8c3203d commit bbc06c7
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d154f32ebe3ffe9dea6ed0a91767883b1e7a6bc0
refs/heads/master: 0faf745872f6d00afb318185e8fb181587974b5a
12 changes: 9 additions & 3 deletions trunk/drivers/net/wireless/ath/ath6kl/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,15 @@ struct rxtid {
struct sk_buff_head q;

/*
* FIXME: No clue what this should protect. Apparently it should
* protect some of the fields above but they are also accessed
* without taking the lock.
* lock mainly protects seq_next and hold_q. Movement of seq_next
* needs to be protected between aggr_timeout() and
* aggr_process_recv_frm(). hold_q will be holding the pending
* reorder frames and it's access should also be protected.
* Some of the other fields like hold_q_sz, win_sz and aggr are
* initialized/reset when receiving addba/delba req, also while
* deleting aggr state all the pending buffers are flushed before
* resetting these fields, so there should not be any race in accessing
* these fields.
*/
spinlock_t lock;
};
Expand Down
12 changes: 9 additions & 3 deletions trunk/drivers/net/wireless/ath/ath6kl/txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,7 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
rxtid = &agg_conn->rx_tid[tid];
stats = &agg_conn->stat[tid];

spin_lock_bh(&rxtid->lock);
idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);

/*
Expand All @@ -1054,8 +1055,6 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
seq_end = seq_no ? seq_no : rxtid->seq_next;
idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);

spin_lock_bh(&rxtid->lock);

do {
node = &rxtid->hold_q[idx];
if ((order == 1) && (!node->skb))
Expand Down Expand Up @@ -1127,11 +1126,13 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
((end > extended_end) && (cur > extended_end) &&
(cur < end))) {
aggr_deque_frms(agg_conn, tid, 0, 0);
spin_lock_bh(&rxtid->lock);
if (cur >= rxtid->hold_q_sz - 1)
rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
else
rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
(rxtid->hold_q_sz - 2 - cur);
spin_unlock_bh(&rxtid->lock);
} else {
/*
* Dequeue only those frames that are outside the
Expand Down Expand Up @@ -1186,7 +1187,8 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,

if (agg_conn->timer_scheduled)
rxtid->progress = true;
else
else {
spin_lock_bh(&rxtid->lock);
for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
if (rxtid->hold_q[idx].skb) {
/*
Expand All @@ -1204,6 +1206,8 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
break;
}
}
spin_unlock_bh(&rxtid->lock);
}

return is_queued;
}
Expand Down Expand Up @@ -1626,6 +1630,7 @@ static void aggr_timeout(unsigned long arg)
rxtid = &aggr_conn->rx_tid[i];

if (rxtid->aggr && rxtid->hold_q) {
spin_lock_bh(&rxtid->lock);
for (j = 0; j < rxtid->hold_q_sz; j++) {
if (rxtid->hold_q[j].skb) {
aggr_conn->timer_scheduled = true;
Expand All @@ -1634,6 +1639,7 @@ static void aggr_timeout(unsigned long arg)
break;
}
}
spin_unlock_bh(&rxtid->lock);

if (j >= rxtid->hold_q_sz)
rxtid->timer_mon = false;
Expand Down

0 comments on commit bbc06c7

Please sign in to comment.