diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2019-06-01 14:11:19 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2019-06-01 14:11:19 +0000 |
commit | a0e1f7014036a5c7704503c72ab3e8adad0cfdc2 (patch) | |
tree | 98949e46f0d4ca770855c7d692b0f592dec8ad00 /sys/kern/kern_time.c | |
parent | 104c8c3e64f6e895292c0fad0cc732f9029b3149 (diff) |
Revert to using the SCHED_LOCK() to protect time accounting.
It currently creates a lock ordering problem because SCHED_LOCK() is taken
by hardclock(). That means the "priorities" of a thread should be moved
out of the SCHED_LOCK() first in order to make progress.
Reported-by: syzbot+8e4863b3dde88eb706dc@syzkaller.appspotmail.com
via anton@ as well as by kettenis@
Diffstat (limited to 'sys/kern/kern_time.c')
-rw-r--r-- | sys/kern/kern_time.c | 14 |
1 files changed, 3 insertions, 11 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 42a7fb369c5..ca109f81434 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.117 2019/05/31 19:51:10 mpi Exp $ */ +/* $OpenBSD: kern_time.c,v 1.118 2019/06/01 14:11:17 mpi Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -106,7 +106,6 @@ settime(const struct timespec *ts) int clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp) { - struct process *pr = p->p_p; struct bintime bt; struct proc *q; int error = 0; @@ -127,18 +126,14 @@ clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp) case CLOCK_PROCESS_CPUTIME_ID: nanouptime(tp); timespecsub(tp, &curcpu()->ci_schedstate.spc_runtime, tp); - mtx_enter(&pr->ps_mtx); - timespecadd(tp, &pr->ps_tu.tu_runtime, tp); + timespecadd(tp, &p->p_p->ps_tu.tu_runtime, tp); timespecadd(tp, &p->p_rtime, tp); - mtx_leave(&pr->ps_mtx); break; case CLOCK_THREAD_CPUTIME_ID: nanouptime(tp); timespecsub(tp, &curcpu()->ci_schedstate.spc_runtime, tp); - mtx_enter(&pr->ps_mtx); timespecadd(tp, &p->p_tu.tu_runtime, tp); timespecadd(tp, &p->p_rtime, tp); - mtx_leave(&pr->ps_mtx); break; default: /* check for clock from pthread_getcpuclockid() */ @@ -147,11 +142,8 @@ clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp) q = tfind(__CLOCK_PTID(clock_id) - THREAD_PID_OFFSET); if (q == NULL || q->p_p != p->p_p) error = ESRCH; - else { - mtx_enter(&pr->ps_mtx); + else *tp = q->p_tu.tu_runtime; - mtx_leave(&pr->ps_mtx); - } KERNEL_UNLOCK(); } else error = EINVAL; |