[PATCH v3 08/14] SUNRPC: stop the svc_unregister() sweep once rpcbind stops answering
From: Jeff Layton
Date: Fri Aug 28 2026 - 12:43:07 EST
svc_unregister() clears the rpcbind entry for every non-hidden program and
version. svc_rpcb_setup() runs it to drop stale entries when a serv binds,
and svc_rpcb_cleanup() runs it when one goes away. An nfsd serv with v3 and
v4 enabled sweeps four or five entries, so a local rpcbind that never
replies costs that many timeouts, twice per NFSD_CMD_LISTENER_SET, all
under nfsd_mutex.
Give up after the first call that gets no answer.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
net/sunrpc/svc.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e437e99a0b36..bccaeb8dfba8 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1277,8 +1277,8 @@ int svc_register(struct svc_serv *serv, struct net *net,
* any "inet6" entries anyway. So a PMAP_UNSET should be sufficient
* in this case to clear all existing entries for [program, version].
*/
-static void __svc_unregister(struct net *net, const u32 program, const u32 version,
- const char *progname)
+static int __svc_unregister(struct net *net, const u32 program, const u32 version,
+ const char *progname)
{
int error;
@@ -1292,6 +1292,7 @@ static void __svc_unregister(struct net *net, const u32 program, const u32 versi
error = rpcb_register(net, program, version, 0, 0);
trace_svc_unregister(progname, version, error);
+ return error;
}
/*
@@ -1318,10 +1319,13 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
continue;
if (progp->pg_vers[i]->vs_hidden)
continue;
- __svc_unregister(net, progp->pg_prog, i, progp->pg_name);
+ if (__svc_unregister(net, progp->pg_prog, i,
+ progp->pg_name) == -ENAVAIL)
+ goto out;
}
}
+out:
rcu_read_lock();
sighand = rcu_dereference(current->sighand);
spin_lock_irqsave(&sighand->siglock, flags);
--
2.55.0