diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index e56c4814822..ed147602bbe 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1334,11 +1334,11 @@ sysctl_root(SYSCTL_HANDLER_ARGS) if (error != 0) return (error); #endif - - /* XXX: Handlers are not guaranteed to be Giant safe! */ - mtx_lock(&Giant); + if (!(oid->oid_kind & CTLFLAG_MPSAFE)) + mtx_lock(&Giant); error = oid->oid_handler(oid, arg1, arg2, req); - mtx_unlock(&Giant); + if (!(oid->oid_kind & CTLFLAG_MPSAFE)) + mtx_unlock(&Giant); return (error); } diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index a92f190bc9c..40e9dc8976c 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -84,6 +84,7 @@ struct ctlname { #define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */ #define CTLMASK_SECURE 0x00F00000 /* Secure level */ #define CTLFLAG_TUN 0x00080000 /* Tunable variable */ +#define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */ #define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN) /*