mac80211: Stop forwarding mesh traffic when tx queues are full
authorJavier Cardona <javier@cozybit.com>
Tue, 6 Sep 2011 20:05:21 +0000 (13:05 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 14 Sep 2011 17:56:17 +0000 (13:56 -0400)
Tx flow control for non-mesh modes of operation only needs to act on the
net device queues: when the hardware queues are full we stop accepting
traffic from the net device.  In mesh, however, we also need to stop
forwarding traffic.  This patch checks the hardware queues before
attempting to forward a mesh frame.

Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/debugfs_netdev.c
net/mac80211/ieee80211_i.h
net/mac80211/rx.c

index 6e8eab7919e2e2a95db3ee761419b066d5c7655a..dd046291751852118783b087f81b6dee6a8da253 100644 (file)
@@ -340,6 +340,8 @@ IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
 IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
 IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
 IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
+IEEE80211_IF_FILE(dropped_frames_congestion,
+               u.mesh.mshstats.dropped_frames_congestion, DEC);
 IEEE80211_IF_FILE(dropped_frames_no_route,
                u.mesh.mshstats.dropped_frames_no_route, DEC);
 IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
@@ -463,6 +465,7 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
        MESHSTATS_ADD(fwded_frames);
        MESHSTATS_ADD(dropped_frames_ttl);
        MESHSTATS_ADD(dropped_frames_no_route);
+       MESHSTATS_ADD(dropped_frames_congestion);
        MESHSTATS_ADD(estab_plinks);
 #undef MESHSTATS_ADD
 }
index a37da74de0232241a44fe9fb90d42b8b3f4a91cf..5e636bc3551fd11b31424030473009cef1db67dd 100644 (file)
@@ -261,6 +261,7 @@ struct mesh_stats {
        __u32 fwded_frames;             /* Mesh total forwarded frames */
        __u32 dropped_frames_ttl;       /* Not transmitted since mesh_ttl == 0*/
        __u32 dropped_frames_no_route;  /* Not transmitted, no route found */
+       __u32 dropped_frames_congestion;/* Not forwarded due to congestion */
        atomic_t estab_plinks;
 };
 
index d479d48e8d188cbbf421c2c554aed8af415a89b9..811e3ade8c743afeb7712809f0463480d8e74e4c 100644 (file)
@@ -1844,6 +1844,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                /* illegal frame */
                return RX_DROP_MONITOR;
 
+       if (ieee80211_queue_stopped(&local->hw, skb_get_queue_mapping(skb))) {
+               IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+                                               dropped_frames_congestion);
+               return RX_DROP_MONITOR;
+       }
+
        if (mesh_hdr->flags & MESH_FLAGS_AE) {
                struct mesh_path *mppath;
                char *proxied_addr;