summaryrefslogtreecommitdiff
path: root/fs/nfsd/state.h
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2022-10-28 10:47:53 -0400
committerChuck Lever <chuck.lever@oracle.com>2022-11-28 12:54:47 -0500
commitd47b295e8d76a4d69f0e2ea0cd8a79c9d3488280 (patch)
treef535161ba82c46365ff92eb001e2bef1ae39f740 /fs/nfsd/state.h
parent15424748001a9b5ea62b3e6ad45f0a8b27f01df9 (diff)
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>
Diffstat (limited to 'fs/nfsd/state.h')
-rw-r--r--fs/nfsd/state.h5
1 files changed, 1 insertions, 4 deletions
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index e2daef3cc003..eadd7f465bf5 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -536,16 +536,13 @@ struct nfs4_clnt_odstate {
* inode can have multiple filehandles associated with it, so there is
* (potentially) a many to one relationship between this struct and struct
* inode.
- *
- * These are hashed by filehandle in the file_hashtbl, which is protected by
- * the global state_lock spinlock.
*/
struct nfs4_file {
refcount_t fi_ref;
struct inode * fi_inode;
bool fi_aliased;
spinlock_t fi_lock;
- struct hlist_node fi_hash; /* hash on fi_fhandle */
+ struct rhlist_head fi_rlist;
struct list_head fi_stateids;
union {
struct list_head fi_delegations;