summaryrefslogtreecommitdiff
path: root/sys/kern/kern_time.c
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2019-06-01 14:11:19 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2019-06-01 14:11:19 +0000
commita0e1f7014036a5c7704503c72ab3e8adad0cfdc2 (patch)
tree98949e46f0d4ca770855c7d692b0f592dec8ad00 /sys/kern/kern_time.c
parent104c8c3e64f6e895292c0fad0cc732f9029b3149 (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.c14
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;