Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_trap.c
Show First 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | #ifdef DIAGNOSTIC | ||||
"failed to set signal flags for ast p %p td %p fl %x", | "failed to set signal flags for ast p %p td %p fl %x", | ||||
p, td, td->td_flags); | p, td, td->td_flags); | ||||
} | } | ||||
} | } | ||||
thread_unlock(td); | thread_unlock(td); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef KTRACE | |||||
KTRUSERRET(td); | |||||
#endif | |||||
td_softdep_cleanup(td); | td_softdep_cleanup(td); | ||||
MPASS(td->td_su == NULL); | MPASS(td->td_su == NULL); | ||||
/* | /* | ||||
* If this thread tickled GEOM, we need to wait for the giggling to | * If this thread tickled GEOM, we need to wait for the giggling to | ||||
* stop before we return to userland | * stop before we return to userland | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | #endif | ||||
if (flags & TDF_PROFPEND) { | if (flags & TDF_PROFPEND) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
kern_psignal(p, SIGPROF); | kern_psignal(p, SIGPROF); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
#ifdef MAC | #ifdef MAC | ||||
if (flags & TDF_MACPEND) | if (flags & TDF_MACPEND) | ||||
mac_thread_userret(td); | mac_thread_userret(td); | ||||
#endif | |||||
#ifdef KTRACE | |||||
KTRUSERRET(td); | |||||
#endif | #endif | ||||
if (flags & TDF_NEEDRESCHED) { | if (flags & TDF_NEEDRESCHED) { | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
if (KTRPOINT(td, KTR_CSW)) | if (KTRPOINT(td, KTR_CSW)) | ||||
ktrcsw(1, 1, __func__); | ktrcsw(1, 1, __func__); | ||||
kib: Idea is that we do not return to userspace with ktrace records not flushed. But look at the… | |||||
traszAuthorUnsubmitted Done Inline ActionsGood point. I'm kind of split about this. On one hand your you're of course right, we should flush the records before returning. On the other hand, the current code didn't do that. On yet another... limb, the current code didn't trigger AST. Perhaps it could be split into two patches, first moving this in a minimally intrusive way (ie the current patch), and subsequent patch moving it more to the end of ast()? I'm exactly 50/50 about this, so if you prefer it to move the call to KTRUSERRET() more to the end of ast(), I'll happily do that. trasz: Good point. I'm kind of split about this. On one hand your you're of course right, we should… | |||||
#endif | #endif | ||||
thread_lock(td); | thread_lock(td); | ||||
sched_prio(td, td->td_user_pri); | sched_prio(td, td->td_user_pri); | ||||
mi_switch(SW_INVOL | SWT_NEEDRESCHED); | mi_switch(SW_INVOL | SWT_NEEDRESCHED); | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
if (KTRPOINT(td, KTR_CSW)) | if (KTRPOINT(td, KTR_CSW)) | ||||
ktrcsw(0, 1, __func__); | ktrcsw(0, 1, __func__); | ||||
#endif | #endif | ||||
Show All 28 Lines | #endif | ||||
/* | /* | ||||
* Check for signals. Unlocked reads of p_pendingcnt or | * Check for signals. Unlocked reads of p_pendingcnt or | ||||
* p_siglist might cause process-directed signal to be handled | * p_siglist might cause process-directed signal to be handled | ||||
* later. | * later. | ||||
*/ | */ | ||||
if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || | if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || | ||||
!SIGISEMPTY(p->p_siglist)) { | !SIGISEMPTY(p->p_siglist)) { | ||||
sigfastblock_fetch(td); | sigfastblock_fetch(td); | ||||
kibUnsubmitted Done Inline ActionsThis function accesses userspace pages and might generate KTR. kib: This function accesses userspace pages and might generate KTR. | |||||
if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0 && | if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0 && | ||||
td->td_sigblock_val != 0) { | td->td_sigblock_val != 0) { | ||||
sigfastblock_setpend(td, true); | sigfastblock_setpend(td, true); | ||||
} else { | } else { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
mtx_lock(&p->p_sigacts->ps_mtx); | mtx_lock(&p->p_sigacts->ps_mtx); | ||||
while ((sig = cursig(td)) != 0) { | while ((sig = cursig(td)) != 0) { | ||||
KASSERT(sig >= 0, ("sig %d", sig)); | KASSERT(sig >= 0, ("sig %d", sig)); | ||||
postsig(sig); | postsig(sig); | ||||
kibUnsubmitted Done Inline ActionsThis function also generates ktrsig records. kib: This function also generates ktrsig records. | |||||
} | } | ||||
mtx_unlock(&p->p_sigacts->ps_mtx); | mtx_unlock(&p->p_sigacts->ps_mtx); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Handle deferred update of the fast sigblock value, after | * Handle deferred update of the fast sigblock value, after | ||||
Show All 34 Lines |
Idea is that we do not return to userspace with ktrace records not flushed. But look at the lines 280-283. It generates new ktrace record. At best, this would set ASTPENDING again.