diff options
author | Dipankar Sarma <dipankar@in.ibm.com> | 2004-08-22 22:58:51 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-22 22:58:51 -0700 |
commit | 5dae7a69a46f3a9f6562a4702f8beaa7f77e94f6 (patch) | |
tree | 40daf62eb530c10372f9cb90f600a0b040c5e725 /net | |
parent | 9711268caede0cbd322244d70145a6e914fac52e (diff) | |
download | history-5dae7a69a46f3a9f6562a4702f8beaa7f77e94f6.tar.gz |
[PATCH] rcu: abstracted RCU dereferencing
Use abstracted RCU API to dereference RCU protected data. Hides barrier
details. Patch from Paul McKenney.
This patch introduced an rcu_dereference() macro that replaces most uses of
smp_read_barrier_depends(). The new macro has the advantage of explicitly
documenting which pointers are protected by RCU -- in contrast, it is
sometimes difficult to figure out which pointer is being protected by a given
smp_read_barrier_depends() call.
Signed-off-by: Paul McKenney <paulmck@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_input.c | 3 | ||||
-rw-r--r-- | net/core/dev.c | 3 | ||||
-rw-r--r-- | net/core/netfilter.c | 3 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 17 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 3 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 3 | ||||
-rw-r--r-- | net/ipv4/route.c | 24 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 3 |
9 files changed, 25 insertions, 37 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index fdf8f9eb6554e0..8a9f66335f95b7 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -56,8 +56,7 @@ int br_handle_frame_finish(struct sk_buff *skb) dest = skb->mac.ethernet->h_dest; rcu_read_lock(); - p = skb->dev->br_port; - smp_read_barrier_depends(); + p = rcu_dereference(skb->dev->br_port); if (p == NULL || p->state == BR_STATE_DISABLED) { kfree_skb(skb); diff --git a/net/core/dev.c b/net/core/dev.c index 547469d2ac6fe4..a67e65a0f26701 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1332,8 +1332,7 @@ int dev_queue_xmit(struct sk_buff *skb) * also serializes access to the device queue. */ - q = dev->qdisc; - smp_read_barrier_depends(); + q = rcu_dereference(dev->qdisc); #ifdef CONFIG_NET_CLS_ACT skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); #endif diff --git a/net/core/netfilter.c b/net/core/netfilter.c index 58632d189f52e3..09d10722632b42 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c @@ -783,13 +783,12 @@ void nf_log_packet(int pf, nf_logfn *logfn; rcu_read_lock(); - logfn = nf_logging[pf]; + logfn = rcu_dereference(nf_logging[pf]); if (logfn) { va_start(args, fmt); vsnprintf(prefix, sizeof(prefix), fmt, args); va_end(args); /* We must read logging before nf_logfn[pf] */ - smp_read_barrier_depends(); logfn(hooknum, skb, in, out, prefix); } else if (!reported) { printk(KERN_WARNING "nf_log_packet: can\'t log yet, " diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index c833f3625ca30f..5b1626bb45ff81 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1,4 +1,3 @@ - /* * DECnet An implementation of the DECnet protocol suite for the LINUX * operating system. DECnet is implemented using the BSD Socket @@ -1175,8 +1174,8 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl if (!(flags & MSG_TRYHARD)) { rcu_read_lock_bh(); - for(rt = dn_rt_hash_table[hash].chain; rt; rt = rt->u.rt_next) { - smp_read_barrier_depends(); + for(rt = rcu_dereference(dn_rt_hash_table[hash].chain); rt; + rt = rcu_dereference(rt->u.rt_next)) { if ((flp->fld_dst == rt->fl.fld_dst) && (flp->fld_src == rt->fl.fld_src) && #ifdef CONFIG_DECNET_ROUTE_FWMARK @@ -1454,8 +1453,8 @@ int dn_route_input(struct sk_buff *skb) return 0; rcu_read_lock(); - for(rt = dn_rt_hash_table[hash].chain; rt != NULL; rt = rt->u.rt_next) { - read_barrier_depends(); + for(rt = rcu_dereference(dn_rt_hash_table[hash].chain); rt != NULL; + rt = rcu_dereference(rt->u.rt_next)) { if ((rt->fl.fld_src == cb->src) && (rt->fl.fld_dst == cb->dst) && (rt->fl.oif == 0) && @@ -1648,8 +1647,9 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) if (h > s_h) s_idx = 0; rcu_read_lock_bh(); - for(rt = dn_rt_hash_table[h].chain, idx = 0; rt; rt = rt->u.rt_next, idx++) { - smp_read_barrier_depends(); + for(rt = rcu_dereference(dn_rt_hash_table[h].chain), idx = 0; + rt; + rt = rcu_dereference(rt->u.rt_next), idx++) { if (idx < s_idx) continue; skb->dst = dst_clone(&rt->u.dst); @@ -1692,9 +1692,8 @@ static struct dn_route *dn_rt_cache_get_first(struct seq_file *seq) static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_route *rt) { - struct dn_rt_cache_iter_state *s = seq->private; + struct dn_rt_cache_iter_state *s = rcu_dereference(seq->private); - smp_read_barrier_depends(); rt = rt->u.rt_next; while(!rt) { rcu_read_unlock_bh(); diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 69261324d4b497..be40431b73cf77 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -705,8 +705,7 @@ static void icmp_unreach(struct sk_buff *skb) read_unlock(&raw_v4_lock); rcu_read_lock(); - ipprot = inet_protos[hash]; - smp_read_barrier_depends(); + ipprot = rcu_dereference(inet_protos[hash]); if (ipprot && ipprot->err_handler) ipprot->err_handler(skb, info); rcu_read_unlock(); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index c7b3b6050207b0..f2e88193d559d7 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -231,10 +231,9 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) if (raw_sk) raw_v4_input(skb, skb->nh.iph, hash); - if ((ipprot = inet_protos[hash]) != NULL) { + if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) { int ret; - smp_read_barrier_depends(); if (!ipprot->no_policy && !xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { kfree_skb(skb); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0cd8965b546b24..92c79da5f2977f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -237,9 +237,8 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq) static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r) { - struct rt_cache_iter_state *st = seq->private; + struct rt_cache_iter_state *st = rcu_dereference(seq->private); - smp_read_barrier_depends(); r = r->u.rt_next; while (!r) { rcu_read_unlock_bh(); @@ -1004,10 +1003,9 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, rthp=&rt_hash_table[hash].chain; rcu_read_lock(); - while ((rth = *rthp) != NULL) { + while ((rth = rcu_dereference(*rthp)) != NULL) { struct rtable *rt; - smp_read_barrier_depends(); if (rth->fl.fl4_dst != daddr || rth->fl.fl4_src != skeys[i] || rth->fl.fl4_tos != tos || @@ -1259,9 +1257,8 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) unsigned hash = rt_hash_code(daddr, skeys[i], tos); rcu_read_lock(); - for (rth = rt_hash_table[hash].chain; rth; - rth = rth->u.rt_next) { - smp_read_barrier_depends(); + for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; + rth = rcu_dereference(rth->u.rt_next)) { if (rth->fl.fl4_dst == daddr && rth->fl.fl4_src == skeys[i] && rth->rt_dst == daddr && @@ -1864,8 +1861,8 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr, hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos); rcu_read_lock(); - for (rth = rt_hash_table[hash].chain; rth; rth = rth->u.rt_next) { - smp_read_barrier_depends(); + for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; + rth = rcu_dereference(rth->u.rt_next)) { if (rth->fl.fl4_dst == daddr && rth->fl.fl4_src == saddr && rth->fl.iif == iif && @@ -2232,8 +2229,8 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp) hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5), flp->fl4_tos); rcu_read_lock_bh(); - for (rth = rt_hash_table[hash].chain; rth; rth = rth->u.rt_next) { - smp_read_barrier_depends(); + for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; + rth = rcu_dereference(rth->u.rt_next)) { if (rth->fl.fl4_dst == flp->fl4_dst && rth->fl.fl4_src == flp->fl4_src && rth->fl.iif == 0 && @@ -2464,9 +2461,8 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) if (h > s_h) s_idx = 0; rcu_read_lock_bh(); - for (rt = rt_hash_table[h].chain, idx = 0; rt; - rt = rt->u.rt_next, idx++) { - smp_read_barrier_depends(); + for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt; + rt = rcu_dereference(rt->u.rt_next), idx++) { if (idx < s_idx) continue; skb->dst = dst_clone(&rt->u.dst); diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 4faafff32e7bc7..9a676aaf61843e 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -530,8 +530,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info) hash = nexthdr & (MAX_INET_PROTOS - 1); rcu_read_lock(); - ipprot = inet6_protos[hash]; - smp_read_barrier_depends(); + ipprot = rcu_dereference(inet6_protos[hash]); if (ipprot && ipprot->err_handler) ipprot->err_handler(skb, NULL, type, code, inner_offset, info); rcu_read_unlock(); diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 9b9cee7c063f81..99436a59e4ceb0 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -167,10 +167,9 @@ resubmit: ipv6_raw_deliver(skb, nexthdr); hash = nexthdr & (MAX_INET_PROTOS - 1); - if ((ipprot = inet6_protos[hash]) != NULL) { + if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) { int ret; - smp_read_barrier_depends(); if (ipprot->flags & INET6_PROTO_FINAL) { struct ipv6hdr *hdr; |