sleepq_remove: Do not call sched_wakeup() when thread is running.
This fixes a locking problem, when l_cpu is changed in LSONPROC state. Possible case was noted by <ad>.
This commit is contained in:
parent
fad077a68d
commit
337692921d
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_sleepq.c,v 1.15 2007/10/09 19:00:14 rmind Exp $ */
|
||||
/* $NetBSD: kern_sleepq.c,v 1.16 2007/10/13 00:13:05 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
|
||||
@ -42,7 +42,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.15 2007/10/09 19:00:14 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.16 2007/10/13 00:13:05 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/lock.h>
|
||||
@ -127,12 +127,6 @@ sleepq_remove(sleepq_t *sq, lwp_t *l)
|
||||
l->l_sleepq = NULL;
|
||||
l->l_flag &= ~LW_SINTR;
|
||||
|
||||
/*
|
||||
* Call the wake-up handler of scheduler.
|
||||
* It might change the CPU for this thread.
|
||||
*/
|
||||
sched_wakeup(l);
|
||||
|
||||
ci = l->l_cpu;
|
||||
spc = &ci->ci_schedstate;
|
||||
|
||||
@ -141,7 +135,7 @@ sleepq_remove(sleepq_t *sq, lwp_t *l)
|
||||
* holds it stopped set it running again.
|
||||
*/
|
||||
if (l->l_stat != LSSLEEP) {
|
||||
KASSERT(l->l_stat == LSSTOP || l->l_stat == LSSUSPENDED);
|
||||
KASSERT(l->l_stat == LSSTOP || l->l_stat == LSSUSPENDED);
|
||||
lwp_setlock(l, &spc->spc_lwplock);
|
||||
return 0;
|
||||
}
|
||||
@ -157,6 +151,14 @@ sleepq_remove(sleepq_t *sq, lwp_t *l)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the wake-up handler of scheduler.
|
||||
* It might change the CPU for this thread.
|
||||
*/
|
||||
sched_wakeup(l);
|
||||
ci = l->l_cpu;
|
||||
spc = &ci->ci_schedstate;
|
||||
|
||||
/*
|
||||
* Set it running. We'll try to get the last CPU that ran
|
||||
* this LWP to pick it up again.
|
||||
|
Loading…
Reference in New Issue
Block a user