diff options
author | dfr <dfr@FreeBSD.org> | 2000-09-12 22:47:10 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2000-09-12 22:47:10 +0000 |
commit | 5adf2c39802a7c30537009e761a1db03b94bb737 (patch) | |
tree | e9c9eebbd406f03857c4dc1e498e68acd8c57fee | |
parent | 1abaaa6dc2fde99f517e7f315a593fd2bbbccd58 (diff) | |
download | FreeBSD-src-5adf2c39802a7c30537009e761a1db03b94bb737.zip FreeBSD-src-5adf2c39802a7c30537009e761a1db03b94bb737.tar.gz |
Merge changes from the i386 port to allow userret() to be called both
with and without holding the Giant mutex.
-rw-r--r-- | sys/alpha/alpha/trap.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c index 072c5f3..ebfd140 100644 --- a/sys/alpha/alpha/trap.c +++ b/sys/alpha/alpha/trap.c @@ -73,7 +73,7 @@ u_int32_t want_resched; -void userret __P((struct proc *, u_int64_t, u_quad_t)); +static int userret __P((struct proc *, u_int64_t, u_quad_t, int)); unsigned long Sfloat_to_reg __P((unsigned int)); unsigned int reg_to_Sfloat __P((unsigned long)); @@ -93,17 +93,23 @@ static void printtrap __P((const unsigned long, const unsigned long, * Define the code needed before returning to user mode, for * trap and syscall. */ -void -userret(p, pc, oticks) +static int +userret(p, pc, oticks, have_giant) register struct proc *p; u_int64_t pc; u_quad_t oticks; + int have_giant; { int sig, s; /* take pending signals */ - while ((sig = CURSIG(p)) != 0) + while ((sig = CURSIG(p)) != 0) { + if (have_giant == 0) { + mtx_enter(&Giant, MTX_DEF); + have_giant = 1; + } postsig(sig); + } p->p_priority = p->p_usrpri; if (want_resched) { /* @@ -119,18 +125,28 @@ userret(p, pc, oticks) p->p_stats->p_ru.ru_nivcsw++; mi_switch(); splx(s); - while ((sig = CURSIG(p)) != 0) + while ((sig = CURSIG(p)) != 0) { + if (have_giant == 0) { + mtx_enter(&Giant, MTX_DEF); + have_giant = 1; + } postsig(sig); + } } /* * If profiling, charge recent system time to the trapped pc. */ if (p->p_flag & P_PROFIL) { + if (have_giant == 0) { + mtx_enter(&Giant, MTX_DEF); + have_giant = 1; + } addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio); } curpriority = p->p_priority; + return (have_giant); } static void @@ -548,7 +564,8 @@ trap(a0, a1, a2, entry, framep) out: if (user) { framep->tf_regs[FRAME_SP] = alpha_pal_rdusp(); - userret(p, framep->tf_regs[FRAME_PC], sticks); + if (userret(p, framep->tf_regs[FRAME_PC], sticks, 0)) + mtx_exit(&Giant, MTX_DEF); } return; @@ -704,7 +721,7 @@ syscall(code, framep) */ p = curproc; - userret(p, framep->tf_regs[FRAME_PC], sticks); + userret(p, framep->tf_regs[FRAME_PC], sticks, 1); #ifdef KTRACE if (KTRPOINT(p, KTR_SYSRET)) ktrsysret(p->p_tracep, code, error, p->p_retval[0]); @@ -726,17 +743,26 @@ void child_return(p) struct proc *p; { + int have_giant; /* * Return values in the frame set by cpu_fork(). */ - userret(p, p->p_md.md_tf->tf_regs[FRAME_PC], 0); + have_giant = userret(p, p->p_md.md_tf->tf_regs[FRAME_PC], 0, + mtx_owned(&Giant)); #ifdef KTRACE - if (KTRPOINT(p, KTR_SYSRET)) + if (KTRPOINT(p, KTR_SYSRET)) { + if (have_giant == 0) { + mtx_enter(&Giant, MTX_DEF); + have_giant = 1; + } ktrsysret(p->p_tracep, SYS_fork, 0, 0); + } #endif - mtx_exit(&Giant, MTX_DEF); + + if (have_giant) + mtx_exit(&Giant, MTX_DEF); } /* @@ -768,7 +794,7 @@ ast(framep) p->p_stats->p_prof.pr_ticks); } - userret(p, framep->tf_regs[FRAME_PC], sticks); + userret(p, framep->tf_regs[FRAME_PC], sticks, 1); mtx_exit(&Giant, MTX_DEF); } |