workqueue_finiqueue: our stack could be swapped out while enqueued to

a worker thread.
This commit is contained in:
ad 2009-04-03 19:34:19 +00:00
parent 5547ed1734
commit 117500b9b2
1 changed files with 8 additions and 2 deletions

View File

@ -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);
}