tipc: purge backlog queue counters when broadcast link is reset
authorJon Paul Maloy <jon.maloy@ericsson.com>
Sun, 28 Jun 2015 13:44:44 +0000 (09:44 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 28 Jun 2015 23:43:02 +0000 (16:43 -0700)
In commit 1f66d161ab3d8b518903fa6c3f9c1f48d6919e74
("tipc: introduce starvation free send algorithm")
we introduced a counter per priority level for buffers
in the link backlog queue. We also introduced a new
function tipc_link_purge_backlog(), to reset these
counters to zero when the link is reset.

Unfortunately, we missed to call this function when
the broadcast link is reset, with the result that the
values of these counters might be permanently skewed
when new nodes are attached. This may in the worst case
lead to permananent, but spurious, broadcast link
congestion, where no broadcast packets can be sent at
all.

We fix this bug with this commit.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/tipc/bcast.c
net/tipc/link.c
net/tipc/link.h

index 4906ca3c0f3a576a529eacb26631f8585291ae40..a816382fc8af1b9efb016f888493ca4dcc65fe3b 100644 (file)
@@ -108,6 +108,11 @@ void tipc_bclink_remove_node(struct net *net, u32 addr)
 
        tipc_bclink_lock(net);
        tipc_nmap_remove(&tn->bclink->bcast_nodes, addr);
+
+       /* Last node? => reset backlog queue */
+       if (!tn->bclink->bcast_nodes.count)
+               tipc_link_purge_backlog(&tn->bclink->link);
+
        tipc_bclink_unlock(net);
 }
 
index ca8b8e0f49b526ebbf7a87e2cc89491ecfedf988..eaa9fe54b4aebfb531610611637915dc1b0c7256 100644 (file)
@@ -404,7 +404,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
        l_ptr->reasm_buf = NULL;
 }
 
-static void tipc_link_purge_backlog(struct tipc_link *l)
+void tipc_link_purge_backlog(struct tipc_link *l)
 {
        __skb_queue_purge(&l->backlogq);
        l->backlog[TIPC_LOW_IMPORTANCE].len = 0;
index 0c02c973e98558c699f006cce06b81768891b08b..ae0a0ea572f2961aca2617f9244ea74ebba15c6a 100644 (file)
@@ -218,6 +218,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr);
 int tipc_link_is_up(struct tipc_link *l_ptr);
 int tipc_link_is_active(struct tipc_link *l_ptr);
 void tipc_link_purge_queues(struct tipc_link *l_ptr);
+void tipc_link_purge_backlog(struct tipc_link *l);
 void tipc_link_reset_all(struct tipc_node *node);
 void tipc_link_reset(struct tipc_link *l_ptr);
 int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,