From: Allan Stephens Date: Wed, 26 Oct 2011 20:13:35 +0000 (-0400) Subject: tipc: Add missing locks in broadcast link statistics accumulation X-Git-Tag: firefly_0821_release~3680^2~3338^2~364^2~6 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b98158e3b36645305363a598d91c544fa31446f1;p=firefly-linux-kernel-4.4.55.git tipc: Add missing locks in broadcast link statistics accumulation Ensures that all attempts to update broadcast link statistics are done only while holding the lock that protects the link's main data structures, to prevent interference by simultaneous updates caused by messages arriving on other interfaces. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 035b350be5c6..facc216c6a92 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -520,6 +520,7 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf) if (likely(seqno == next_in)) { receive: + spin_lock_bh(&bc_lock); bcl->stats.recv_info++; node->bclink.last_in++; bclink_set_gap(node); @@ -527,7 +528,9 @@ receive: bclink_send_ack(node); bcl->stats.sent_acks++; } + if (likely(msg_isdata(msg))) { + spin_unlock_bh(&bc_lock); tipc_node_unlock(node); if (likely(msg_mcast(msg))) tipc_port_recv_mcast(buf, NULL); @@ -536,6 +539,7 @@ receive: } else if (msg_user(msg) == MSG_BUNDLER) { bcl->stats.recv_bundles++; bcl->stats.recv_bundled += msg_msgcnt(msg); + spin_unlock_bh(&bc_lock); tipc_node_unlock(node); tipc_link_recv_bundle(buf); } else if (msg_user(msg) == MSG_FRAGMENTER) { @@ -543,12 +547,15 @@ receive: if (tipc_link_recv_fragment(&node->bclink.defragm, &buf, &msg)) bcl->stats.recv_fragmented++; + spin_unlock_bh(&bc_lock); tipc_node_unlock(node); tipc_net_route_msg(buf); } else if (msg_user(msg) == NAME_DISTRIBUTOR) { + spin_unlock_bh(&bc_lock); tipc_node_unlock(node); tipc_named_recv(buf); } else { + spin_unlock_bh(&bc_lock); tipc_node_unlock(node); buf_discard(buf); } @@ -601,11 +608,15 @@ receive: } else deferred = 0; + spin_lock_bh(&bc_lock); + if (deferred) bcl->stats.deferred_recv++; else bcl->stats.duplicates++; + spin_unlock_bh(&bc_lock); + unlock: tipc_node_unlock(node); exit: