Skip to content

Commit

Permalink
tipc: Add missing locks in broadcast link statistics accumulation
Browse files Browse the repository at this point in the history
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 <allan.stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
  • Loading branch information
Allan Stephens authored and Paul Gortmaker committed Feb 6, 2012
1 parent 0232c5a commit b98158e
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions net/tipc/bcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,14 +520,17 @@ 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);
if (unlikely(bclink_ack_allowed(seqno))) {
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);
Expand All @@ -536,19 +539,23 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
} 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) {
bcl->stats.recv_fragments++;
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);
}
Expand Down Expand Up @@ -601,11 +608,15 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
} 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:
Expand Down

0 comments on commit b98158e

Please sign in to comment.