316-brcmfmac-block-the-correct-flowring-when-backup-queu.patch 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. From: Franky Lin <[email protected]>
  2. Date: Thu, 20 Aug 2015 22:06:06 +0200
  3. Subject: [PATCH] brcmfmac: block the correct flowring when backup queue
  4. overflow
  5. brcmf_flowring_block blocks the last active flowring under the same
  6. interface instead of the one provided by caller. This could lead to a
  7. dead lock of netif stop if there are more than one flowring under the
  8. interface and the traffic is high enough so brcmf_flowring_enqueue can
  9. not unblock the ring right away.
  10. Reviewed-by: Pieter-Paul Giesberts <[email protected]>
  11. Reviewed-by: Hante Meuleman <[email protected]>
  12. Signed-off-by: Franky Lin <[email protected]>
  13. Signed-off-by: Arend van Spriel <[email protected]>
  14. Signed-off-by: Kalle Valo <[email protected]>
  15. ---
  16. --- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
  17. +++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
  18. @@ -194,11 +194,15 @@ static void brcmf_flowring_block(struct
  19. spin_lock_irqsave(&flow->block_lock, flags);
  20. ring = flow->rings[flowid];
  21. + if (ring->blocked == blocked) {
  22. + spin_unlock_irqrestore(&flow->block_lock, flags);
  23. + return;
  24. + }
  25. ifidx = brcmf_flowring_ifidx_get(flow, flowid);
  26. currently_blocked = false;
  27. for (i = 0; i < flow->nrofrings; i++) {
  28. - if (flow->rings[i]) {
  29. + if ((flow->rings[i]) && (i != flowid)) {
  30. ring = flow->rings[i];
  31. if ((ring->status == RING_OPEN) &&
  32. (brcmf_flowring_ifidx_get(flow, i) == ifidx)) {
  33. @@ -209,8 +213,8 @@ static void brcmf_flowring_block(struct
  34. }
  35. }
  36. }
  37. - ring->blocked = blocked;
  38. - if (currently_blocked == blocked) {
  39. + flow->rings[flowid]->blocked = blocked;
  40. + if (currently_blocked) {
  41. spin_unlock_irqrestore(&flow->block_lock, flags);
  42. return;
  43. }