From 9bf9055eb716f85372c41b3fbc51f90bc7653740 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:14:09 -0700 Subject: decnet: Fix set-but-unused variable. "next" in dn_rebuild_zone() is set but not actually used, kill it off. Signed-off-by: David S. Miller --- net/decnet/dn_table.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net/decnet') diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 99d8d3a40998..d8ea583076cf 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -124,11 +124,10 @@ static inline void dn_rebuild_zone(struct dn_zone *dz, int old_divisor) { int i; - struct dn_fib_node *f, **fp, *next; + struct dn_fib_node *f, **fp; for(i = 0; i < old_divisor; i++) { for(f = old_ht[i]; f; f = f->fn_next) { - next = f->fn_next; for(fp = dn_chain_p(f->fn_key, dz); *fp && dn_key_leq((*fp)->fn_key, f->fn_key); fp = &(*fp)->fn_next) -- cgit v1.2.3 From a01c1335a308ee660518e33db03fb5f5e1dfc166 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 20:47:07 -0700 Subject: decnet: Don't leak entries when rebuilding zone. As noticed by Ben Hutchings, when we move entries from one table to another we leak all except the first entry. Put back the "next" variable removed by commit 9bf9055eb716f85372c41b3fbc51f90bc7653740 ("decnet: Fix set-but-unused variable.") and use it properly. Reported-by: Ben Hutchings Signed-off-by: David S. Miller --- net/decnet/dn_table.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'net/decnet') diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index d8ea583076cf..bd0a52dd1d40 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -123,11 +123,12 @@ static inline void dn_rebuild_zone(struct dn_zone *dz, struct dn_fib_node **old_ht, int old_divisor) { + struct dn_fib_node *f, **fp, *next; int i; - struct dn_fib_node *f, **fp; for(i = 0; i < old_divisor; i++) { - for(f = old_ht[i]; f; f = f->fn_next) { + for(f = old_ht[i]; f; f = next) { + next = f->fn_next; for(fp = dn_chain_p(f->fn_key, dz); *fp && dn_key_leq((*fp)->fn_key, f->fn_key); fp = &(*fp)->fn_next) -- cgit v1.2.3 From 5c1e6aa300a7a669dc469d2dcb20172c6bd8fed9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Apr 2011 14:13:38 -0700 Subject: net: Make dst_alloc() take more explicit initializations. Now the dst->dev, dev->obsolete, and dst->flags values can be specified as well. Signed-off-by: David S. Miller --- net/decnet/dn_route.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'net/decnet') diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 9f09d4fc2880..f489b081c25d 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1125,13 +1125,10 @@ make_route: if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; - rt = dst_alloc(&dn_dst_ops, 0); + rt = dst_alloc(&dn_dst_ops, dev_out, 1, 0, DST_HOST); if (rt == NULL) goto e_nobufs; - atomic_set(&rt->dst.__refcnt, 1); - rt->dst.flags = DST_HOST; - rt->fld.saddr = oldflp->saddr; rt->fld.daddr = oldflp->daddr; rt->fld.flowidn_oif = oldflp->flowidn_oif; @@ -1146,8 +1143,6 @@ make_route: rt->rt_dst_map = fld.daddr; rt->rt_src_map = fld.saddr; - rt->dst.dev = dev_out; - dev_hold(dev_out); rt->dst.neighbour = neigh; neigh = NULL; @@ -1399,7 +1394,7 @@ static int dn_route_input_slow(struct sk_buff *skb) } make_route: - rt = dst_alloc(&dn_dst_ops, 0); + rt = dst_alloc(&dn_dst_ops, out_dev, 0, 0, DST_HOST); if (rt == NULL) goto e_nobufs; @@ -1419,9 +1414,7 @@ make_route: rt->fld.flowidn_iif = in_dev->ifindex; rt->fld.flowidn_mark = fld.flowidn_mark; - rt->dst.flags = DST_HOST; rt->dst.neighbour = neigh; - rt->dst.dev = out_dev; rt->dst.lastuse = jiffies; rt->dst.output = dn_rt_bug; switch(res.type) { @@ -1440,8 +1433,6 @@ make_route: rt->dst.input = dst_discard; } rt->rt_flags = flags; - if (rt->dst.dev) - dev_hold(rt->dst.dev); err = dn_rt_set_next_hop(rt, &res); if (err) -- cgit v1.2.3 From cf91166223772ef4a2ed98b9874958bf6a2470df Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Apr 2011 14:31:47 -0700 Subject: net: Use non-zero allocations in dst_alloc(). Make dst_alloc() and it's users explicitly initialize the entire entry. The zero'ing done by kmem_cache_zalloc() was almost entirely redundant. Signed-off-by: David S. Miller --- net/decnet/dn_route.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net/decnet') diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index f489b081c25d..74544bc6fdec 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1129,6 +1129,7 @@ make_route: if (rt == NULL) goto e_nobufs; + memset(&rt->fld, 0, sizeof(rt->fld)); rt->fld.saddr = oldflp->saddr; rt->fld.daddr = oldflp->daddr; rt->fld.flowidn_oif = oldflp->flowidn_oif; @@ -1398,6 +1399,7 @@ make_route: if (rt == NULL) goto e_nobufs; + memset(&rt->fld, 0, sizeof(rt->fld)); rt->rt_saddr = fld.saddr; rt->rt_daddr = fld.daddr; rt->rt_gateway = fld.daddr; -- cgit v1.2.3 From e67f88dd12f610da98ca838822f2c9b4e7c6100e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 27 Apr 2011 22:56:07 +0000 Subject: net: dont hold rtnl mutex during netlink dump callbacks Four years ago, Patrick made a change to hold rtnl mutex during netlink dump callbacks. I believe it was a wrong move. This slows down concurrent dumps, making good old /proc/net/ files faster than rtnetlink in some situations. This occurred to me because one "ip link show dev ..." was _very_ slow on a workload adding/removing network devices in background. All dump callbacks are able to use RCU locking now, so this patch does roughly a revert of commits : 1c2d670f366 : [RTNETLINK]: Hold rtnl_mutex during netlink dump callbacks 6313c1e0992 : [RTNETLINK]: Remove unnecessary locking in dump callbacks This let writers fight for rtnl mutex and readers going full speed. It also takes care of phonet : phonet_route_get() is now called from rcu read section. I renamed it to phonet_route_get_rcu() Signed-off-by: Eric Dumazet Cc: Patrick McHardy Cc: Remi Denis-Courmont Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/decnet/dn_dev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'net/decnet') diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 0dcaa903e00e..404fa1591027 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -752,7 +752,8 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) skip_naddr = cb->args[1]; idx = 0; - for_each_netdev(&init_net, dev) { + rcu_read_lock(); + for_each_netdev_rcu(&init_net, dev) { if (idx < skip_ndevs) goto cont; else if (idx > skip_ndevs) { @@ -761,11 +762,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) skip_naddr = 0; } - if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) + if ((dn_db = rcu_dereference(dev->dn_ptr)) == NULL) goto cont; - for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa; - ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) { + for (ifa = rcu_dereference(dn_db->ifa_list), dn_idx = 0; ifa; + ifa = rcu_dereference(ifa->ifa_next), dn_idx++) { if (dn_idx < skip_naddr) continue; @@ -778,6 +779,7 @@ cont: idx++; } done: + rcu_read_unlock(); cb->args[0] = idx; cb->args[1] = dn_idx; -- cgit v1.2.3