summaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2011-10-26 16:13:35 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-02-06 16:59:18 -0500
commitb98158e3b36645305363a598d91c544fa31446f1 (patch)
tree0bef1102cf7010554b0937caef31c2fb35678bca /net/tipc
parent0232c5a566ff52d5c9fc1dda70253c942628ca66 (diff)
downloadlinux-b98158e3b36645305363a598d91c544fa31446f1.tar.gz
linux-b98158e3b36645305363a598d91c544fa31446f1.tar.bz2
linux-b98158e3b36645305363a598d91c544fa31446f1.zip
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 <allan.stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c11
1 files changed, 11 insertions, 0 deletions
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: