diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-05-18 07:08:46 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-05-18 07:08:46 +0000 |
commit | 0fa1c0241b2e2aee5991c242ced52139edd081d6 (patch) | |
tree | cb33fb01f29a8b10c7dea5e7f6a8639f36cf73c7 /sys/kern | |
parent | 759d7a530ec4abbaa0343a71d209a313cb44f4e0 (diff) |
Do not panic if we find ourself on the sleep queue while being SONPROC.
If the rwlock passed to rwsleep(9) is contented, the CPU will call wakeup()
between sleep_setup() and sleep_finish(). At this moment curproc is on the
sleep queue but marked as SONPROC. Avoid panicing in this case.
Problem reported by sthen@
ok kettenis@, visa@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_synch.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 9925025e304..83b4cc9f3b5 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.140 2017/04/20 13:57:30 visa Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.141 2017/05/18 07:08:45 mpi Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* @@ -450,6 +450,15 @@ wakeup_n(const volatile void *ident, int n) for (p = TAILQ_FIRST(qp); p != NULL && n != 0; p = pnext) { pnext = TAILQ_NEXT(p, p_runq); #ifdef DIAGNOSTIC + /* + * If the rwlock passed to rwsleep() is contended, the + * CPU will end up calling wakeup() between sleep_setup() + * and sleep_finish(). + */ + if (p == curproc) { + KASSERT(p->p_stat == SONPROC); + continue; + } if (p->p_stat != SSLEEP && p->p_stat != SSTOP) panic("wakeup: p_stat is %d", (int)p->p_stat); #endif |