aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-04-16 20:00:53 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:29:05 -0400
commit6313c1e0992feaee56bc09b85042b3186041fa3c (patch)
treef75cda674d8f2b62bcdb09e59f8bc7010003a91f
parent1c2d670f3660e9103fdcdca702f6dbf8ea7d6afb (diff)
[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 5e84ade129c..35facc0c11c 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)
109 struct net_device *dev; 109 struct net_device *dev;
110 int idx; 110 int idx;
111 111
112 read_lock(&dev_base_lock);
113 for (dev = dev_base, idx = 0; dev; dev = dev->next) { 112 for (dev = dev_base, idx = 0; dev; dev = dev->next) {
114 /* not a bridge port */ 113 /* not a bridge port */
115 if (dev->br_port == NULL || idx < cb->args[0]) 114 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)
122skip: 121skip:
123 ++idx; 122 ++idx;
124 } 123 }
125 read_unlock(&dev_base_lock);
126 124
127 cb->args[0] = idx; 125 cb->args[0] = idx;
128 126
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index cb2dae19531..8c5474e1668 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,
495 int idx = 0; 495 int idx = 0;
496 struct fib_rule *rule; 496 struct fib_rule *rule;
497 497
498 rcu_read_lock(); 498 list_for_each_entry(rule, ops->rules_list, list) {
499 list_for_each_entry_rcu(rule, ops->rules_list, list) {
500 if (idx < cb->args[1]) 499 if (idx < cb->args[1])
501 goto skip; 500 goto skip;
502 501
@@ -507,7 +506,6 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
507skip: 506skip:
508 idx++; 507 idx++;
509 } 508 }
510 rcu_read_unlock();
511 cb->args[1] = idx; 509 cb->args[1] = idx;
512 rules_ops_put(ops); 510 rules_ops_put(ops);
513 511
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 62f5c7f98d1..bc95fab0b0c 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)
543 int s_idx = cb->args[0]; 543 int s_idx = cb->args[0];
544 struct net_device *dev; 544 struct net_device *dev;
545 545
546 read_lock(&dev_base_lock);
547 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { 546 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
548 if (idx < s_idx) 547 if (idx < s_idx)
549 continue; 548 continue;
@@ -552,7 +551,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
552 cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) 551 cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
553 break; 552 break;
554 } 553 }
555 read_unlock(&dev_base_lock);
556 cb->args[0] = idx; 554 cb->args[0] = idx;
557 555
558 return skb->len; 556 return skb->len;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 61be2caddc5..5c2a9951b63 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)
799 skip_ndevs = cb->args[0]; 799 skip_ndevs = cb->args[0];
800 skip_naddr = cb->args[1]; 800 skip_naddr = cb->args[1];
801 801
802 read_lock(&dev_base_lock);
803 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { 802 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
804 if (idx < skip_ndevs) 803 if (idx < skip_ndevs)
805 continue; 804 continue;
@@ -824,8 +823,6 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
824 } 823 }
825 } 824 }
826done: 825done:
827 read_unlock(&dev_base_lock);
828
829 cb->args[0] = idx; 826 cb->args[0] = idx;
830 cb->args[1] = dn_idx; 827 cb->args[1] = dn_idx;
831 828
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 9bdc79564cc..088888db8b3 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)
1182 int s_ip_idx, s_idx = cb->args[0]; 1182 int s_ip_idx, s_idx = cb->args[0];
1183 1183
1184 s_ip_idx = ip_idx = cb->args[1]; 1184 s_ip_idx = ip_idx = cb->args[1];
1185 read_lock(&dev_base_lock);
1186 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { 1185 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
1187 if (idx < s_idx) 1186 if (idx < s_idx)
1188 continue; 1187 continue;
1189 if (idx > s_idx) 1188 if (idx > s_idx)
1190 s_ip_idx = 0; 1189 s_ip_idx = 0;
1191 rcu_read_lock(); 1190 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
1192 if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
1193 rcu_read_unlock();
1194 continue; 1191 continue;
1195 }
1196 1192
1197 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; 1193 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1198 ifa = ifa->ifa_next, ip_idx++) { 1194 ifa = ifa->ifa_next, ip_idx++) {
@@ -1200,16 +1196,12 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1200 continue; 1196 continue;
1201 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, 1197 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
1202 cb->nlh->nlmsg_seq, 1198 cb->nlh->nlmsg_seq,
1203 RTM_NEWADDR, NLM_F_MULTI) <= 0) { 1199 RTM_NEWADDR, NLM_F_MULTI) <= 0)
1204 rcu_read_unlock();
1205 goto done; 1200 goto done;
1206 }
1207 } 1201 }
1208 rcu_read_unlock();
1209 } 1202 }
1210 1203
1211done: 1204done:
1212 read_unlock(&dev_base_lock);
1213 cb->args[0] = idx; 1205 cb->args[0] = idx;
1214 cb->args[1] = ip_idx; 1206 cb->args[1] = ip_idx;
1215 1207
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index eecba1886b4..1486f76f787 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,
3224 3224
3225 s_idx = cb->args[0]; 3225 s_idx = cb->args[0];
3226 s_ip_idx = ip_idx = cb->args[1]; 3226 s_ip_idx = ip_idx = cb->args[1];
3227 read_lock(&dev_base_lock);
3228 3227
3229 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { 3228 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
3230 if (idx < s_idx) 3229 if (idx < s_idx)
@@ -3286,7 +3285,6 @@ done:
3286 read_unlock_bh(&idev->lock); 3285 read_unlock_bh(&idev->lock);
3287 in6_dev_put(idev); 3286 in6_dev_put(idev);
3288 } 3287 }
3289 read_unlock(&dev_base_lock);
3290 cb->args[0] = idx; 3288 cb->args[0] = idx;
3291 cb->args[1] = ip_idx; 3289 cb->args[1] = ip_idx;
3292 return skb->len; 3290 return skb->len;