NFSD: Use rhashtable for managing nfs4_file objects
authorChuck Lever <chuck.lever@oracle.com>
Fri, 28 Oct 2022 14:47:53 +0000 (10:47 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 28 Nov 2022 17:54:47 +0000 (12:54 -0500)
commitd47b295e8d76a4d69f0e2ea0cd8a79c9d3488280
treef535161ba82c46365ff92eb001e2bef1ae39f740
parent15424748001a9b5ea62b3e6ad45f0a8b27f01df9
NFSD: Use rhashtable for managing nfs4_file objects

fh_match() is costly, especially when filehandles are large (as is
the case for NFSv4). It needs to be used sparingly when searching
data structures. Unfortunately, with common workloads, I see
multiple thousands of objects stored in file_hashtbl[], which has
just 256 buckets, making its bucket hash chains quite lengthy.

Walking long hash chains with the state_lock held blocks other
activity that needs that lock. Sizable hash chains are a common
occurrance once the server has handed out some delegations, for
example -- IIUC, each delegated file is held open on the server by
an nfs4_file object.

To help mitigate the cost of searching with fh_match(), replace the
nfs4_file hash table with an rhashtable, which can dynamically
resize its bucket array to minimize hash chain length.

The result of this modification is an improvement in the latency of
NFSv4 operations, and the reduction of nfsd CPU utilization due to
eliminating the cost of multiple calls to fh_match() and reducing
the CPU cache misses incurred while walking long hash chains in the
nfs4_file hash table.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: NeilBrown <neilb@suse.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
fs/nfsd/nfs4state.c
fs/nfsd/state.h