From 0fa1c0241b2e2aee5991c242ced52139edd081d6 Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Thu, 18 May 2017 07:08:46 +0000 Subject: 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@ --- sys/kern/kern_synch.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 -- cgit v1.2.3