aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-04-16 17:00:53 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-25 22:29:05 -0700
commit6313c1e0992feaee56bc09b85042b3186041fa3c (patch)
treef75cda674d8f2b62bcdb09e59f8bc7010003a91f
parent[RTNETLINK]: Hold rtnl_mutex during netlink dump callbacks (diff)
downloadlinux-dev-6313c1e0992feaee56bc09b85042b3186041fa3c.tar.xz
linux-dev-6313c1e0992feaee56bc09b85042b3186041fa3c.zip
[RTNETLINK]: Remove unnecessary locking in dump callbacks
Since we're now holding the rtnl during the entire dump operation, we can remove additional locking for rtnl protected data. This patch does that for all simple cases (dev_base_lock for dev_base walking, RCU protection for FIB rule dumping). Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/bridge/br_netlink.c2
-rw-r--r--net/core/fib_rules.c4
-rw-r--r--net/core/rtnetlink.c2
-rw-r--r--net/decnet/dn_dev.c3
-rw-r--r--net/ipv4/devinet.c12
-rw-r--r--net/ipv6/addrconf.c2
6 files changed, 3 insertions, 22 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 5e84ade129ca..35facc0c11c2 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -109,7 +109,6 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
struct net_device *dev;
int idx;
- read_lock(&dev_base_lock);
for (dev = dev_base, idx = 0; dev; dev = dev->next) {
/* not a bridge port */
if (dev->br_port == NULL || idx < cb->args[0])
@@ -122,7 +121,6 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
skip:
++idx;
}
- read_unlock(&dev_base_lock);
cb->args[0] = idx;
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index cb2dae19531b..8c5474e16683 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -495,8 +495,7 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
int idx = 0;
struct fib_rule *rule;
- rcu_read_lock();
- list_for_each_entry_rcu(rule, ops->rules_list, list) {
+ list_for_each_entry(rule, ops->rules_list, list) {
if (idx < cb->args[1])
goto skip;
@@ -507,7 +506,6 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
skip:
idx++;
}
- rcu_read_unlock();
cb->args[1] = idx;
rules_ops_put(ops);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 62f5c7f98d17..bc95fab0b0ce 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -543,7 +543,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
int s_idx = cb->args[0];
struct net_device *dev;
- read_lock(&dev_base_lock);
for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
if (idx < s_idx)
continue;
@@ -552,7 +551,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
break;
}
- read_unlock(&dev_base_lock);
cb->args[0] = idx;
return skb->len;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 61be2caddc57..5c2a9951b638 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -799,7 +799,6 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
skip_ndevs = cb->args[0];
skip_naddr = cb->args[1];
- read_lock(&dev_base_lock);
for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
if (idx < skip_ndevs)
continue;
@@ -824,8 +823,6 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
}
}
done:
- read_unlock(&dev_base_lock);
-
cb->args[0] = idx;
cb->args[1] = dn_idx;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 9bdc79564cc6..088888db8b3d 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1182,17 +1182,13 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
int s_ip_idx, s_idx = cb->args[0];
s_ip_idx = ip_idx = cb->args[1];
- read_lock(&dev_base_lock);
for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
if (idx < s_idx)
continue;
if (idx > s_idx)
s_ip_idx = 0;
- rcu_read_lock();
- if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
- rcu_read_unlock();
+ if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
continue;
- }
for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
ifa = ifa->ifa_next, ip_idx++) {
@@ -1200,16 +1196,12 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
continue;
if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
- RTM_NEWADDR, NLM_F_MULTI) <= 0) {
- rcu_read_unlock();
+ RTM_NEWADDR, NLM_F_MULTI) <= 0)
goto done;
- }
}
- rcu_read_unlock();
}
done:
- read_unlock(&dev_base_lock);
cb->args[0] = idx;
cb->args[1] = ip_idx;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index eecba1886b49..1486f76f7878 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3224,7 +3224,6 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
s_idx = cb->args[0];
s_ip_idx = ip_idx = cb->args[1];
- read_lock(&dev_base_lock);
for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
if (idx < s_idx)
@@ -3286,7 +3285,6 @@ done:
read_unlock_bh(&idev->lock);
in6_dev_put(idev);
}
- read_unlock(&dev_base_lock);
cb->args[0] = idx;
cb->args[1] = ip_idx;
return skb->len;