vfs: Fix pathological performance case for __alloc_fd()
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Oct 2015 23:53:57 +0000 (16:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 31 Oct 2015 23:12:10 +0000 (16:12 -0700)
commitf3f86e33dc3da437fa4f204588ce7c78ea756982
treeb74105990139f8102016b786bff0e29768ef7828
parent8a28d67457b613258aa0578ccece206d166f2b9f
vfs: Fix pathological performance case for __alloc_fd()

Al Viro points out that:
> >     * [Linux-specific aside] our __alloc_fd() can degrade quite badly
> > with some use patterns.  The cacheline pingpong in the bitmap is probably
> > inevitable, unless we accept considerably heavier memory footprint,
> > but we also have a case when alloc_fd() takes O(n) and it's _not_ hard
> > to trigger - close(3);open(...); will have the next open() after that
> > scanning the entire in-use bitmap.

And Eric Dumazet has a somewhat realistic multithreaded microbenchmark
that opens and closes a lot of sockets with minimal work per socket.

This patch largely fixes it.  We keep a 2nd-level bitmap of the open
file bitmaps, showing which words are already full.  So then we can
traverse that second-level bitmap to efficiently skip already allocated
file descriptors.

On his benchmark, this improves performance by up to an order of
magnitude, by avoiding the excessive open file bitmap scanning.

Tested-and-acked-by: Eric Dumazet <edumazet@google.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/file.c
include/linux/fdtable.h