workqueue_finiqueue: our stack could be swapped out while enqueued to
a worker thread.
This commit is contained in:
parent
5547ed1734
commit
117500b9b2
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr_workqueue.c,v 1.26 2008/09/15 10:43:29 rmind Exp $ */
|
||||
/* $NetBSD: subr_workqueue.c,v 1.27 2009/04/03 19:34:19 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c)2002, 2005, 2006, 2007 YAMAMOTO Takashi,
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_workqueue.c,v 1.26 2008/09/15 10:43:29 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_workqueue.c,v 1.27 2009/04/03 19:34:19 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cpu.h>
|
||||
|
@ -40,6 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: subr_workqueue.c,v 1.26 2008/09/15 10:43:29 rmind Ex
|
|||
#include <sys/condvar.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
typedef struct work_impl {
|
||||
SIMPLEQ_ENTRY(work_impl) wk_entry;
|
||||
} work_impl_t;
|
||||
|
@ -203,12 +205,15 @@ static void
|
|||
workqueue_finiqueue(struct workqueue *wq, struct workqueue_queue *q)
|
||||
{
|
||||
struct workqueue_exitargs wqe;
|
||||
lwp_t *l;
|
||||
|
||||
KASSERT(wq->wq_func == workqueue_exit);
|
||||
|
||||
wqe.wqe_q = q;
|
||||
KASSERT(SIMPLEQ_EMPTY(&q->q_queue));
|
||||
KASSERT(q->q_worker != NULL);
|
||||
l = curlwp;
|
||||
uvm_lwp_hold(l);
|
||||
mutex_enter(&q->q_mutex);
|
||||
SIMPLEQ_INSERT_TAIL(&q->q_queue, &wqe.wqe_wk, wk_entry);
|
||||
cv_signal(&q->q_cv);
|
||||
|
@ -216,6 +221,7 @@ workqueue_finiqueue(struct workqueue *wq, struct workqueue_queue *q)
|
|||
cv_wait(&q->q_cv, &q->q_mutex);
|
||||
}
|
||||
mutex_exit(&q->q_mutex);
|
||||
uvm_lwp_rele(l);
|
||||
mutex_destroy(&q->q_mutex);
|
||||
cv_destroy(&q->q_cv);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue