inetpeer: seqlock optimization
authorEric Dumazet <eric.dumazet@gmail.com>
Fri, 4 Mar 2011 22:33:59 +0000 (14:33 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 4 Mar 2011 22:33:59 +0000 (14:33 -0800)
commit65e8354ec13a45414045084166cb340c0d7ffe8a
tree3a7d8b63a3765343c07d6f878b4ef389041da6f0
parentd72751ede1b9bf993d7bd3377305c8e9e36a3cc4
inetpeer: seqlock optimization

David noticed :

------------------
Eric, I was profiling the non-routing-cache case and something that
stuck out is the case of calling inet_getpeer() with create==0.

If an entry is not found, we have to redo the lookup under a spinlock
to make certain that a concurrent writer rebalancing the tree does
not "hide" an existing entry from us.

This makes the case of a create==0 lookup for a not-present entry
really expensive.  It is on the order of 600 cpu cycles on my
Niagara2.

I added a hack to not do the relookup under the lock when create==0
and it now costs less than 300 cycles.

This is now a pretty common operation with the way we handle COW'd
metrics, so I think it's definitely worth optimizing.
-----------------

One solution is to use a seqlock instead of a spinlock to protect struct
inet_peer_base.

After a failed avl tree lookup, we can easily detect if a writer did
some changes during our lookup. Taking the lock and redo the lookup is
only necessary in this case.

Note: Add one private rcu_deref_locked() macro to place in one spot the
access to spinlock included in seqlock.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/inetpeer.c