From f7b14315faf62935a791dd67969c4289563058f0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 Feb 2007 15:46:51 -0800 Subject: [DECNET]: fix misannotation of linkinfo_dn Signed-off-by: Al Viro Signed-off-by: David S. Miller --- include/linux/dn.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/dn.h b/include/linux/dn.h index 10b6a6fd5837..02bba040fcfb 100644 --- a/include/linux/dn.h +++ b/include/linux/dn.h @@ -113,7 +113,7 @@ struct accessdata_dn * DECnet logical link information structure */ struct linkinfo_dn { - __le16 idn_segsize; /* Segment size for link */ + __u16 idn_segsize; /* Segment size for link */ __u8 idn_linkstate; /* Logical link state */ }; -- cgit v1.2.3 From 75ce7ceaa1221858c0163e75d19eb8a423a212ff Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 9 Feb 2007 16:14:24 -0800 Subject: [NET]: Introduce union in struct dst_entry to hold 'next' pointer This patch introduces an anonymous union to nicely express the fact that all objects inherited from struct dst_entry should access to the generic 'next' pointer but with appropriate type verification. This patch is a prereq before following patches. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/dst.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/dst.h b/include/net/dst.h index 62b7e7598e9a..5d62342e8bc4 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -37,7 +37,12 @@ struct sk_buff; struct dst_entry { - struct dst_entry *next; + union { + struct dst_entry *next; + struct rtable *rt_next; + struct rt6_info *rt6_next; + struct dn_route *dn_next; + }; atomic_t __refcnt; /* client references */ int __use; struct dst_entry *child; -- cgit v1.2.3 From 093c2ca4167cf66f69020329d14138da0da8599b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 9 Feb 2007 16:19:26 -0800 Subject: [IPV4]: Convert ipv4 route to use the new dst_entry 'next' pointer This patch removes the rt_next pointer from 'struct rtable.u' union, and renames u.rt_next to u.dst_rt_next. It also moves 'struct flowi' right after 'struct dst_entry' to prepare the gain on lookups. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/route.h | 7 +++---- net/ipv4/route.c | 56 ++++++++++++++++++++++++++--------------------------- 2 files changed, 31 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/net/route.h b/include/net/route.h index 1440bdb5a27d..749e4dfe5ff3 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -53,9 +53,11 @@ struct rtable union { struct dst_entry dst; - struct rtable *rt_next; } u; + /* Cache lookup keys */ + struct flowi fl; + struct in_device *idev; unsigned rt_flags; @@ -69,9 +71,6 @@ struct rtable /* Info on neighbour */ __be32 rt_gateway; - /* Cache lookup keys */ - struct flowi fl; - /* Miscellaneous cached information */ __be32 rt_spec_dst; /* RFC1122 specific destination */ struct inet_peer *peer; /* long-living peer info */ diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 56d6602affb4..5b3834b38a2d 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -289,7 +289,7 @@ static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r) { struct rt_cache_iter_state *st = rcu_dereference(seq->private); - r = r->u.rt_next; + r = r->u.dst.rt_next; while (!r) { rcu_read_unlock_bh(); if (--st->bucket < 0) @@ -512,7 +512,7 @@ static __inline__ int rt_fast_clean(struct rtable *rth) /* Kill broadcast/multicast entries very aggresively, if they collide in hash table with more useful entries */ return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) && - rth->fl.iif && rth->u.rt_next; + rth->fl.iif && rth->u.dst.rt_next; } static __inline__ int rt_valuable(struct rtable *rth) @@ -595,10 +595,10 @@ static struct rtable **rt_remove_balanced_route(struct rtable **chain_head, if (((*rthp)->u.dst.flags & DST_BALANCED) != 0 && compare_keys(&(*rthp)->fl, &expentry->fl)) { if (*rthp == expentry) { - *rthp = rth->u.rt_next; + *rthp = rth->u.dst.rt_next; continue; } else { - *rthp = rth->u.rt_next; + *rthp = rth->u.dst.rt_next; rt_free(rth); if (removed_count) ++(*removed_count); @@ -606,9 +606,9 @@ static struct rtable **rt_remove_balanced_route(struct rtable **chain_head, } else { if (!((*rthp)->u.dst.flags & DST_BALANCED) && passedexpired && !nextstep) - nextstep = &rth->u.rt_next; + nextstep = &rth->u.dst.rt_next; - rthp = &rth->u.rt_next; + rthp = &rth->u.dst.rt_next; } } @@ -649,12 +649,12 @@ static void rt_check_expire(unsigned long dummy) /* Entry is expired even if it is in use */ if (time_before_eq(now, rth->u.dst.expires)) { tmo >>= 1; - rthp = &rth->u.rt_next; + rthp = &rth->u.dst.rt_next; continue; } } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) { tmo >>= 1; - rthp = &rth->u.rt_next; + rthp = &rth->u.dst.rt_next; continue; } @@ -668,11 +668,11 @@ static void rt_check_expire(unsigned long dummy) if (!rthp) break; } else { - *rthp = rth->u.rt_next; + *rthp = rth->u.dst.rt_next; rt_free(rth); } #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ - *rthp = rth->u.rt_next; + *rthp = rth->u.dst.rt_next; rt_free(rth); #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ } @@ -706,7 +706,7 @@ static void rt_run_flush(unsigned long dummy) spin_unlock_bh(rt_hash_lock_addr(i)); for (; rth; rth = next) { - next = rth->u.rt_next; + next = rth->u.dst.rt_next; rt_free(rth); } } @@ -840,7 +840,7 @@ static int rt_garbage_collect(void) while ((rth = *rthp) != NULL) { if (!rt_may_expire(rth, tmo, expire)) { tmo >>= 1; - rthp = &rth->u.rt_next; + rthp = &rth->u.dst.rt_next; continue; } #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED @@ -858,12 +858,12 @@ static int rt_garbage_collect(void) if (!rthp) break; } else { - *rthp = rth->u.rt_next; + *rthp = rth->u.dst.rt_next; rt_free(rth); goal--; } #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ - *rthp = rth->u.rt_next; + *rthp = rth->u.dst.rt_next; rt_free(rth); goal--; #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ @@ -947,13 +947,13 @@ restart: if (compare_keys(&rth->fl, &rt->fl)) { #endif /* Put it first */ - *rthp = rth->u.rt_next; + *rthp = rth->u.dst.rt_next; /* * Since lookup is lockfree, the deletion * must be visible to another weakly ordered CPU before * the insertion at the start of the hash chain. */ - rcu_assign_pointer(rth->u.rt_next, + rcu_assign_pointer(rth->u.dst.rt_next, rt_hash_table[hash].chain); /* * Since lookup is lockfree, the update writes @@ -983,7 +983,7 @@ restart: chain_length++; - rthp = &rth->u.rt_next; + rthp = &rth->u.dst.rt_next; } if (cand) { @@ -994,7 +994,7 @@ restart: * only 2 entries per bucket. We will see. */ if (chain_length > ip_rt_gc_elasticity) { - *candp = cand->u.rt_next; + *candp = cand->u.dst.rt_next; rt_free(cand); } } @@ -1034,13 +1034,13 @@ restart: } } - rt->u.rt_next = rt_hash_table[hash].chain; + rt->u.dst.rt_next = rt_hash_table[hash].chain; #if RT_CACHE_DEBUG >= 2 - if (rt->u.rt_next) { + if (rt->u.dst.rt_next) { struct rtable *trt; printk(KERN_DEBUG "rt_cache @%02x: %u.%u.%u.%u", hash, NIPQUAD(rt->rt_dst)); - for (trt = rt->u.rt_next; trt; trt = trt->u.rt_next) + for (trt = rt->u.dst.rt_next; trt; trt = trt->u.dst.rt_next) printk(" . %u.%u.%u.%u", NIPQUAD(trt->rt_dst)); printk("\n"); } @@ -1117,9 +1117,9 @@ static void rt_del(unsigned hash, struct rtable *rt) spin_lock_bh(rt_hash_lock_addr(hash)); ip_rt_put(rt); for (rthp = &rt_hash_table[hash].chain; *rthp; - rthp = &(*rthp)->u.rt_next) + rthp = &(*rthp)->u.dst.rt_next) if (*rthp == rt) { - *rthp = rt->u.rt_next; + *rthp = rt->u.dst.rt_next; rt_free(rt); break; } @@ -1167,7 +1167,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rth->fl.fl4_src != skeys[i] || rth->fl.oif != ikeys[k] || rth->fl.iif != 0) { - rthp = &rth->u.rt_next; + rthp = &rth->u.dst.rt_next; continue; } @@ -1416,7 +1416,7 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) rcu_read_lock(); for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; - rth = rcu_dereference(rth->u.rt_next)) { + rth = rcu_dereference(rth->u.dst.rt_next)) { if (rth->fl.fl4_dst == daddr && rth->fl.fl4_src == skeys[i] && rth->rt_dst == daddr && @@ -2099,7 +2099,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, rcu_read_lock(); for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; - rth = rcu_dereference(rth->u.rt_next)) { + rth = rcu_dereference(rth->u.dst.rt_next)) { if (rth->fl.fl4_dst == daddr && rth->fl.fl4_src == saddr && rth->fl.iif == iif && @@ -2563,7 +2563,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp) rcu_read_lock_bh(); for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; - rth = rcu_dereference(rth->u.rt_next)) { + rth = rcu_dereference(rth->u.dst.rt_next)) { if (rth->fl.fl4_dst == flp->fl4_dst && rth->fl.fl4_src == flp->fl4_src && rth->fl.iif == 0 && @@ -2825,7 +2825,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) s_idx = 0; rcu_read_lock_bh(); for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt; - rt = rcu_dereference(rt->u.rt_next), idx++) { + rt = rcu_dereference(rt->u.dst.rt_next), idx++) { if (idx < s_idx) continue; skb->dst = dst_clone(&rt->u.dst); -- cgit v1.2.3 From 7cc482634f1f1e1db5401007658c8e8d6cf1617d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 9 Feb 2007 16:22:57 -0800 Subject: [IPV6]: Convert ipv6 route to use the new dst_entry 'next' pointer This patch removes the next pointer from 'struct rt6_info.u' union, and renames u.next to u.dst.rt6_next. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 1 - net/ipv6/ip6_fib.c | 20 ++++++++++---------- net/ipv6/route.c | 20 ++++++++++---------- 3 files changed, 20 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 7be4f4e3a0f2..9eda572a2a65 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -83,7 +83,6 @@ struct rt6_info { union { struct dst_entry dst; - struct rt6_info *next; } u; struct inet6_dev *rt6i_idev; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f90ab5233326..8c9024890bbe 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -298,7 +298,7 @@ static int fib6_dump_node(struct fib6_walker_t *w) int res; struct rt6_info *rt; - for (rt = w->leaf; rt; rt = rt->u.next) { + for (rt = w->leaf; rt; rt = rt->u.dst.rt6_next) { res = rt6_dump_route(rt, w->args); if (res < 0) { /* Frame is full, suspend walking */ @@ -624,11 +624,11 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, fn->leaf == &ip6_null_entry && !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){ fn->leaf = rt; - rt->u.next = NULL; + rt->u.dst.rt6_next = NULL; goto out; } - for (iter = fn->leaf; iter; iter=iter->u.next) { + for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) { /* * Search for duplicates */ @@ -656,7 +656,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, if (iter->rt6i_metric > rt->rt6i_metric) break; - ins = &iter->u.next; + ins = &iter->u.dst.rt6_next; } /* @@ -664,7 +664,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, */ out: - rt->u.next = iter; + rt->u.dst.rt6_next = iter; *ins = rt; rt->rt6i_node = fn; atomic_inc(&rt->rt6i_ref); @@ -1105,7 +1105,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, RT6_TRACE("fib6_del_route\n"); /* Unlink it */ - *rtp = rt->u.next; + *rtp = rt->u.dst.rt6_next; rt->rt6i_node = NULL; rt6_stats.fib_rt_entries--; rt6_stats.fib_discarded_routes++; @@ -1115,14 +1115,14 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, FOR_WALKERS(w) { if (w->state == FWS_C && w->leaf == rt) { RT6_TRACE("walker %p adjusted by delroute\n", w); - w->leaf = rt->u.next; + w->leaf = rt->u.dst.rt6_next; if (w->leaf == NULL) w->state = FWS_U; } } read_unlock(&fib6_walker_lock); - rt->u.next = NULL; + rt->u.dst.rt6_next = NULL; if (fn->leaf == NULL && fn->fn_flags&RTN_TL_ROOT) fn->leaf = &ip6_null_entry; @@ -1190,7 +1190,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info) * Walk the leaf entries looking for ourself */ - for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) { + for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.dst.rt6_next) { if (*rtp == rt) { fib6_del_route(fn, rtp, info); return 0; @@ -1317,7 +1317,7 @@ static int fib6_clean_node(struct fib6_walker_t *w) struct rt6_info *rt; struct fib6_cleaner_t *c = (struct fib6_cleaner_t*)w; - for (rt = w->leaf; rt; rt = rt->u.next) { + for (rt = w->leaf; rt; rt = rt->u.dst.rt6_next) { res = c->func(rt, c->arg); if (res < 0) { w->leaf = rt; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index fc8448cc5d21..a415ac610e2d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -243,7 +243,7 @@ static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt, struct rt6_info *sprt; if (oif) { - for (sprt = rt; sprt; sprt = sprt->u.next) { + for (sprt = rt; sprt; sprt = sprt->u.dst.rt6_next) { struct net_device *dev = sprt->rt6i_dev; if (dev->ifindex == oif) return sprt; @@ -376,7 +376,7 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, for (rt = rt0, metric = rt0->rt6i_metric; rt && rt->rt6i_metric == metric && (!last || rt != rt0); - rt = rt->u.next) { + rt = rt->u.dst.rt6_next) { int m; if (rt6_check_expired(rt)) @@ -404,9 +404,9 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, /* no entries matched; do round-robin */ static DEFINE_SPINLOCK(lock); spin_lock(&lock); - *head = rt0->u.next; - rt0->u.next = last->u.next; - last->u.next = rt0; + *head = rt0->u.dst.rt6_next; + rt0->u.dst.rt6_next = last->u.dst.rt6_next; + last->u.dst.rt6_next = rt0; spin_unlock(&lock); } @@ -1278,7 +1278,7 @@ static int ip6_route_del(struct fib6_config *cfg) &cfg->fc_src, cfg->fc_src_len); if (fn) { - for (rt = fn->leaf; rt; rt = rt->u.next) { + for (rt = fn->leaf; rt; rt = rt->u.dst.rt6_next) { if (cfg->fc_ifindex && (rt->rt6i_dev == NULL || rt->rt6i_dev->ifindex != cfg->fc_ifindex)) @@ -1329,7 +1329,7 @@ static struct rt6_info *__ip6_route_redirect(struct fib6_table *table, read_lock_bh(&table->tb6_lock); fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); restart: - for (rt = fn->leaf; rt; rt = rt->u.next) { + for (rt = fn->leaf; rt; rt = rt->u.dst.rt6_next) { /* * Current route is on-link; redirect is always invalid. * @@ -1590,7 +1590,7 @@ static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixle if (!fn) goto out; - for (rt = fn->leaf; rt; rt = rt->u.next) { + for (rt = fn->leaf; rt; rt = rt->u.dst.rt6_next) { if (rt->rt6i_dev->ifindex != ifindex) continue; if ((rt->rt6i_flags & (RTF_ROUTEINFO|RTF_GATEWAY)) != (RTF_ROUTEINFO|RTF_GATEWAY)) @@ -1641,7 +1641,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d return NULL; write_lock_bh(&table->tb6_lock); - for (rt = table->tb6_root.leaf; rt; rt=rt->u.next) { + for (rt = table->tb6_root.leaf; rt; rt=rt->u.dst.rt6_next) { if (dev == rt->rt6i_dev && ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && ipv6_addr_equal(&rt->rt6i_gateway, addr)) @@ -1684,7 +1684,7 @@ void rt6_purge_dflt_routers(void) restart: read_lock_bh(&table->tb6_lock); - for (rt = table->tb6_root.leaf; rt; rt = rt->u.next) { + for (rt = table->tb6_root.leaf; rt; rt = rt->u.dst.rt6_next) { if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) { dst_hold(&rt->u.dst); read_unlock_bh(&table->tb6_lock); -- cgit v1.2.3 From 0c195c3fc4e95a06b0c0017506f074c94af99c35 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 9 Feb 2007 16:25:52 -0800 Subject: [DECNET]: Convert decnet route to use the new dst_entry 'next' pointer This patch removes the next pointer from 'struct dn_route.u' union, and renames u.rt_next to u.dst.dn_next. It also moves 'struct flowi' right after 'struct dst_entry' to prepare speedup lookups. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/dn_route.h | 5 ++--- net/decnet/dn_route.c | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/net/dn_route.h b/include/net/dn_route.h index 76f957e258b0..a566944c4962 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h @@ -68,9 +68,10 @@ extern void dn_rt_cache_flush(int delay); struct dn_route { union { struct dst_entry dst; - struct dn_route *rt_next; } u; + struct flowi fl; + __le16 rt_saddr; __le16 rt_daddr; __le16 rt_gateway; @@ -80,8 +81,6 @@ struct dn_route { unsigned rt_flags; unsigned rt_type; - - struct flowi fl; }; extern void dn_route_init(void); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 49b27a477e89..efccc42ff1c6 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -167,11 +167,11 @@ static void dn_dst_check_expire(unsigned long dummy) while((rt=*rtp) != NULL) { if (atomic_read(&rt->u.dst.__refcnt) || (now - rt->u.dst.lastuse) < expire) { - rtp = &rt->u.rt_next; + rtp = &rt->u.dst.dn_next; continue; } - *rtp = rt->u.rt_next; - rt->u.rt_next = NULL; + *rtp = rt->u.dst.dn_next; + rt->u.dst.dn_next = NULL; dnrt_free(rt); } spin_unlock(&dn_rt_hash_table[i].lock); @@ -198,11 +198,11 @@ static int dn_dst_gc(void) while((rt=*rtp) != NULL) { if (atomic_read(&rt->u.dst.__refcnt) || (now - rt->u.dst.lastuse) < expire) { - rtp = &rt->u.rt_next; + rtp = &rt->u.dst.dn_next; continue; } - *rtp = rt->u.rt_next; - rt->u.rt_next = NULL; + *rtp = rt->u.dst.dn_next; + rt->u.dst.dn_next = NULL; dnrt_drop(rt); break; } @@ -286,8 +286,8 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route * while((rth = *rthp) != NULL) { if (compare_keys(&rth->fl, &rt->fl)) { /* Put it first */ - *rthp = rth->u.rt_next; - rcu_assign_pointer(rth->u.rt_next, + *rthp = rth->u.dst.dn_next; + rcu_assign_pointer(rth->u.dst.dn_next, dn_rt_hash_table[hash].chain); rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth); @@ -300,10 +300,10 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route * *rp = rth; return 0; } - rthp = &rth->u.rt_next; + rthp = &rth->u.dst.dn_next; } - rcu_assign_pointer(rt->u.rt_next, dn_rt_hash_table[hash].chain); + rcu_assign_pointer(rt->u.dst.dn_next, dn_rt_hash_table[hash].chain); rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt); dst_hold(&rt->u.dst); @@ -326,8 +326,8 @@ void dn_run_flush(unsigned long dummy) goto nothing_to_declare; for(; rt; rt=next) { - next = rt->u.rt_next; - rt->u.rt_next = NULL; + next = rt->u.dst.dn_next; + rt->u.dst.dn_next = NULL; dst_free((struct dst_entry *)rt); } @@ -1169,7 +1169,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl if (!(flags & MSG_TRYHARD)) { rcu_read_lock_bh(); for(rt = rcu_dereference(dn_rt_hash_table[hash].chain); rt; - rt = rcu_dereference(rt->u.rt_next)) { + rt = rcu_dereference(rt->u.dst.dn_next)) { if ((flp->fld_dst == rt->fl.fld_dst) && (flp->fld_src == rt->fl.fld_src) && (flp->mark == rt->fl.mark) && @@ -1443,7 +1443,7 @@ int dn_route_input(struct sk_buff *skb) rcu_read_lock(); for(rt = rcu_dereference(dn_rt_hash_table[hash].chain); rt != NULL; - rt = rcu_dereference(rt->u.rt_next)) { + rt = rcu_dereference(rt->u.dst.dn_next)) { if ((rt->fl.fld_src == cb->src) && (rt->fl.fld_dst == cb->dst) && (rt->fl.oif == 0) && @@ -1627,7 +1627,7 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) rcu_read_lock_bh(); for(rt = rcu_dereference(dn_rt_hash_table[h].chain), idx = 0; rt; - rt = rcu_dereference(rt->u.rt_next), idx++) { + rt = rcu_dereference(rt->u.dst.dn_next), idx++) { if (idx < s_idx) continue; skb->dst = dst_clone(&rt->u.dst); @@ -1673,7 +1673,7 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou { struct dn_rt_cache_iter_state *s = rcu_dereference(seq->private); - rt = rt->u.rt_next; + rt = rt->u.dst.dn_next; while(!rt) { rcu_read_unlock_bh(); if (--s->bucket < 0) -- cgit v1.2.3 From 1e19e02ca0c5e33ea73a25127dbe6c3b8fcaac4b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 9 Feb 2007 16:26:55 -0800 Subject: [NET]: Reorder fields of struct dst_entry This last patch (but not least :) ) finally moves the next pointer at the end of struct dst_entry. This permits to perform route cache lookups with a minimal cost of one cache line per entry, instead of two. Both 32bits and 64bits platforms benefit from this new layout. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/dst.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/net/dst.h b/include/net/dst.h index 5d62342e8bc4..e12a8ce0b9b3 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -37,14 +37,7 @@ struct sk_buff; struct dst_entry { - union { - struct dst_entry *next; - struct rtable *rt_next; - struct rt6_info *rt6_next; - struct dn_route *dn_next; - }; - atomic_t __refcnt; /* client references */ - int __use; + struct rcu_head rcu_head; struct dst_entry *child; struct net_device *dev; short error; @@ -55,7 +48,6 @@ struct dst_entry #define DST_NOPOLICY 4 #define DST_NOHASH 8 #define DST_BALANCED 0x10 - unsigned long lastuse; unsigned long expires; unsigned short header_len; /* more space at head required */ @@ -80,8 +72,16 @@ struct dst_entry #endif struct dst_ops *ops; - struct rcu_head rcu_head; + unsigned long lastuse; + atomic_t __refcnt; /* client references */ + int __use; + union { + struct dst_entry *next; + struct rtable *rt_next; + struct rt6_info *rt6_next; + struct dn_route *dn_next; + }; char info[0]; }; -- cgit v1.2.3