linker_kldload_busy(): allow recursion
Some drivers recursively loads modules by explicit calls to kldload during initialization, which might occur during kldload. PR: 259748 Reported and tested by: thj Reviewed by: markj Sponsored by: Nvidia networking MFC after: 1 week Differential revision: https://reviews.freebsd.org/D32972
This commit is contained in:
parent
dad71022bd
commit
4f924a786a
@ -106,7 +106,8 @@ MALLOC_DEFINE(M_LINKER, "linker", "kernel linker");
|
||||
linker_file_t linker_kernel_file;
|
||||
|
||||
static struct sx kld_sx; /* kernel linker lock */
|
||||
static bool kld_busy;
|
||||
static u_int kld_busy;
|
||||
static struct thread *kld_busy_owner;
|
||||
|
||||
/*
|
||||
* Load counter used by clients to determine if a linker file has been
|
||||
@ -1065,7 +1066,9 @@ linker_kldload_busy(int flags)
|
||||
|
||||
if ((flags & LINKER_UB_LOCKED) == 0)
|
||||
sx_xlock(&kld_sx);
|
||||
while (kld_busy) {
|
||||
while (kld_busy > 0) {
|
||||
if (kld_busy_owner == curthread)
|
||||
break;
|
||||
error = sx_sleep(&kld_busy, &kld_sx,
|
||||
(flags & LINKER_UB_PCATCH) != 0 ? PCATCH : 0,
|
||||
"kldbusy", 0);
|
||||
@ -1075,7 +1078,8 @@ linker_kldload_busy(int flags)
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
kld_busy = true;
|
||||
kld_busy++;
|
||||
kld_busy_owner = curthread;
|
||||
if ((flags & LINKER_UB_UNLOCK) != 0)
|
||||
sx_xunlock(&kld_sx);
|
||||
return (0);
|
||||
@ -1090,9 +1094,15 @@ linker_kldload_unbusy(int flags)
|
||||
|
||||
if ((flags & LINKER_UB_LOCKED) == 0)
|
||||
sx_xlock(&kld_sx);
|
||||
MPASS(kld_busy);
|
||||
kld_busy = false;
|
||||
wakeup(&kld_busy);
|
||||
MPASS(kld_busy > 0);
|
||||
if (kld_busy_owner != curthread)
|
||||
panic("linker_kldload_unbusy done by not owning thread %p",
|
||||
kld_busy_owner);
|
||||
kld_busy--;
|
||||
if (kld_busy == 0) {
|
||||
kld_busy_owner = NULL;
|
||||
wakeup(&kld_busy);
|
||||
}
|
||||
sx_xunlock(&kld_sx);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user