aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-02-16 17:08:44 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-17 18:44:00 -0500
commit3c7bd1a14071b99d6535b710bc998ae5d3abbb66 (patch)
tree05f31758aa4d6b49b70a4af4a8df4a83588610c2
parent0c4dcd58fd69aded93b0dc6917cd88b262c8aa3f (diff)
net: Add initial_ref arg to dst_alloc().
This allows avoiding multiple writes to the initial __refcnt. The most simplest cases of wanting an initial reference of "1" in ipv4 and ipv6 have been converted, the rest have been left along and kept at the existing "0". Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/dst.h2
-rw-r--r--net/core/dst.c4
-rw-r--r--net/decnet/dn_route.c4
-rw-r--r--net/ipv4/route.c7
-rw-r--r--net/ipv6/route.c5
-rw-r--r--net/xfrm/xfrm_policy.c2
6 files changed, 10 insertions, 14 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index e01855de21e..23b564d3e11 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -352,7 +352,7 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
352} 352}
353 353
354extern int dst_discard(struct sk_buff *skb); 354extern int dst_discard(struct sk_buff *skb);
355extern void * dst_alloc(struct dst_ops * ops); 355extern void *dst_alloc(struct dst_ops * ops, int initial_ref);
356extern void __dst_free(struct dst_entry * dst); 356extern void __dst_free(struct dst_entry * dst);
357extern struct dst_entry *dst_destroy(struct dst_entry * dst); 357extern struct dst_entry *dst_destroy(struct dst_entry * dst);
358 358
diff --git a/net/core/dst.c b/net/core/dst.c
index c1674fde827..91104d35de7 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -166,7 +166,7 @@ EXPORT_SYMBOL(dst_discard);
166 166
167const u32 dst_default_metrics[RTAX_MAX]; 167const u32 dst_default_metrics[RTAX_MAX];
168 168
169void *dst_alloc(struct dst_ops *ops) 169void *dst_alloc(struct dst_ops *ops, int initial_ref)
170{ 170{
171 struct dst_entry *dst; 171 struct dst_entry *dst;
172 172
@@ -177,7 +177,7 @@ void *dst_alloc(struct dst_ops *ops)
177 dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC); 177 dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC);
178 if (!dst) 178 if (!dst)
179 return NULL; 179 return NULL;
180 atomic_set(&dst->__refcnt, 0); 180 atomic_set(&dst->__refcnt, initial_ref);
181 dst->ops = ops; 181 dst->ops = ops;
182 dst->lastuse = jiffies; 182 dst->lastuse = jiffies;
183 dst->path = dst; 183 dst->path = dst;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 42c9c62d341..06c054d5ccb 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1122,7 +1122,7 @@ make_route:
1122 if (dev_out->flags & IFF_LOOPBACK) 1122 if (dev_out->flags & IFF_LOOPBACK)
1123 flags |= RTCF_LOCAL; 1123 flags |= RTCF_LOCAL;
1124 1124
1125 rt = dst_alloc(&dn_dst_ops); 1125 rt = dst_alloc(&dn_dst_ops, 0);
1126 if (rt == NULL) 1126 if (rt == NULL)
1127 goto e_nobufs; 1127 goto e_nobufs;
1128 1128
@@ -1383,7 +1383,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
1383 } 1383 }
1384 1384
1385make_route: 1385make_route:
1386 rt = dst_alloc(&dn_dst_ops); 1386 rt = dst_alloc(&dn_dst_ops, 0);
1387 if (rt == NULL) 1387 if (rt == NULL)
1388 goto e_nobufs; 1388 goto e_nobufs;
1389 1389
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 79a28718102..9841543c468 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1818,12 +1818,10 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
1818 1818
1819static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm) 1819static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm)
1820{ 1820{
1821 struct rtable *rt = dst_alloc(&ipv4_dst_ops); 1821 struct rtable *rt = dst_alloc(&ipv4_dst_ops, 1);
1822 if (rt) { 1822 if (rt) {
1823 rt->dst.obsolete = -1; 1823 rt->dst.obsolete = -1;
1824 1824
1825 atomic_set(&rt->dst.__refcnt, 1);
1826
1827 rt->dst.flags = DST_HOST | 1825 rt->dst.flags = DST_HOST |
1828 (nopolicy ? DST_NOPOLICY : 0) | 1826 (nopolicy ? DST_NOPOLICY : 0) |
1829 (noxfrm ? DST_NOXFRM : 0); 1827 (noxfrm ? DST_NOXFRM : 0);
@@ -2679,12 +2677,11 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi
2679{ 2677{
2680 struct rtable *ort = *rp; 2678 struct rtable *ort = *rp;
2681 struct rtable *rt = (struct rtable *) 2679 struct rtable *rt = (struct rtable *)
2682 dst_alloc(&ipv4_dst_blackhole_ops); 2680 dst_alloc(&ipv4_dst_blackhole_ops, 1);
2683 2681
2684 if (rt) { 2682 if (rt) {
2685 struct dst_entry *new = &rt->dst; 2683 struct dst_entry *new = &rt->dst;
2686 2684
2687 atomic_set(&new->__refcnt, 1);
2688 new->__use = 1; 2685 new->__use = 1;
2689 new->input = dst_discard; 2686 new->input = dst_discard;
2690 new->output = dst_discard; 2687 new->output = dst_discard;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ad8556e6fd4..7946b53692d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -221,7 +221,7 @@ static struct rt6_info ip6_blk_hole_entry_template = {
221/* allocate dst with ip6_dst_ops */ 221/* allocate dst with ip6_dst_ops */
222static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops) 222static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops)
223{ 223{
224 return (struct rt6_info *)dst_alloc(ops); 224 return (struct rt6_info *)dst_alloc(ops, 0);
225} 225}
226 226
227static void ip6_dst_destroy(struct dst_entry *dst) 227static void ip6_dst_destroy(struct dst_entry *dst)
@@ -873,13 +873,12 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
873{ 873{
874 struct rt6_info *ort = (struct rt6_info *) *dstp; 874 struct rt6_info *ort = (struct rt6_info *) *dstp;
875 struct rt6_info *rt = (struct rt6_info *) 875 struct rt6_info *rt = (struct rt6_info *)
876 dst_alloc(&ip6_dst_blackhole_ops); 876 dst_alloc(&ip6_dst_blackhole_ops, 1);
877 struct dst_entry *new = NULL; 877 struct dst_entry *new = NULL;
878 878
879 if (rt) { 879 if (rt) {
880 new = &rt->dst; 880 new = &rt->dst;
881 881
882 atomic_set(&new->__refcnt, 1);
883 new->__use = 1; 882 new->__use = 1;
884 new->input = dst_discard; 883 new->input = dst_discard;
885 new->output = dst_discard; 884 new->output = dst_discard;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 8b3ef404c79..3f1257add4f 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1340,7 +1340,7 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
1340 default: 1340 default:
1341 BUG(); 1341 BUG();
1342 } 1342 }
1343 xdst = dst_alloc(dst_ops) ?: ERR_PTR(-ENOBUFS); 1343 xdst = dst_alloc(dst_ops, 0) ?: ERR_PTR(-ENOBUFS);
1344 xfrm_policy_put_afinfo(afinfo); 1344 xfrm_policy_put_afinfo(afinfo);
1345 1345
1346 xdst->flo.ops = &xfrm_bundle_fc_ops; 1346 xdst->flo.ops = &xfrm_bundle_fc_ops;