net: use a per task frag allocator
authorEric Dumazet <edumazet@google.com>
Sun, 23 Sep 2012 23:04:42 +0000 (23:04 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 24 Sep 2012 20:31:37 +0000 (16:31 -0400)
commit5640f7685831e088fe6c2e1f863a6805962f8e81
treefb7660173338a45c27d610eb59ba20cf5c2b91b8
parentb98b8babd6e3370fadb7c6eaacb00eb2f6344a6c
net: use a per task frag allocator

We currently use a per socket order-0 page cache for tcp_sendmsg()
operations.

This page is used to build fragments for skbs.

Its done to increase probability of coalescing small write() into
single segments in skbs still in write queue (not yet sent)

But it wastes a lot of memory for applications handling many mostly
idle sockets, since each socket holds one page in sk->sk_sndmsg_page

Its also quite inefficient to build TSO 64KB packets, because we need
about 16 pages per skb on arches where PAGE_SIZE = 4096, so we hit
page allocator more than wanted.

This patch adds a per task frag allocator and uses bigger pages,
if available. An automatic fallback is done in case of memory pressure.

(up to 32768 bytes per frag, thats order-3 pages on x86)

This increases TCP stream performance by 20% on loopback device,
but also benefits on other network devices, since 8x less frags are
mapped on transmit and unmapped on tx completion. Alexander Duyck
mentioned a probable performance win on systems with IOMMU enabled.

Its possible some SG enabled hardware cant cope with bigger fragments,
but their ndo_start_xmit() should already handle this, splitting a
fragment in sub fragments, since some arches have PAGE_SIZE=65536

Successfully tested on various ethernet devices.
(ixgbe, igb, bnx2x, tg3, mellanox mlx4)

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Vijay Subramanian <subramanian.vijay@gmail.com>
Cc: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Vijay Subramanian <subramanian.vijay@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
13 files changed:
include/linux/sched.h
include/net/inet_sock.h
include/net/sock.h
kernel/exit.c
kernel/fork.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/ip_output.c
net/ipv4/raw.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv6/ip6_output.c
net/sched/em_meta.c