summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2004-08-31 11:52:05 +0000
committerdavidxu <davidxu@FreeBSD.org>2004-08-31 11:52:05 +0000
commit21ee614ff9524db05ee9b0fc3848b9308245685e (patch)
tree6b578f28e8054efbe6451cf47be55627738eac3d
parent2782d4b3fc93d70e6b2e643c22ad90982b863bf1 (diff)
downloadFreeBSD-src-21ee614ff9524db05ee9b0fc3848b9308245685e.zip
FreeBSD-src-21ee614ff9524db05ee9b0fc3848b9308245685e.tar.gz
Remove TDP_USTATCLOCK, we no longer need it because we now always
update tick count for userland in thread_userret. This change also removes a "no upcall owned" panic because fuword() schedules an upcall under heavily loaded, and code assumes there is no upcall can occur. Reported and Tested by: Peter Holm <peter@holm.cc>
-rw-r--r--sys/kern/kern_kse.c85
-rw-r--r--sys/sys/proc.h1
2 files changed, 30 insertions, 56 deletions
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index 02ef46d..5636df5 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -65,7 +65,7 @@ extern struct mtx kse_zombie_lock;
TAILQ_HEAD(, kse_upcall) zombie_upcalls =
TAILQ_HEAD_INITIALIZER(zombie_upcalls);
-static int thread_update_usr_ticks(struct thread *td, int user);
+static int thread_update_usr_ticks(struct thread *td);
static void thread_alloc_spare(struct thread *td);
/* move to proc.h */
@@ -818,7 +818,7 @@ thread_export_context(struct thread *td, int willexit)
struct ksegrp *kg;
uintptr_t mbx;
void *addr;
- int error = 0, temp, sig;
+ int error = 0, sig;
mcontext_t mc;
p = td->td_proc;
@@ -850,14 +850,6 @@ thread_export_context(struct thread *td, int willexit)
if (error)
goto bad;
- /* Exports clock ticks in kernel mode */
- addr = (caddr_t)(&td->td_mailbox->tm_sticks);
- temp = fuword32(addr) + td->td_usticks;
- if (suword32(addr, temp)) {
- error = EFAULT;
- goto bad;
- }
-
addr = (caddr_t)(&td->td_mailbox->tm_lwp);
if (suword32(addr, 0)) {
error = EFAULT;
@@ -938,13 +930,11 @@ int
thread_statclock(int user)
{
struct thread *td = curthread;
- struct ksegrp *kg = td->td_ksegrp;
- if (kg->kg_numupcalls == 0 || !(td->td_pflags & TDP_SA))
+ if (!(td->td_pflags & TDP_SA))
return (0);
if (user) {
/* Current always do via ast() */
- td->td_pflags |= TDP_USTATCLOCK;
mtx_lock_spin(&sched_lock);
td->td_flags |= TDF_ASTPENDING;
mtx_unlock_spin(&sched_lock);
@@ -958,47 +948,34 @@ thread_statclock(int user)
* Export state clock ticks for userland
*/
static int
-thread_update_usr_ticks(struct thread *td, int user)
+thread_update_usr_ticks(struct thread *td)
{
struct proc *p = td->td_proc;
- struct kse_thr_mailbox *tmbx;
- struct kse_upcall *ku;
- struct ksegrp *kg;
caddr_t addr;
u_int uticks;
- if ((ku = td->td_upcall) == NULL)
+ if (td->td_mailbox == NULL)
return (-1);
- if ((tmbx = td->td_mailbox) == NULL) {
- tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
- if ((tmbx == NULL) || (tmbx == (void *)-1))
- return (-1);
- }
- if (user) {
- uticks = td->td_uuticks;
+ if ((uticks = td->td_uuticks) != 0) {
td->td_uuticks = 0;
- addr = (caddr_t)&tmbx->tm_uticks;
- } else {
- uticks = td->td_usticks;
- td->td_usticks = 0;
- addr = (caddr_t)&tmbx->tm_sticks;
- }
- if (uticks) {
- if (suword32(addr, uticks+fuword32(addr))) {
- PROC_LOCK(p);
- psignal(p, SIGSEGV);
- PROC_UNLOCK(p);
- return (-2);
- }
+ addr = (caddr_t)&td->td_mailbox->tm_uticks;
+ if (suword32(addr, uticks+fuword32(addr)))
+ goto error;
}
- kg = td->td_ksegrp;
- if (kg->kg_upquantum && ticks >= kg->kg_nextupcall) {
- mtx_lock_spin(&sched_lock);
- td->td_upcall->ku_flags |= KUF_DOUPCALL;
- mtx_unlock_spin(&sched_lock);
+ if ((uticks = td->td_usticks) != 0) {
+ td->td_usticks = 0;
+ addr = (caddr_t)&td->td_mailbox->tm_sticks;
+ if (suword32(addr, uticks+fuword32(addr)))
+ goto error;
}
return (0);
+
+error:
+ PROC_LOCK(p);
+ psignal(p, SIGSEGV);
+ PROC_UNLOCK(p);
+ return (-2);
}
/*
@@ -1222,25 +1199,24 @@ thread_userret(struct thread *td, struct trapframe *frame)
struct timespec ts;
int error = 0, upcalls, uts_crit;
- p = td->td_proc;
- kg = td->td_ksegrp;
- ku = td->td_upcall;
-
/* Nothing to do with bound thread */
if (!(td->td_pflags & TDP_SA))
return (0);
/*
- * Stat clock interrupt hit in userland, it
- * is returning from interrupt, charge thread's
- * userland time for UTS.
+ * Update stat clock count for userland
*/
- if (td->td_pflags & TDP_USTATCLOCK) {
- thread_update_usr_ticks(td, 1);
- td->td_pflags &= ~TDP_USTATCLOCK;
+ if (td->td_mailbox != NULL) {
+ thread_update_usr_ticks(td);
+ uts_crit = 0;
+ } else {
+ uts_crit = 1;
}
- uts_crit = (td->td_mailbox == NULL);
+ p = td->td_proc;
+ kg = td->td_ksegrp;
+ ku = td->td_upcall;
+
/*
* Optimisation:
* This thread has not started any upcall.
@@ -1253,7 +1229,6 @@ thread_userret(struct thread *td, struct trapframe *frame)
(kg->kg_completed == NULL) &&
(ku->ku_flags & KUF_DOUPCALL) == 0 &&
(kg->kg_upquantum && ticks < kg->kg_nextupcall)) {
- thread_update_usr_ticks(td, 0);
nanotime(&ts);
error = copyout(&ts,
(caddr_t)&ku->ku_mailbox->km_timeofday,
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 11a68a6..130f33e 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -387,7 +387,6 @@ struct thread {
#define TDP_SA 0x00000080 /* A scheduler activation based thread. */
#define TDP_OWEPREEMPT 0x00000100 /* Thread has a pending preemption. */
#define TDP_OWEUPC 0x00000200 /* Call addupc() at next AST. */
-#define TDP_USTATCLOCK 0x00000400 /* Finish user statclock hit at next AST. */
#define TDP_CAN_UNBIND 0x00000800 /* Only temporarily bound. */
#define TDP_SCHED1 0x00001000 /* Reserved for scheduler private use */
#define TDP_SCHED2 0x00002000 /* Reserved for scheduler private use */
OpenPOWER on IntegriCloud