diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2011-12-06 16:13:48 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-05 11:59:18 -0500 |
commit | 0aaaf5c424c7ffd6b0c4253251356558b16ef3a2 (patch) | |
tree | 8ef0eebc41a8e247d52280fd79d36934a71fcb00 /include/linux | |
parent | 414adf14cd3b52e411f79d941a15d0fd4af427fc (diff) |
NFS: Cache state owners after files are closed
Servers have a finite amount of memory to store NFSv4 open and lock
owners. Moreover, servers may have a difficult time determining when
they can reap their state owner table, thanks to gray areas in the
NFSv4 protocol specification. Thus clients should be careful to reuse
state owners when possible.
Currently Linux is not too careful. When a user has closed all her
files on one mount point, the state owner's reference count goes to
zero, and it is released. The next OPEN allocates a new one. A
workload that serially opens and closes files can run through a large
number of open owners this way.
When a state owner's reference count goes to zero, slap it onto a free
list for that nfs_server, with an expiry time. Garbage collect before
looking for a state owner. This makes state owners for active users
available for re-use.
Now that there can be unused state owners remaining at umount time,
purge the state owner free list when a server is destroyed. Also be
sure not to reclaim unused state owners during state recovery.
This change has benefits for the client as well. For some workloads,
this approach drops the number of OPEN_CONFIRM calls from the same as
the number of OPEN calls, down to just one. This reduces wire traffic
and thus open(2) latency. Before this patch, untarring a kernel
source tarball shows the OPEN_CONFIRM call counter steadily increasing
through the test. With the patch, the OPEN_CONFIRM count remains at 1
throughout the entire untar.
As long as the expiry time is kept short, I don't think garbage
collection should be terribly expensive, although it does bounce the
clp->cl_lock around a bit.
[ At some point we should rationalize the use of the nfs_server
->destroy method. ]
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
[Trond: Fixed a garbage collection race and a few efficiency issues]
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/nfs_fs_sb.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b5479df8378d..ba4d7656ecfd 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -153,6 +153,7 @@ struct nfs_server { | |||
153 | struct rb_root openowner_id; | 153 | struct rb_root openowner_id; |
154 | struct rb_root lockowner_id; | 154 | struct rb_root lockowner_id; |
155 | #endif | 155 | #endif |
156 | struct list_head state_owners_lru; | ||
156 | struct list_head layouts; | 157 | struct list_head layouts; |
157 | struct list_head delegations; | 158 | struct list_head delegations; |
158 | void (*destroy)(struct nfs_server *); | 159 | void (*destroy)(struct nfs_server *); |