Skip to content

Commit

Permalink
[RTNETLINK]: Remove unnecessary locking in dump callbacks
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
kaber authored and David S. Miller committed Apr 26, 2007
1 parent 1c2d670 commit 6313c1e
Show file tree
Hide file tree
Showing 6 changed files with 3 additions and 22 deletions.
2 changes: 0 additions & 2 deletions net/bridge/br_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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;

Expand Down
4 changes: 1 addition & 3 deletions net/core/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);

Expand Down
2 changes: 0 additions & 2 deletions net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions net/decnet/dn_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down
12 changes: 2 additions & 10 deletions net/ipv4/devinet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1182,34 +1182,26 @@ 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++) {
if (ip_idx < s_ip_idx)
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;

Expand Down
2 changes: 0 additions & 2 deletions net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -3286,7 +3285,6 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
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;
Expand Down

0 comments on commit 6313c1e

Please sign in to comment.