LAKITU: NFS: do not clear the file access cache upon login by default
Commit 0eb43812c027 ("NFS: Clear the file access cache upon login")
causes the file access cache to be cleared on every `docker exec`. This
is a performance regression for some workloads. Since clearing the cache
solves real problems, put that functionality behind a module parameter
(Ubuntu implemented this parameter in GKE).
BUG=b/427144804
TEST=presubmit
RELEASE_NOTE=The NFS access cache is no longer cleared on login by default. To use the old behavior, load the NFS module with the `nfs_fasc=1` module parameter.
Change-Id: I2e5ee568d240bb41afd0f577979e158b70fe3e1c
Signed-off-by: Robert Kolchmeyer <rkolchmeyer@google.com>
Reviewed-on: https://cos-review.googlesource.com/c/third_party/kernel/+/107400
Reviewed-by: Kevin Berry <kpberry@google.com>
Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f9f4a92..376aacf 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2847,6 +2847,10 @@ static DEFINE_SPINLOCK(nfs_access_lru_lock);
static LIST_HEAD(nfs_access_lru_list);
static atomic_long_t nfs_access_nr_entries;
+static bool nfs_fasc = false;
+module_param(nfs_fasc, bool, 0644);
+MODULE_PARM_DESC(nfs_fasc, "Use file access stale cache for NFS");
+
static unsigned long nfs_access_max_cachesize = 4*1024*1024;
module_param(nfs_access_max_cachesize, ulong, 0644);
MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache length");
@@ -3058,7 +3062,9 @@ static u64 nfs_access_login_time(const struct task_struct *task,
static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, u32 *mask, bool may_block)
{
struct nfs_inode *nfsi = NFS_I(inode);
- u64 login_time = nfs_access_login_time(current, cred);
+ u64 login_time;
+ if (nfs_fasc)
+ login_time = nfs_access_login_time(current, cred);
struct nfs_access_entry *cache;
bool retry = true;
int err;
@@ -3086,9 +3092,11 @@ static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *
spin_lock(&inode->i_lock);
retry = false;
}
- err = -ENOENT;
- if ((s64)(login_time - cache->timestamp) > 0)
- goto out;
+ if (nfs_fasc) {
+ err = -ENOENT;
+ if ((s64)(login_time - cache->timestamp) > 0)
+ goto out;
+ }
*mask = cache->mask;
list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru);
err = 0;
@@ -3107,7 +3115,9 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
* but do it without locking.
*/
struct nfs_inode *nfsi = NFS_I(inode);
- u64 login_time = nfs_access_login_time(current, cred);
+ u64 login_time;
+ if (nfs_fasc)
+ login_time = nfs_access_login_time(current, cred);
struct nfs_access_entry *cache;
int err = -ECHILD;
struct list_head *lh;
@@ -3122,8 +3132,10 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
cache = NULL;
if (cache == NULL)
goto out;
- if ((s64)(login_time - cache->timestamp) > 0)
- goto out;
+ if (nfs_fasc) {
+ if ((s64)(login_time - cache->timestamp) > 0)
+ goto out;
+ }
if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
goto out;
*mask = cache->mask;
@@ -3195,7 +3207,8 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set,
cache->fsgid = cred->fsgid;
cache->group_info = get_group_info(cred->group_info);
cache->mask = set->mask;
- cache->timestamp = ktime_get_ns();
+ if (nfs_fasc)
+ cache->timestamp = ktime_get_ns();
/* The above field assignments must be visible
* before this item appears on the lru. We cannot easily