wl12xx: avoid starving the system hlid
authorArik Nemtsov <arik@wizery.com>
Mon, 27 Feb 2012 22:41:31 +0000 (00:41 +0200)
committerLuciano Coelho <coelho@ti.com>
Tue, 28 Feb 2012 11:25:09 +0000 (13:25 +0200)
Re-factor the Tx scheduler so that the system_hlid is taken into account
before restarting an iteration over the wlvifs. Previously this
hlid had a lower priority and would starve if some wlvif had many
packets.
In addition avoid iterating over wlvifs past last_wlvif when performing
the a second pass. If we had packets in those wlvifs they would have
been found earlier.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/wl12xx/tx.c

index 8f5ab04..6640c39 100644 (file)
@@ -572,6 +572,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
        struct wl12xx_vif *wlvif = wl->last_wlvif;
        struct sk_buff *skb = NULL;
 
+       /* continue from last wlvif (round robin) */
        if (wlvif) {
                wl12xx_for_each_wlvif_continue(wl, wlvif) {
                        skb = wl12xx_vif_skb_dequeue(wl, wlvif);
@@ -582,7 +583,11 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                }
        }
 
-       /* do another pass */
+       /* dequeue from the system HLID before the restarting wlvif list */
+       if (!skb)
+               skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
+
+       /* do a new pass over the wlvif list */
        if (!skb) {
                wl12xx_for_each_wlvif(wl, wlvif) {
                        skb = wl12xx_vif_skb_dequeue(wl, wlvif);
@@ -590,12 +595,16 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                                wl->last_wlvif = wlvif;
                                break;
                        }
+
+                       /*
+                        * No need to continue after last_wlvif. The previous
+                        * pass should have found it.
+                        */
+                       if (wlvif == wl->last_wlvif)
+                               break;
                }
        }
 
-       if (!skb)
-               skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
-
        if (!skb &&
            test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
                int q;