aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDipankar Sarma <dipankar@in.ibm.com>2004-08-22 22:58:51 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-22 22:58:51 -0700
commit5dae7a69a46f3a9f6562a4702f8beaa7f77e94f6 (patch)
tree40daf62eb530c10372f9cb90f600a0b040c5e725 /net
parent9711268caede0cbd322244d70145a6e914fac52e (diff)
downloadhistory-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.c3
-rw-r--r--net/core/dev.c3
-rw-r--r--net/core/netfilter.c3
-rw-r--r--net/decnet/dn_route.c17
-rw-r--r--net/ipv4/icmp.c3
-rw-r--r--net/ipv4/ip_input.c3
-rw-r--r--net/ipv4/route.c24
-rw-r--r--net/ipv6/icmp.c3
-rw-r--r--net/ipv6/ip6_input.c3
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;