Re: [PATCH] SUNRPC: Load the GSS module by OID only when the mechanism is missing

From: Jeff Layton

Date: Tue Nov 10 2026 - 07:43:26 EST


On Mon, 2026-11-09 at 22:09 -0500, Sasha Levin wrote:
> gss_mech_get_by_OID() calls request_module() before it looks at the
> list of registered mechanisms, so every lookup forks a modprobe, even
> when the mechanism is already registered or built in.
> gss_mech_get_by_name() and gss_mech_get_by_pseudoflavor() only load
> the module when the lookup fails.
>
> The read handler of /proc/net/rpc/gss_krb5_enctypes uses this lookup,
> so every read() of that file runs modprobe, two per cat. The file is
> present in every /proc/<pid>/net/rpc and /proc/<pid>/task/<tid>/net/rpc
> directory, and LTP read_all gives each read one second. On a slow board
> in KernelCI its workers stall on this file and the test times out.
>
> Look up the mechanism first and call request_module() only when it is
> not found, as the other two lookup functions do.
>
> Reported-by: kernelci.org bot <bot@xxxxxxxxxxxx>
> Closes: https://d.kernelci.org/test/maestro:6af225865b429d354e253b9b
> Fixes: f783288f0cf4 ("SUNRPC: Load GSS kernel module by OID")
> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
> ---
> net/sunrpc/auth_gss/gss_mech_switch.c | 23 +++++++++++++++++------
> 1 file changed, 17 insertions(+), 6 deletions(-)
>
> diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
> index 78eab245f94a7..d8b6ff9505399 100644
> --- a/net/sunrpc/auth_gss/gss_mech_switch.c
> +++ b/net/sunrpc/auth_gss/gss_mech_switch.c
> @@ -157,14 +157,9 @@ struct gss_api_mech * gss_mech_get_by_name(const char *name)
> return gm;
> }
>
> -struct gss_api_mech *gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
> +static struct gss_api_mech *_gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
> {
> struct gss_api_mech *pos, *gm = NULL;
> - char buf[32];
> -
> - if (sprint_oid(obj->data, obj->len, buf, sizeof(buf)) < 0)
> - return NULL;
> - request_module("rpc-auth-gss-%s", buf);
>
> rcu_read_lock();
> list_for_each_entry_rcu(pos, &registered_mechs, gm_list) {
> @@ -177,6 +172,22 @@ struct gss_api_mech *gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
> }
> }
> rcu_read_unlock();
> + return gm;
> +}
> +
> +struct gss_api_mech *gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
> +{
> + struct gss_api_mech *gm;
> + char buf[32];
> +
> + if (sprint_oid(obj->data, obj->len, buf, sizeof(buf)) < 0)
> + return NULL;
> +
> + gm = _gss_mech_get_by_OID(obj);
> + if (!gm) {
> + request_module("rpc-auth-gss-%s", buf);
> + gm = _gss_mech_get_by_OID(obj);
> + }
> if (!gm)
> trace_rpcgss_oid_to_mech(buf);
> return gm;

Nice catch!

Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>