summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2000-09-12 22:47:10 +0000
committerdfr <dfr@FreeBSD.org>2000-09-12 22:47:10 +0000
commit5adf2c39802a7c30537009e761a1db03b94bb737 (patch)
treee9c9eebbd406f03857c4dc1e498e68acd8c57fee
parent1abaaa6dc2fde99f517e7f315a593fd2bbbccd58 (diff)
downloadFreeBSD-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.c48
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);
}
OpenPOWER on IntegriCloud