Skip to content

Commit 908344c

Browse files
Jon Maloydavem330
authored andcommitted
tipc: fix bug in multicast congestion handling
One aim of commit 50100a5 ("tipc: use pseudo message to wake up sockets after link congestion") was to handle link congestion abatement in a uniform way for both unicast and multicast transmit. However, the latter doesn't work correctly, and has been broken since the referenced commit was applied. If a user now sends a burst of multicast messages that is big enough to cause broadcast link congestion, it will be put to sleep, and not be waked up when the congestion abates as it should be. This has two reasons. First, the flag that is used, TIPC_WAKEUP_USERS, is set correctly, but in the wrong field. Instead of setting it in the 'action_flags' field of the arrival node struct, it is by mistake set in the dummy node struct that is owned by the broadcast link, where it will never tested for. Second, we cannot use the same flag for waking up unicast and multicast users, since the function tipc_node_unlock() needs to pick the wakeup pseudo messages to deliver from different queues. It must hence be able to distinguish between the two cases. This commit solves this problem by adding a new flag TIPC_WAKEUP_BCAST_USERS, and a new function tipc_bclink_wakeup_user(). The latter is to be called by tipc_node_unlock() when the named flag, now set in the correct field, is encountered. v2: using explicit 'unsigned int' declaration instead of 'uint', as per comment from David Miller. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0287587 commit 908344c

File tree

4 files changed

+21
-3
lines changed

4 files changed

+21
-3
lines changed

net/tipc/bcast.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,17 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
225225
tipc_link_retransmit(bcl, buf, mod(to - after));
226226
}
227227

228+
/**
229+
* tipc_bclink_wakeup_users - wake up pending users
230+
*
231+
* Called with no locks taken
232+
*/
233+
void tipc_bclink_wakeup_users(void)
234+
{
235+
while (skb_queue_len(&bclink->link.waiting_sks))
236+
tipc_sk_rcv(skb_dequeue(&bclink->link.waiting_sks));
237+
}
238+
228239
/**
229240
* tipc_bclink_acknowledge - handle acknowledgement of broadcast packets
230241
* @n_ptr: node that sent acknowledgement info
@@ -300,7 +311,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
300311
bclink_set_last_sent();
301312
}
302313
if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks)))
303-
bclink->node.action_flags |= TIPC_WAKEUP_USERS;
314+
n_ptr->action_flags |= TIPC_WAKEUP_BCAST_USERS;
315+
304316
exit:
305317
tipc_bclink_unlock();
306318
}

net/tipc/bcast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,5 @@ int tipc_bclink_set_queue_limits(u32 limit);
9999
void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
100100
uint tipc_bclink_get_mtu(void);
101101
int tipc_bclink_xmit(struct sk_buff *buf);
102-
102+
void tipc_bclink_wakeup_users(void);
103103
#endif

net/tipc/node.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ void tipc_node_unlock(struct tipc_node *node)
552552
LIST_HEAD(conn_sks);
553553
struct sk_buff_head waiting_sks;
554554
u32 addr = 0;
555+
unsigned int flags = node->action_flags;
555556

556557
if (likely(!node->action_flags)) {
557558
spin_unlock_bh(&node->lock);
@@ -572,6 +573,7 @@ void tipc_node_unlock(struct tipc_node *node)
572573
node->action_flags &= ~TIPC_NOTIFY_NODE_UP;
573574
addr = node->addr;
574575
}
576+
node->action_flags &= ~TIPC_WAKEUP_BCAST_USERS;
575577
spin_unlock_bh(&node->lock);
576578

577579
while (!skb_queue_empty(&waiting_sks))
@@ -583,6 +585,9 @@ void tipc_node_unlock(struct tipc_node *node)
583585
if (!list_empty(&nsub_list))
584586
tipc_nodesub_notify(&nsub_list);
585587

588+
if (flags & TIPC_WAKEUP_BCAST_USERS)
589+
tipc_bclink_wakeup_users();
590+
586591
if (addr)
587592
tipc_named_node_up(addr);
588593
}

net/tipc/node.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ enum {
5959
TIPC_WAIT_OWN_LINKS_DOWN = (1 << 2),
6060
TIPC_NOTIFY_NODE_DOWN = (1 << 3),
6161
TIPC_NOTIFY_NODE_UP = (1 << 4),
62-
TIPC_WAKEUP_USERS = (1 << 5)
62+
TIPC_WAKEUP_USERS = (1 << 5),
63+
TIPC_WAKEUP_BCAST_USERS = (1 << 6)
6364
};
6465

6566
/**

0 commit comments

Comments
 (0)