Skip to contentSkip to conversation

nfsd: Replace clamp_t in nfsd4_get_drc_mem()

PATCH In review Chuck Lever 3 participants 4 messages Nov 14, 2025 – Dec 2, 2025

Subsystems (3)
lore
Share & tools
lore

Chuck Lever

author maintainer
#0 lore raw

PATCH 1/1 nfsd: Replace clamp_t in nfsd4_get_drc_mem()

From: NeilBrown <[email protected]>

A recent change to clamp_t() in 6.1.y caused fs/nfsd/nfs4state.c to fail to compile with gcc-9. The code in nfsd4_get_drc_mem() was written with the assumption that when "max < min",

clamp(val, min, max)

would return max. This assumption is not documented as an API promise and the change caused a compile failure if it could be statically determined that "max < min".

The relevant code was no longer present upstream when commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()") landed there, so there is no upstream change to nfsd4_get_drc_mem() to backport.

There is no clear case that the existing code in nfsd4_get_drc_mem() is functioning incorrectly. The goal of this patch is to permit the clean application of commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()"), and any commits that depend on it, to LTS kernels without affecting the ability to compile those kernels. This is done by open-coding the __clamp() macro sans the built-in type checking.

Stable-dep-of: 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()")

---
 fs/nfsd/nfs4state.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Changes since Neil's post:
* Editorial changes to the commit message
* Attempt to address David's review comments
* Applied to linux-6.12.y, passed NFSD upstream CI suite

This patch is intended to be applied to linux-6.12.y, and should apply cleanly to other LTS kernels since nfsd4_get_drc_mem hasn't changed since v5.4.

fs/nfsd/nfs4state.c +4 -2
index 7b0fabf8c657..41545933dd18 100644
@@ -1983,8 +1983,10 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn
 	 */
 	scale_factor = max_t(unsigned int, 8, nn->nfsd_serv->sv_nrthreads);
 
-	avail = clamp_t(unsigned long, avail, slotsize,
-			total_avail/scale_factor);
+	if (avail > total_avail / scale_factor)
+		avail = total_avail / scale_factor;
+	else if (avail < slotsize)
+		avail = slotsize;
 	num = min_t(int, num, avail / slotsize);
 	num = max_t(int, num, 1);
 	nfsd_drc_mem_used += num * slotsize;
Signature · 1 line
2.51.0
#1 lore raw
Quoted 24 lines · On Fri, 14 Nov 2025 16:19:22 -0500 Chuck Lever <[email protected]> wrote:

From: NeilBrown <[email protected]>

A recent change to clamp_t() in 6.1.y caused fs/nfsd/nfs4state.c to fail to compile with gcc-9. The code in nfsd4_get_drc_mem() was written with the assumption that when "max < min",

clamp(val, min, max)

would return max. This assumption is not documented as an API promise and the change caused a compile failure if it could be statically determined that "max < min".

The relevant code was no longer present upstream when commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()") landed there, so there is no upstream change to nfsd4_get_drc_mem() to backport.

There is no clear case that the existing code in nfsd4_get_drc_mem() is functioning incorrectly. The goal of this patch is to permit the clean application of commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()"), and any commits that depend on it, to LTS kernels without affecting the ability to compile those kernels. This is done by open-coding the __clamp() macro sans the built-in type checking.

Quoted 4 lines

Stable-dep-of: 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()")

Reviewed_by: David Laight <[email protected]>

Quoted 30 lines
---
 fs/nfsd/nfs4state.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Changes since Neil's post:
* Editorial changes to the commit message
* Attempt to address David's review comments
* Applied to linux-6.12.y, passed NFSD upstream CI suite

This patch is intended to be applied to linux-6.12.y, and should apply cleanly to other LTS kernels since nfsd4_get_drc_mem hasn't changed since v5.4.

fs/nfsd/nfs4state.c +4 -2
index 7b0fabf8c657..41545933dd18 100644
@@ -1983,8 +1983,10 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn
 	 */
 	scale_factor = max_t(unsigned int, 8, nn->nfsd_serv->sv_nrthreads);
 
-	avail = clamp_t(unsigned long, avail, slotsize,
-			total_avail/scale_factor);
+	if (avail > total_avail / scale_factor)
+		avail = total_avail / scale_factor;
+	else if (avail < slotsize)
+		avail = slotsize;
 	num = min_t(int, num, avail / slotsize);
 	num = max_t(int, num, 1);
 	nfsd_drc_mem_used += num * slotsize;
author maintainer
#2 lore raw
In reply to Chuck Lever
Quoted 48 lines · Chuck Lever

From: NeilBrown <[email protected]>

A recent change to clamp_t() in 6.1.y caused fs/nfsd/nfs4state.c to fail to compile with gcc-9. The code in nfsd4_get_drc_mem() was written with the assumption that when "max < min",

clamp(val, min, max)

would return max. This assumption is not documented as an API promise and the change caused a compile failure if it could be statically determined that "max < min".

The relevant code was no longer present upstream when commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()") landed there, so there is no upstream change to nfsd4_get_drc_mem() to backport.

There is no clear case that the existing code in nfsd4_get_drc_mem() is functioning incorrectly. The goal of this patch is to permit the clean application of commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()"), and any commits that depend on it, to LTS kernels without affecting the ability to compile those kernels. This is done by open-coding the __clamp() macro sans the built-in type checking.

Stable-dep-of: 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()")

---
 fs/nfsd/nfs4state.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Changes since Neil's post:
* Editorial changes to the commit message
* Attempt to address David's review comments
* Applied to linux-6.12.y, passed NFSD upstream CI suite

This patch is intended to be applied to linux-6.12.y, and should apply cleanly to other LTS kernels since nfsd4_get_drc_mem hasn't changed since v5.4.

fs/nfsd/nfs4state.c +0 -0
index 7b0fabf8c657..41545933dd18 100644
@@ -1983,8 +1983,10 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn
 	 */
 	scale_factor = max_t(unsigned int, 8, nn->nfsd_serv->sv_nrthreads);

fs/nfsd/nfs4state.c static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn · line 1992

Quoted 10 lines
fs/nfsd/nfs4state.c +4 -2
 
-	avail = clamp_t(unsigned long, avail, slotsize,
-			total_avail/scale_factor);
+	if (avail > total_avail / scale_factor)
+		avail = total_avail / scale_factor;
+	else if (avail < slotsize)
+		avail = slotsize;
 	num = min_t(int, num, avail / slotsize);
 	num = max_t(int, num, 1);
 	nfsd_drc_mem_used += num * slotsize;

Is something else needed from me to get this applied to v6.12 and older LTS kernels?

Signature · 1 line
Chuck Lever
maintainer
#3 lore raw
Quoted 50 lines · Chuck Lever
Quoted 49 lines · Chuck Lever

From: NeilBrown <[email protected]>

A recent change to clamp_t() in 6.1.y caused fs/nfsd/nfs4state.c to fail to compile with gcc-9. The code in nfsd4_get_drc_mem() was written with the assumption that when "max < min",

clamp(val, min, max)

would return max. This assumption is not documented as an API promise and the change caused a compile failure if it could be statically determined that "max < min".

The relevant code was no longer present upstream when commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()") landed there, so there is no upstream change to nfsd4_get_drc_mem() to backport.

There is no clear case that the existing code in nfsd4_get_drc_mem() is functioning incorrectly. The goal of this patch is to permit the clean application of commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()"), and any commits that depend on it, to LTS kernels without affecting the ability to compile those kernels. This is done by open-coding the __clamp() macro sans the built-in type checking.

Stable-dep-of: 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()")

---
 fs/nfsd/nfs4state.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Changes since Neil's post:
* Editorial changes to the commit message
* Attempt to address David's review comments
* Applied to linux-6.12.y, passed NFSD upstream CI suite

This patch is intended to be applied to linux-6.12.y, and should apply cleanly to other LTS kernels since nfsd4_get_drc_mem hasn't changed since v5.4.

fs/nfsd/nfs4state.c +0 -0
index 7b0fabf8c657..41545933dd18 100644
@@ -1983,8 +1983,10 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn
 	 */
 	scale_factor = max_t(unsigned int, 8, nn->nfsd_serv->sv_nrthreads);
 
Quoted 12 lines

fs/nfsd/nfs4state.c static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn · line 1992

Quoted 9 lines
fs/nfsd/nfs4state.c +4 -2
-	avail = clamp_t(unsigned long, avail, slotsize,
-			total_avail/scale_factor);
+	if (avail > total_avail / scale_factor)
+		avail = total_avail / scale_factor;
+	else if (avail < slotsize)
+		avail = slotsize;
 	num = min_t(int, num, avail / slotsize);
 	num = max_t(int, num, 1);
 	nfsd_drc_mem_used += num * slotsize;

Is something else needed from me to get this applied to v6.12 and older LTS kernels?

Oops, sorry about that, now queued up.

greg k-h