diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c --- a/sys/geom/geom_event.c +++ b/sys/geom/geom_event.c @@ -347,6 +347,7 @@ g_post_event_ep_va(g_event_t *func, void *arg, int wuflag, struct g_event *ep, va_list ap) { + struct thread *td; void *p; u_int n; @@ -366,8 +367,12 @@ TAILQ_INSERT_TAIL(&g_events, ep, events); mtx_unlock(&g_eventlock); wakeup(&g_wait_event); - curthread->td_pflags |= TDP_GEOM; - ast_sched(curthread, TDA_GEOM); + + td = curthread; + if ((td->td_pflags & TDP_KTHREAD) == 0) { + td->td_pflags |= TDP_GEOM; + ast_sched(td, TDA_GEOM); + } } void diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -346,6 +346,17 @@ p = td->td_proc; + /* + * Clear kernel ASTs in advance of selecting the last exiting + * thread and collecting schedulers locks. It is fine to + * clear that ASTs there even if we are not going to exit + * after all. On the other hand, having them pending could + * trigger that subsystems in the context that is not prepared + * to handle top kernel actions, even in execution of an + * unrelated thread. + */ + ast_kclear(td); + /* * If all of the threads in a process call this routine to * exit (e.g. all threads call pthread_exit()), exactly one