DF-0239 / fix.diff
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -205,6 +205,34 @@ } } +/* + * DF-0239: resume a kernel process previously suspended with + * suspend_kproc(). This was declared in <sys/kthread.h> but never + * implemented, so a suspended daemon (syncer, bufdaemon, swapcache, + * mountd, printf, hptmv, ...) would spin forever in + * kproc_suspend_loop() waiting for TDF_MP_WAKEREQ and never wake up. + */ +int +resume_kproc(struct thread *td) +{ + if (td->td_proc == NULL) { + lwkt_gettoken(&kpsus_token); + /* request thread resume */ + atomic_set_int(&td->td_mpflags, TDF_MP_WAKEREQ); + wakeup(td); + while (td->td_mpflags & TDF_MP_WAKEREQ) { + int error = tsleep(td, 0, "reskp", 0); + if (error == EWOULDBLOCK) + break; + } + atomic_clear_int(&td->td_mpflags, TDF_MP_WAKEREQ); + lwkt_reltoken(&kpsus_token); + return(0); + } else { + return(EINVAL); /* not a kernel thread */ + } +} + void kproc_suspend_loop(void) { |