Commit 96f817fe authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

tcp: shrink tcp6_timewait_sock by one cache line

While working on tcp listener refactoring, I found that it
would really make things easier if sock_common could include
the IPv6 addresses needed in the lookups, instead of doing
very complex games to get their values (depending on sock
being SYN_RECV, ESTABLISHED, TIME_WAIT)

For this to happen, I need to be sure that tcp6_timewait_sock
and tcp_timewait_sock consume same number of cache lines.

This is possible if we only use 32bits for tw_ttd, as we remove
one 32bit hole in inet_timewait_sock

inet_tw_time_stamp() is defined and used, even if its current
implementation looks like tcp_time_stamp : We might need finer
resolution for tcp_time_stamp in the future.

Before patch : sizeof(struct tcp6_timewait_sock) = 0xc8

After patch : sizeof(struct tcp6_timewait_sock) = 0xc0
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 40dc9ab2
...@@ -58,6 +58,11 @@ struct inet_hashinfo; ...@@ -58,6 +58,11 @@ struct inet_hashinfo;
# define INET_TWDR_RECYCLE_TICK (12 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG) # define INET_TWDR_RECYCLE_TICK (12 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#endif #endif
static inline u32 inet_tw_time_stamp(void)
{
return jiffies;
}
/* TIME_WAIT reaping mechanism. */ /* TIME_WAIT reaping mechanism. */
#define INET_TWDR_TWKILL_SLOTS 8 /* Please keep this a power of 2. */ #define INET_TWDR_TWKILL_SLOTS 8 /* Please keep this a power of 2. */
...@@ -130,7 +135,7 @@ struct inet_timewait_sock { ...@@ -130,7 +135,7 @@ struct inet_timewait_sock {
tw_tos : 8, tw_tos : 8,
tw_ipv6_offset : 16; tw_ipv6_offset : 16;
kmemcheck_bitfield_end(flags); kmemcheck_bitfield_end(flags);
unsigned long tw_ttd; u32 tw_ttd;
struct inet_bind_bucket *tw_tb; struct inet_bind_bucket *tw_tb;
struct hlist_node tw_death_node; struct hlist_node tw_death_node;
}; };
......
...@@ -222,7 +222,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, ...@@ -222,7 +222,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
u32 portid, u32 seq, u16 nlmsg_flags, u32 portid, u32 seq, u16 nlmsg_flags,
const struct nlmsghdr *unlh) const struct nlmsghdr *unlh)
{ {
long tmo; s32 tmo;
struct inet_diag_msg *r; struct inet_diag_msg *r;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
...@@ -234,7 +234,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, ...@@ -234,7 +234,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
r = nlmsg_data(nlh); r = nlmsg_data(nlh);
BUG_ON(tw->tw_state != TCP_TIME_WAIT); BUG_ON(tw->tw_state != TCP_TIME_WAIT);
tmo = tw->tw_ttd - jiffies; tmo = tw->tw_ttd - inet_tw_time_stamp();
if (tmo < 0) if (tmo < 0)
tmo = 0; tmo = 0;
...@@ -248,7 +248,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, ...@@ -248,7 +248,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
r->id.idiag_dst[0] = tw->tw_daddr; r->id.idiag_dst[0] = tw->tw_daddr;
r->idiag_state = tw->tw_substate; r->idiag_state = tw->tw_substate;
r->idiag_timer = 3; r->idiag_timer = 3;
r->idiag_expires = DIV_ROUND_UP(tmo * 1000, HZ); r->idiag_expires = jiffies_to_msecs(tmo);
r->idiag_rqueue = 0; r->idiag_rqueue = 0;
r->idiag_wqueue = 0; r->idiag_wqueue = 0;
r->idiag_uid = 0; r->idiag_uid = 0;
......
...@@ -387,11 +387,11 @@ void inet_twsk_schedule(struct inet_timewait_sock *tw, ...@@ -387,11 +387,11 @@ void inet_twsk_schedule(struct inet_timewait_sock *tw,
if (slot >= INET_TWDR_TWKILL_SLOTS) if (slot >= INET_TWDR_TWKILL_SLOTS)
slot = INET_TWDR_TWKILL_SLOTS - 1; slot = INET_TWDR_TWKILL_SLOTS - 1;
} }
tw->tw_ttd = jiffies + timeo; tw->tw_ttd = inet_tw_time_stamp() + timeo;
slot = (twdr->slot + slot) & (INET_TWDR_TWKILL_SLOTS - 1); slot = (twdr->slot + slot) & (INET_TWDR_TWKILL_SLOTS - 1);
list = &twdr->cells[slot]; list = &twdr->cells[slot];
} else { } else {
tw->tw_ttd = jiffies + (slot << INET_TWDR_RECYCLE_TICK); tw->tw_ttd = inet_tw_time_stamp() + (slot << INET_TWDR_RECYCLE_TICK);
if (twdr->twcal_hand < 0) { if (twdr->twcal_hand < 0) {
twdr->twcal_hand = 0; twdr->twcal_hand = 0;
......
...@@ -1811,7 +1811,7 @@ static void get_timewait6_sock(struct seq_file *seq, ...@@ -1811,7 +1811,7 @@ static void get_timewait6_sock(struct seq_file *seq,
const struct in6_addr *dest, *src; const struct in6_addr *dest, *src;
__u16 destp, srcp; __u16 destp, srcp;
const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw); const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
long delta = tw->tw_ttd - jiffies; s32 delta = tw->tw_ttd - inet_tw_time_stamp();
dest = &tw6->tw_v6_daddr; dest = &tw6->tw_v6_daddr;
src = &tw6->tw_v6_rcv_saddr; src = &tw6->tw_v6_rcv_saddr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment