mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
NFSD: Count delegations per network namespace
The state shrinker is allocated per network namespace, but nfsd4_state_shrinker_count() reports num_delegations, which counts the delegations held by the whole host. Every namespace therefore reports every delegation on the server. Reclaim sees the population multiplied by the number of namespaces running NFSD. A namespace holding no delegations of its own still reports a nonzero count and queues its reaper, which then finds nothing to recall. Count the delegations in each namespace and report that instead. num_delegations stays for the admission check in __alloc_init_deleg() and the ceiling check in nfs4_laundromat(). Both compare against max_delegations, which is sized from host memory and so remains a host-wide limit. Reviewed-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260817-recall-any-keep-count-v5-5-3b2cffce701e@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
parent
9af39c0773
commit
dda5168447
|
|
@ -238,6 +238,8 @@ struct nfsd_net {
|
|||
int nfs4_max_clients;
|
||||
|
||||
atomic_t nfsd_courtesy_clients;
|
||||
/* per-namespace; num_delegations in nfs4state.c is host-wide */
|
||||
atomic_long_t nfsd_delegations;
|
||||
struct shrinker *nfsd_client_shrinker;
|
||||
struct work_struct nfsd_shrinker_work;
|
||||
|
||||
|
|
|
|||
|
|
@ -1161,6 +1161,7 @@ static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
|
|||
*/
|
||||
static void nfs4_free_deleg(struct nfs4_stid *stid)
|
||||
{
|
||||
struct nfsd_net *nn = net_generic(stid->sc_client->net, nfsd_net_id);
|
||||
struct nfs4_delegation *dp = delegstateid(stid);
|
||||
|
||||
WARN_ON_ONCE(!list_empty(&stid->sc_cp_list));
|
||||
|
|
@ -1171,6 +1172,7 @@ static void nfs4_free_deleg(struct nfs4_stid *stid)
|
|||
nfsd41_cb_destroy_referring_call_list(&dp->dl_recall);
|
||||
kmem_cache_free(deleg_slab, stid);
|
||||
atomic_long_dec(&num_delegations);
|
||||
atomic_long_dec(&nn->nfsd_delegations);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1255,6 +1257,7 @@ __alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp,
|
|||
struct nfs4_clnt_odstate *odstate, u32 dl_type,
|
||||
void (*sc_free)(struct nfs4_stid *))
|
||||
{
|
||||
struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
|
||||
struct nfs4_delegation *dp;
|
||||
struct nfs4_stid *stid;
|
||||
long n;
|
||||
|
|
@ -1263,6 +1266,7 @@ __alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp,
|
|||
return NULL;
|
||||
|
||||
n = atomic_long_inc_return(&num_delegations);
|
||||
atomic_long_inc(&nn->nfsd_delegations);
|
||||
if (n < 0 || n > max_delegations)
|
||||
goto out_dec;
|
||||
|
||||
|
|
@ -1295,6 +1299,7 @@ __alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp,
|
|||
return dp;
|
||||
out_dec:
|
||||
atomic_long_dec(&num_delegations);
|
||||
atomic_long_dec(&nn->nfsd_delegations);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -5581,7 +5586,7 @@ nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control *sc)
|
|||
|
||||
count = atomic_read(&nn->nfsd_courtesy_clients);
|
||||
if (!count)
|
||||
count = atomic_long_read(&num_delegations);
|
||||
count = atomic_long_read(&nn->nfsd_delegations);
|
||||
if (count)
|
||||
queue_work(laundry_wq, &nn->nfsd_shrinker_work);
|
||||
return (unsigned long)count;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user