summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-10-17 22:04:45 +0000
committerjhb <jhb@FreeBSD.org>2001-10-17 22:04:45 +0000
commitd51a15e1db59ea760a9fc9ac47b87905d063ef14 (patch)
treea645efda6417bd966879f3b9d0adc3531675066e
parent946a8b3717e073c150190e81f53a4e3b49458296 (diff)
downloadFreeBSD-src-d51a15e1db59ea760a9fc9ac47b87905d063ef14.zip
FreeBSD-src-d51a15e1db59ea760a9fc9ac47b87905d063ef14.tar.gz
- Small cleanups to the Giant handling in trap().
- Only release Giant in trap() if we locked it, otherwise we could release Giant in a kernel trap if we didn't get it for a page fault and the previous frame had grabbed the lock. - Only get Giant for !MP safe syscalls.
-rw-r--r--sys/ia64/ia64/trap.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index 63b2f43..8d6d719 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -302,11 +302,10 @@ trap(int vector, int imm, struct trapframe *framep)
*/
if (user) {
mtx_lock(&Giant);
- if ((i = unaligned_fixup(framep, td)) == 0) {
- mtx_unlock(&Giant);
- goto out;
- }
+ i = unaligned_fixup(framep, td);
mtx_unlock(&Giant);
+ if (i == 0)
+ goto out;
ucode = framep->tf_cr_ifa; /* VA */
break;
}
@@ -478,6 +477,7 @@ trap(int vector, int imm, struct trapframe *framep)
} else if (rv == KERN_PROTECTION_FAILURE)
rv = KERN_INVALID_ADDRESS;
}
+ mtx_unlock(&Giant);
if (rv == KERN_SUCCESS)
goto out;
@@ -520,10 +520,10 @@ trap(int vector, int imm, struct trapframe *framep)
#endif
trapsignal(p, i, ucode);
out:
- if (user)
+ if (user) {
userret(td, framep, sticks);
- if (mtx_owned(&Giant))
- mtx_unlock(&Giant);
+ mtx_assert(&Giant, MA_NOTOWNED);
+ }
return;
dopanic:
@@ -568,7 +568,6 @@ syscall(int code, u_int64_t *args, struct trapframe *framep)
td->td_frame = framep;
sticks = td->td_kse->ke_sticks;
- mtx_lock(&Giant);
/*
* Skip past the break instruction. Remember old address in case
* we have to restart.
@@ -610,6 +609,11 @@ syscall(int code, u_int64_t *args, struct trapframe *framep)
else
callp = &p->p_sysent->sv_table[code];
+ /*
+ * Try to run the syscall without Giant if the syscall is MP safe.
+ */
+ if ((callp->sys_narg & SYS_MPSAFE) == 0)
+ mtx_lock(&Giant);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
ktrsyscall(p->p_tracep, code, (callp->sy_narg & SYF_ARGMASK), args);
@@ -654,7 +658,11 @@ syscall(int code, u_int64_t *args, struct trapframe *framep)
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p->p_tracep, code, error, td->td_retval[0]);
#endif
- mtx_unlock(&Giant);
+ /*
+ * Release Giant if we had to get it.
+ */
+ if ((callp->sy_narg & SYF_MPSAFE) == 0)
+ mtx_unlock(&Giant);
/*
* This works because errno is findable through the
OpenPOWER on IntegriCloud