diff mbox series

[v6,1/2] NFSD: keep track of the number of courtesy clients in the system

Message ID 1663085170-23136-2-git-send-email-dai.ngo@oracle.com (mailing list archive)
State New, archived
Headers show
Series NFSD: memory shrinker for NFSv4 clients | expand

Commit Message

Dai Ngo Sept. 13, 2022, 4:06 p.m. UTC
Add counter nfs4_courtesy_client_count to nfsd_net to keep track
of the number of courtesy clients in the system.

Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
---
 fs/nfsd/netns.h     |  2 ++
 fs/nfsd/nfs4state.c | 17 ++++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

Comments

Chuck Lever III Sept. 13, 2022, 11:57 p.m. UTC | #1
> On Sep 13, 2022, at 9:06 AM, Dai Ngo <dai.ngo@oracle.com> wrote:
> 
> Add counter nfs4_courtesy_client_count to nfsd_net to keep track
> of the number of courtesy clients in the system.
> 
> Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
> ---
> fs/nfsd/netns.h     |  2 ++
> fs/nfsd/nfs4state.c | 17 ++++++++++++++++-
> 2 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
> index ffe17743cc74..55c7006d6109 100644
> --- a/fs/nfsd/netns.h
> +++ b/fs/nfsd/netns.h
> @@ -192,6 +192,8 @@ struct nfsd_net {
> 
> 	atomic_t		nfs4_client_count;
> 	int			nfs4_max_clients;
> +
> +	atomic_t		nfsd_courtesy_clients;
> };
> 
> /* Simple check to find out if a given net was properly initialized */
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index c5d199d7e6b4..3af4fc5241b2 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -160,6 +160,13 @@ static bool is_client_expired(struct nfs4_client *clp)
> 	return clp->cl_time == 0;
> }
> 
> +static inline void nfsd4_decr_courtesy_client_count(struct nfsd_net *nn,
> +					struct nfs4_client *clp)

Nit: The usual naming scheme is "dec" for helpers like this
rather than "decr".

Also "inline" is not necessary here since this helper is used
only in the same source file where it is defined. The compiler
will figure out when to inline it.


> +{
> +	if (clp->cl_state != NFSD4_ACTIVE)
> +		atomic_add_unless(&nn->nfsd_courtesy_clients, -1, 0);
> +}
> +
> static __be32 get_client_locked(struct nfs4_client *clp)
> {
> 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> @@ -169,6 +176,7 @@ static __be32 get_client_locked(struct nfs4_client *clp)
> 	if (is_client_expired(clp))
> 		return nfserr_expired;
> 	atomic_inc(&clp->cl_rpc_users);
> +	nfsd4_decr_courtesy_client_count(nn, clp);
> 	clp->cl_state = NFSD4_ACTIVE;
> 	return nfs_ok;
> }
> @@ -190,6 +198,7 @@ renew_client_locked(struct nfs4_client *clp)
> 
> 	list_move_tail(&clp->cl_lru, &nn->client_lru);
> 	clp->cl_time = ktime_get_boottime_seconds();
> +	nfsd4_decr_courtesy_client_count(nn, clp);
> 	clp->cl_state = NFSD4_ACTIVE;
> }
> 
> @@ -2233,6 +2242,7 @@ __destroy_client(struct nfs4_client *clp)
> 	if (clp->cl_cb_conn.cb_xprt)
> 		svc_xprt_put(clp->cl_cb_conn.cb_xprt);
> 	atomic_add_unless(&nn->nfs4_client_count, -1, 0);
> +	nfsd4_decr_courtesy_client_count(nn, clp);
> 	free_client(clp);
> 	wake_up_all(&expiry_wq);
> }
> @@ -4356,6 +4366,8 @@ void nfsd4_init_leases_net(struct nfsd_net *nn)
> 	max_clients = (u64)si.totalram * si.mem_unit / (1024 * 1024 * 1024);
> 	max_clients *= NFS4_CLIENTS_PER_GB;
> 	nn->nfs4_max_clients = max_t(int, max_clients, NFS4_CLIENTS_PER_GB);
> +
> +	atomic_set(&nn->nfsd_courtesy_clients, 0);
> }
> 
> static void init_nfs4_replay(struct nfs4_replay *rp)
> @@ -5878,8 +5890,11 @@ nfs4_get_client_reaplist(struct nfsd_net *nn, struct list_head *reaplist,
> 			goto exp_client;
> 		if (!state_expired(lt, clp->cl_time))
> 			break;
> -		if (!atomic_read(&clp->cl_rpc_users))
> +		if (!atomic_read(&clp->cl_rpc_users)) {
> +			if (clp->cl_state == NFSD4_ACTIVE)
> +				atomic_inc(&nn->nfsd_courtesy_clients);
> 			clp->cl_state = NFSD4_COURTESY;
> +		}
> 		if (!client_has_state(clp))
> 			goto exp_client;
> 		if (!nfs4_anylock_blockers(clp))
> -- 
> 2.9.5
> 

--
Chuck Lever
diff mbox series

Patch

diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index ffe17743cc74..55c7006d6109 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -192,6 +192,8 @@  struct nfsd_net {
 
 	atomic_t		nfs4_client_count;
 	int			nfs4_max_clients;
+
+	atomic_t		nfsd_courtesy_clients;
 };
 
 /* Simple check to find out if a given net was properly initialized */
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c5d199d7e6b4..3af4fc5241b2 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -160,6 +160,13 @@  static bool is_client_expired(struct nfs4_client *clp)
 	return clp->cl_time == 0;
 }
 
+static inline void nfsd4_decr_courtesy_client_count(struct nfsd_net *nn,
+					struct nfs4_client *clp)
+{
+	if (clp->cl_state != NFSD4_ACTIVE)
+		atomic_add_unless(&nn->nfsd_courtesy_clients, -1, 0);
+}
+
 static __be32 get_client_locked(struct nfs4_client *clp)
 {
 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
@@ -169,6 +176,7 @@  static __be32 get_client_locked(struct nfs4_client *clp)
 	if (is_client_expired(clp))
 		return nfserr_expired;
 	atomic_inc(&clp->cl_rpc_users);
+	nfsd4_decr_courtesy_client_count(nn, clp);
 	clp->cl_state = NFSD4_ACTIVE;
 	return nfs_ok;
 }
@@ -190,6 +198,7 @@  renew_client_locked(struct nfs4_client *clp)
 
 	list_move_tail(&clp->cl_lru, &nn->client_lru);
 	clp->cl_time = ktime_get_boottime_seconds();
+	nfsd4_decr_courtesy_client_count(nn, clp);
 	clp->cl_state = NFSD4_ACTIVE;
 }
 
@@ -2233,6 +2242,7 @@  __destroy_client(struct nfs4_client *clp)
 	if (clp->cl_cb_conn.cb_xprt)
 		svc_xprt_put(clp->cl_cb_conn.cb_xprt);
 	atomic_add_unless(&nn->nfs4_client_count, -1, 0);
+	nfsd4_decr_courtesy_client_count(nn, clp);
 	free_client(clp);
 	wake_up_all(&expiry_wq);
 }
@@ -4356,6 +4366,8 @@  void nfsd4_init_leases_net(struct nfsd_net *nn)
 	max_clients = (u64)si.totalram * si.mem_unit / (1024 * 1024 * 1024);
 	max_clients *= NFS4_CLIENTS_PER_GB;
 	nn->nfs4_max_clients = max_t(int, max_clients, NFS4_CLIENTS_PER_GB);
+
+	atomic_set(&nn->nfsd_courtesy_clients, 0);
 }
 
 static void init_nfs4_replay(struct nfs4_replay *rp)
@@ -5878,8 +5890,11 @@  nfs4_get_client_reaplist(struct nfsd_net *nn, struct list_head *reaplist,
 			goto exp_client;
 		if (!state_expired(lt, clp->cl_time))
 			break;
-		if (!atomic_read(&clp->cl_rpc_users))
+		if (!atomic_read(&clp->cl_rpc_users)) {
+			if (clp->cl_state == NFSD4_ACTIVE)
+				atomic_inc(&nn->nfsd_courtesy_clients);
 			clp->cl_state = NFSD4_COURTESY;
+		}
 		if (!client_has_state(clp))
 			goto exp_client;
 		if (!nfs4_anylock_blockers(clp))