tcp: Fix slowness in read /proc/net/tcp
authorTom Herbert <therbert@google.com>
Mon, 7 Jun 2010 07:43:42 +0000 (00:43 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 7 Jun 2010 07:43:42 +0000 (00:43 -0700)
commita8b690f98baf9fb1902b8eeab801351ea603fa3a
treeb48940354a3236d33e33ca4f1b9169c9545cd551
parent83038a2a7062f6cbbdcfaff47284566f060a5af1
tcp: Fix slowness in read /proc/net/tcp

This patch address a serious performance issue in reading the
TCP sockets table (/proc/net/tcp).

Reading the full table is done by a number of sequential read
operations.  At each read operation, a seek is done to find the
last socket that was previously read.  This seek operation requires
that the sockets in the table need to be counted up to the current
file position, and to count each of these requires taking a lock for
each non-empty bucket.  The whole algorithm is O(n^2).

The fix is to cache the last bucket value, offset within the bucket,
and the file position returned by the last read operation.   On the
next sequential read, the bucket and offset are used to find the
last read socket immediately without needing ot scan the previous
buckets  the table.  This algorithm t read the whole table is O(n).

The improvement offered by this patch is easily show by performing
cat'ing /proc/net/tcp on a machine with a lot of connections.  With
about 182K connections in the table, I see the following:

- Without patch
time cat /proc/net/tcp > /dev/null

real 1m56.729s
user 0m0.214s
sys 1m56.344s

- With patch
time cat /proc/net/tcp > /dev/null

real 0m0.894s
user 0m0.290s
sys 0m0.594s

Signed-off-by: Tom Herbert <therbert@google.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tcp.h
net/ipv4/tcp_ipv4.c