| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- From: Franky Lin <[email protected]>
- Date: Thu, 20 Aug 2015 22:06:06 +0200
- Subject: [PATCH] brcmfmac: block the correct flowring when backup queue
- overflow
- brcmf_flowring_block blocks the last active flowring under the same
- interface instead of the one provided by caller. This could lead to a
- dead lock of netif stop if there are more than one flowring under the
- interface and the traffic is high enough so brcmf_flowring_enqueue can
- not unblock the ring right away.
- Reviewed-by: Pieter-Paul Giesberts <[email protected]>
- Reviewed-by: Hante Meuleman <[email protected]>
- Signed-off-by: Franky Lin <[email protected]>
- Signed-off-by: Arend van Spriel <[email protected]>
- Signed-off-by: Kalle Valo <[email protected]>
- ---
- --- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
- +++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
- @@ -194,11 +194,15 @@ static void brcmf_flowring_block(struct
- spin_lock_irqsave(&flow->block_lock, flags);
-
- ring = flow->rings[flowid];
- + if (ring->blocked == blocked) {
- + spin_unlock_irqrestore(&flow->block_lock, flags);
- + return;
- + }
- ifidx = brcmf_flowring_ifidx_get(flow, flowid);
-
- currently_blocked = false;
- for (i = 0; i < flow->nrofrings; i++) {
- - if (flow->rings[i]) {
- + if ((flow->rings[i]) && (i != flowid)) {
- ring = flow->rings[i];
- if ((ring->status == RING_OPEN) &&
- (brcmf_flowring_ifidx_get(flow, i) == ifidx)) {
- @@ -209,8 +213,8 @@ static void brcmf_flowring_block(struct
- }
- }
- }
- - ring->blocked = blocked;
- - if (currently_blocked == blocked) {
- + flow->rings[flowid]->blocked = blocked;
- + if (currently_blocked) {
- spin_unlock_irqrestore(&flow->block_lock, flags);
- return;
- }
|