From: Eric Dumazet <dada1@cosmosbay.com>
To: Andi Kleen <ak@suse.de>
Cc: netdev@vger.kernel.org, davem@davemloft.net
Subject: Re: [PATCH] Shrink struct dst_entry a bit
Date: Tue, 13 Mar 2007 15:58:10 +0100 [thread overview]
Message-ID: <200703131558.10596.dada1@cosmosbay.com> (raw)
In-Reply-To: <200703131544.57757.dada1@cosmosbay.com>
[-- Attachment #1: Type: text/plain, Size: 426 bytes --]
On Tuesday 13 March 2007 15:44, Eric Dumazet wrote:
> Also, 'lastuse' could use a u32 too, I even had a patch for this one...
Here is the patch I have here for lastuse u32 conversion, not for inclusion
yet because not yet tested (only compiled)
[PATCH] NET : abstract lastuse (from struct dst_entry) and convert it to u32
This saves 4 bytes (possibly 8) on 64 bit archs
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
[-- Attachment #2: lastuse.patch --]
[-- Type: text/plain, Size: 12548 bytes --]
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index c080f61..fb23951 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -89,7 +89,16 @@ static inline u64 get_jiffies_64(void)
return (u64)jiffies;
}
#endif
-
+/*
+ * On 64bit archs, storing timestamps in 'unsigned long' vars
+ * may consume unecessary memory. Using u32 is ok when deltas
+ * between current jiffie and past timestamps are known to
+ * fit in 32-1 bits. Even with HZ=1000, thats 24 days.
+ */
+static inline u32 get_jiffies_32(void)
+{
+ return (u32)jiffies;
+}
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
diff --git a/include/net/dst.h b/include/net/dst.h
index e12a8ce..70366b7 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -67,13 +67,13 @@ #define DST_BALANCED 0x10
int (*input)(struct sk_buff*);
int (*output)(struct sk_buff*);
+
+ struct dst_ops *ops;
#ifdef CONFIG_NET_CLS_ROUTE
__u32 tclassid;
#endif
-
- struct dst_ops *ops;
- unsigned long lastuse;
+ u32 __lastuse;
atomic_t __refcnt; /* client references */
int __use;
union {
@@ -103,11 +103,23 @@ struct dst_ops
int entry_size;
atomic_t entries;
- struct kmem_cache *kmem_cachep;
+ struct kmem_cache *kmem_cachep;
};
#ifdef __KERNEL__
+static inline void
+dst_lastuse_set(struct dst_entry *dst)
+{
+ dst->__lastuse = get_jiffies_32();
+}
+
+static inline unsigned long
+dst_lastuse_delta(const struct dst_entry *dst)
+{
+ return get_jiffies_32() - dst->__lastuse;
+}
+
static inline u32
dst_metric(const struct dst_entry *dst, int metric)
{
diff --git a/net/core/dst.c b/net/core/dst.c
index 764bccb..6c0a023 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -136,7 +136,7 @@ void * dst_alloc(struct dst_ops * ops)
return NULL;
atomic_set(&dst->__refcnt, 0);
dst->ops = ops;
- dst->lastuse = jiffies;
+ dst_lastuse_set(dst);
dst->path = dst;
dst->input = dst_discard_in;
dst->output = dst_discard_out;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 6055074..c3f5264 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -215,7 +215,7 @@ int rtnl_put_cacheinfo(struct sk_buff *s
u32 ts, u32 tsage, long expires, u32 error)
{
struct rta_cacheinfo ci = {
- .rta_lastuse = jiffies_to_clock_t(jiffies - dst->lastuse),
+ .rta_lastuse = jiffies_to_clock_t(dst_lastuse_delta(dst)),
.rta_used = dst->__use,
.rta_clntref = atomic_read(&(dst->__refcnt)),
.rta_error = error,
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 32a7db3..3d5c46c 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -166,7 +166,7 @@ static void dn_dst_check_expire(unsigned
spin_lock(&dn_rt_hash_table[i].lock);
while((rt=*rtp) != NULL) {
if (atomic_read(&rt->u.dst.__refcnt) ||
- (now - rt->u.dst.lastuse) < expire) {
+ dst_lastuse_delta(&rt->u.dst) < expire) {
rtp = &rt->u.dst.dn_next;
continue;
}
@@ -187,7 +187,6 @@ static int dn_dst_gc(void)
{
struct dn_route *rt, **rtp;
int i;
- unsigned long now = jiffies;
unsigned long expire = 10 * HZ;
for(i = 0; i <= dn_rt_hash_mask; i++) {
@@ -197,7 +196,7 @@ static int dn_dst_gc(void)
while((rt=*rtp) != NULL) {
if (atomic_read(&rt->u.dst.__refcnt) ||
- (now - rt->u.dst.lastuse) < expire) {
+ dst_lastuse_delta(&rt->u.dst) < expire) {
rtp = &rt->u.dst.dn_next;
continue;
}
@@ -278,7 +277,6 @@ static inline int compare_keys(struct fl
static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp)
{
struct dn_route *rth, **rthp;
- unsigned long now = jiffies;
rthp = &dn_rt_hash_table[hash].chain;
@@ -293,7 +291,7 @@ static int dn_insert_route(struct dn_rou
rth->u.dst.__use++;
dst_hold(&rth->u.dst);
- rth->u.dst.lastuse = now;
+ dst_lastuse_set(&rth->u.dst);
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
dnrt_drop(rt);
@@ -308,7 +306,7 @@ static int dn_insert_route(struct dn_rou
dst_hold(&rt->u.dst);
rt->u.dst.__use++;
- rt->u.dst.lastuse = now;
+ dst_lastuse_set(&rt->u.dst);
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
*rp = rt;
return 0;
@@ -1119,7 +1117,7 @@ make_route:
rt->u.dst.neighbour = neigh;
neigh = NULL;
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
rt->u.dst.output = dn_output;
rt->u.dst.input = dn_rt_bug;
rt->rt_flags = flags;
@@ -1175,7 +1173,7 @@ static int __dn_route_output_key(struct
(flp->mark == rt->fl.mark) &&
(rt->fl.iif == 0) &&
(rt->fl.oif == flp->oif)) {
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
dst_hold(&rt->u.dst);
rt->u.dst.__use++;
rcu_read_unlock_bh();
@@ -1380,7 +1378,7 @@ make_route:
rt->u.dst.flags = DST_HOST;
rt->u.dst.neighbour = neigh;
rt->u.dst.dev = out_dev;
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
rt->u.dst.output = dn_rt_bug;
switch(res.type) {
case RTN_UNICAST:
@@ -1449,7 +1447,7 @@ int dn_route_input(struct sk_buff *skb)
(rt->fl.oif == 0) &&
(rt->fl.mark == skb->mark) &&
(rt->fl.iif == cb->iif)) {
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
dst_hold(&rt->u.dst);
rt->u.dst.__use++;
rcu_read_unlock();
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 2f44e61..6831897 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -343,7 +343,7 @@ static int cleanup_once(unsigned long tt
spin_lock_bh(&inet_peer_unused_lock);
p = inet_peer_unused_head;
if (p != NULL) {
- __u32 delta = (__u32)jiffies - p->dtime;
+ __u32 delta = get_jiffies_32() - p->dtime;
if (delta < ttl) {
/* Do not prune fresh entries. */
spin_unlock_bh(&inet_peer_unused_lock);
@@ -471,7 +471,7 @@ void inet_putpeer(struct inet_peer *p)
p->unused_next = NULL;
*inet_peer_unused_tailp = p;
inet_peer_unused_tailp = &p->unused_next;
- p->dtime = (__u32)jiffies;
+ p->dtime = get_jiffies_32();
}
spin_unlock_bh(&inet_peer_unused_lock);
}
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c
index 574c735..e318dbd 100644
--- a/net/ipv4/multipath_drr.c
+++ b/net/ipv4/multipath_drr.c
@@ -147,7 +147,7 @@ static void drr_select_route(const struc
multipath_comparekeys(&nh->fl, flp)) {
int nh_ifidx = nh->u.dst.dev->ifindex;
- nh->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&nh->u.dst);
nh->u.dst.__use++;
if (result != NULL)
continue;
diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c
index c312785..5355593 100644
--- a/net/ipv4/multipath_random.c
+++ b/net/ipv4/multipath_random.c
@@ -78,7 +78,7 @@ static void random_select_route(const st
for (rt = first; rt; rt = rt->u.dst.rt_next) {
if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
multipath_comparekeys(&rt->fl, flp)) {
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
if (i == candidate_no)
decision = rt;
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c
index 0ad2252..26a55bf 100644
--- a/net/ipv4/multipath_rr.c
+++ b/net/ipv4/multipath_rr.c
@@ -60,7 +60,7 @@ static void rr_select_route(const struct
nh = rcu_dereference(nh->u.dst.rt_next)) {
if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
multipath_comparekeys(&nh->fl, flp)) {
- nh->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&nh->u.dst);
if (min_use == -1 || nh->u.dst.__use < min_use) {
min_use = nh->u.dst.__use;
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index 57c5036..30467d3 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -189,7 +189,7 @@ static void wrandom_select_route(const s
decision = first;
last_mpc = NULL;
for (mpc = first_mpc; mpc; mpc = mpc->next) {
- mpc->rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&mpc->rt->u.dst);
if (last_power <= selector && selector < mpc->power)
decision = mpc->rt;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5841739..cbd6337 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -533,7 +533,7 @@ static int rt_may_expire(struct rtable *
time_after_eq(jiffies, rth->u.dst.expires))
goto out;
- age = jiffies - rth->u.dst.lastuse;
+ age = dst_lastuse_delta(&rth->u.dst);
ret = 0;
if ((age <= tmo1 && !rt_fast_clean(rth)) ||
(age <= tmo2 && rt_valuable(rth)))
@@ -549,7 +549,7 @@ out: return ret;
*/
static inline u32 rt_score(struct rtable *rt)
{
- u32 score = jiffies - rt->u.dst.lastuse;
+ u32 score = dst_lastuse_delta(&rt->u.dst);
score = ~score & ~(3<<30);
@@ -922,7 +922,6 @@ out: return 0;
static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
{
struct rtable *rth, **rthp;
- unsigned long now;
struct rtable *cand, **candp;
u32 min_score;
int chain_length;
@@ -933,7 +932,6 @@ restart:
min_score = ~(u32)0;
cand = NULL;
candp = NULL;
- now = jiffies;
rthp = &rt_hash_table[hash].chain;
@@ -962,7 +960,7 @@ #endif
rth->u.dst.__use++;
dst_hold(&rth->u.dst);
- rth->u.dst.lastuse = now;
+ dst_lastuse_set(&rth->u.dst);
spin_unlock_bh(rt_hash_lock_addr(hash));
rt_drop(rt);
@@ -1198,7 +1196,7 @@ void ip_rt_redirect(__be32 old_gw, __be3
if (rt->idev)
in_dev_hold(rt->idev);
rt->u.dst.obsolete = 0;
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
rt->u.dst.path = &rt->u.dst;
rt->u.dst.neighbour = NULL;
rt->u.dst.hh = NULL;
@@ -2105,7 +2103,7 @@ int ip_route_input(struct sk_buff *skb,
rth->fl.oif == 0 &&
rth->fl.mark == skb->mark &&
rth->fl.fl4_tos == tos) {
- rth->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rth->u.dst);
dst_hold(&rth->u.dst);
rth->u.dst.__use++;
RT_CACHE_STAT_INC(in_hit);
@@ -2581,7 +2579,7 @@ int __ip_route_output_key(struct rtable
return 0;
}
- rth->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rth->u.dst);
dst_hold(&rth->u.dst);
rth->u.dst.__use++;
RT_CACHE_STAT_INC(out_hit);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index f1c32ff..ecc8aa9 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -160,7 +160,7 @@ #endif
dev_hold(rt->u.dst.dev);
dst_prev->obsolete = -1;
dst_prev->flags |= DST_HOST;
- dst_prev->lastuse = jiffies;
+ dst_lastuse_set(dst_prev);
dst_prev->header_len = header_len;
dst_prev->nfheader_len = 0;
dst_prev->trailer_len = trailer_len;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index f4d7be7..906cfed 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1425,7 +1425,7 @@ static int fib6_age(struct rt6_info *rt,
gc_args.more++;
} else if (rt->rt6i_flags & RTF_CACHE) {
if (atomic_read(&rt->u.dst.__refcnt) == 0 &&
- time_after_eq(now, rt->u.dst.lastuse + gc_args.timeout)) {
+ dst_lastuse_delta(&rt->u.dst) >= gc_args.timeout) {
RT6_TRACE("aging clone %p\n", rt);
return -1;
} else if ((rt->rt6i_flags & RTF_GATEWAY) &&
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index bb2b508..bb7f203 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -528,7 +528,7 @@ out:
dst_hold(&rt->u.dst);
read_unlock_bh(&table->tb6_lock);
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
rt->u.dst.__use++;
return rt;
@@ -706,7 +706,7 @@ out:
dst_hold(&rt->u.dst);
read_unlock_bh(&table->tb6_lock);
out2:
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
rt->u.dst.__use++;
return rt;
@@ -801,7 +801,7 @@ out:
dst_hold(&rt->u.dst);
read_unlock_bh(&table->tb6_lock);
out2:
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
rt->u.dst.__use++;
return rt;
}
@@ -1560,7 +1560,7 @@ static struct rt6_info * ip6_rt_copy(str
rt->rt6i_idev = ort->rt6i_idev;
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
- rt->u.dst.lastuse = jiffies;
+ dst_lastuse_set(&rt->u.dst);
rt->rt6i_expires = 0;
ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index b93bfb8..f059cbe 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -223,7 +223,7 @@ __xfrm6_bundle_create(struct xfrm_policy
dev_hold(rt->u.dst.dev);
dst_prev->obsolete = -1;
dst_prev->flags |= DST_HOST;
- dst_prev->lastuse = jiffies;
+ dst_lastuse_set(dst_prev);
dst_prev->header_len = header_len;
dst_prev->nfheader_len = nfheader_len;
dst_prev->trailer_len = trailer_len;
prev parent reply other threads:[~2007-03-13 14:58 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-13 13:48 [PATCH] Shrink struct dst_entry a bit Andi Kleen
2007-03-13 14:10 ` Eric Dumazet
2007-03-13 14:31 ` Andi Kleen
2007-03-13 14:44 ` Eric Dumazet
2007-03-13 14:58 ` Eric Dumazet [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200703131558.10596.dada1@cosmosbay.com \
--to=dada1@cosmosbay.com \
--cc=ak@suse.de \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.