1
linux/net/sched
Eric Dumazet 81c3d5470e [INET]: speedup inet (tcp/dccp) lookups
Arnaldo and I agreed it could be applied now, because I have other
pending patches depending on this one (Thank you Arnaldo)

(The other important patch moves skc_refcnt in a separate cache line,
so that the SMP/NUMA performance doesnt suffer from cache line ping pongs)

1) First some performance data :
--------------------------------

tcp_v4_rcv() wastes a *lot* of time in __inet_lookup_established()

The most time critical code is :

sk_for_each(sk, node, &head->chain) {
     if (INET_MATCH(sk, acookie, saddr, daddr, ports, dif))
         goto hit; /* You sunk my battleship! */
}

The sk_for_each() does use prefetch() hints but only the begining of
"struct sock" is prefetched.

As INET_MATCH first comparison uses inet_sk(__sk)->daddr, wich is far
away from the begining of "struct sock", it has to bring into CPU
cache cold cache line. Each iteration has to use at least 2 cache
lines.

This can be problematic if some chains are very long.

2) The goal
-----------

The idea I had is to change things so that INET_MATCH() may return
FALSE in 99% of cases only using the data already in the CPU cache,
using one cache line per iteration.

3) Description of the patch
---------------------------

Adds a new 'unsigned int skc_hash' field in 'struct sock_common',
filling a 32 bits hole on 64 bits platform.

struct sock_common {
	unsigned short		skc_family;
	volatile unsigned char	skc_state;
	unsigned char		skc_reuse;
	int			skc_bound_dev_if;
	struct hlist_node	skc_node;
	struct hlist_node	skc_bind_node;
	atomic_t		skc_refcnt;
+	unsigned int		skc_hash;
	struct proto		*skc_prot;
};

Store in this 32 bits field the full hash, not masked by (ehash_size -
1) Using this full hash as the first comparison done in INET_MATCH
permits us immediatly skip the element without touching a second cache
line in case of a miss.

Suppress the sk_hashent/tw_hashent fields since skc_hash (aliased to
sk_hash and tw_hash) already contains the slot number if we mask with
(ehash_size - 1)

File include/net/inet_hashtables.h

64 bits platforms :
#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
     (((__sk)->sk_hash == (__hash))
     ((*((__u64 *)&(inet_sk(__sk)->daddr)))== (__cookie))   &&  \
     ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports))   &&  \
     (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))

32bits platforms:
#define TCP_IPV4_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
     (((__sk)->sk_hash == (__hash))                 &&  \
     (inet_sk(__sk)->daddr          == (__saddr))   &&  \
     (inet_sk(__sk)->rcv_saddr      == (__daddr))   &&  \
     (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))


- Adds a prefetch(head->chain.first) in 
__inet_lookup_established()/__tcp_v4_check_established() and 
__inet6_lookup_established()/__tcp_v6_check_established() and 
__dccp_v4_check_established() to bring into cache the first element of the 
list, before the {read|write}_lock(&head->lock);

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Acked-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2005-10-03 14:13:38 -07:00
..
act_api.c [NETLINK]: Convert netlink users to use group numbers instead of bitmasks 2005-08-29 16:00:54 -07:00
cls_api.c [NETLINK]: Convert netlink users to use group numbers instead of bitmasks 2005-08-29 16:00:54 -07:00
cls_basic.c [PKT_SCHED]: Dump classification result for basic classifier 2005-06-08 15:11:02 -07:00
cls_fw.c [PKT_SCHED]: improve hashing performance of cls_fw 2005-04-24 20:19:54 -07:00
cls_route.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cls_rsvp6.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cls_rsvp.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cls_rsvp.h [NETLINK]: Missing padding fields in dumped structures 2005-06-28 12:56:45 -07:00
cls_tcindex.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cls_u32.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
em_cmp.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
em_meta.c [INET]: speedup inet (tcp/dccp) lookups 2005-10-03 14:13:38 -07:00
em_nbyte.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
em_text.c [PKT_SCHED]: Remove debugging leftover from textsearch ematch 2005-07-18 13:29:49 -07:00
em_u32.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ematch.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
estimator.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
gact.c [NET]: Kill skb->tc_classid 2005-08-29 15:31:18 -07:00
ipt.c [NET]: Kill skb->tc_classid 2005-08-29 15:31:18 -07:00
Kconfig [LIB]: Make TEXTSEARCH_BM plain tristate like the others 2005-08-29 16:11:11 -07:00
Makefile [PKT_SCHED]: Blackhole queueing discipline 2005-07-05 15:29:16 -07:00
mirred.c [NET]: Kill skb->tc_classid 2005-08-29 15:31:18 -07:00
pedit.c [NET]: Kill skb->tc_classid 2005-08-29 15:31:18 -07:00
police.c [NET]: Kill skb->tc_classid 2005-08-29 15:31:18 -07:00
sch_api.c [PATCH] timer initialization cleanup: DEFINE_TIMER 2005-09-09 14:03:48 -07:00
sch_atm.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sch_blackhole.c [PKT_SCHED]: Blackhole queueing discipline 2005-07-05 15:29:16 -07:00
sch_cbq.c [NETLINK]: Missing padding fields in dumped structures 2005-06-28 12:56:45 -07:00
sch_dsmark.c [PKT_SCHED]: Logic simplifications and codingstyle/whitespace cleanups 2005-06-18 22:53:29 -07:00
sch_fifo.c [PKT_SCHED]: Cleanup fifo qdisc and remove unnecessary code 2005-06-18 22:58:00 -07:00
sch_generic.c [NET]: Deinline netif_carrier_{on,off}(). 2005-08-29 15:57:08 -07:00
sch_gred.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sch_hfsc.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sch_htb.c [PKT_SCHED]: HTB: Drop packet when direct queue is full 2005-05-03 14:39:33 -07:00
sch_ingress.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sch_netem.c [PKT_SCHED] netem: allow random reordering (with fix) 2005-05-26 12:55:48 -07:00
sch_prio.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sch_red.c [NET]: Transform skb_queue_len() binary tests into skb_queue_empty() 2005-07-08 14:57:23 -07:00
sch_sfq.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sch_tbf.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sch_teql.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
simple.c [NET]: Kill skb->tc_classid 2005-08-29 15:31:18 -07:00