diff options
author | davidxu <davidxu@FreeBSD.org> | 2004-08-31 11:52:05 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2004-08-31 11:52:05 +0000 |
commit | 21ee614ff9524db05ee9b0fc3848b9308245685e (patch) | |
tree | 6b578f28e8054efbe6451cf47be55627738eac3d | |
parent | 2782d4b3fc93d70e6b2e643c22ad90982b863bf1 (diff) | |
download | FreeBSD-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.c | 85 | ||||
-rw-r--r-- | sys/sys/proc.h | 1 |
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 */ |