summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_pool.c
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2017-02-20 00:43:25 +0000
committerdlg <dlg@openbsd.org>2017-02-20 00:43:25 +0000
commitca3bb01eb033b5f824da3984eef1ed2e8b582b33 (patch)
tree0591f2c53b622eecd1e0e90fefc7b20c3c3015bc /sys/kern/subr_pool.c
parentDo not break the line at U+00A0 NO-BREAK SPACE. (diff)
downloadwireguard-openbsd-ca3bb01eb033b5f824da3984eef1ed2e8b582b33.tar.xz
wireguard-openbsd-ca3bb01eb033b5f824da3984eef1ed2e8b582b33.zip
revert 1.206 because it allows deadlocks.
if the gc task is running on a cpu that handles interrupts it is possible to allow a deadlock. the gc task my be cleaning up a pool and holding its mutex when an non-MPSAFE interrupt arrives and tries to take the kernel lock. another cpu may already be holding the kernel lock when it then tries use the same pool thats the pool GC is currently processing. thanks to sthen@ and mpi@ for chasing this down.
Diffstat (limited to 'sys/kern/subr_pool.c')
-rw-r--r--sys/kern/subr_pool.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c
index 177b4083c8e..e6f67130730 100644
--- a/sys/kern/subr_pool.c
+++ b/sys/kern/subr_pool.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_pool.c,v 1.206 2017/02/08 05:28:30 dlg Exp $ */
+/* $OpenBSD: subr_pool.c,v 1.207 2017/02/20 00:43:25 dlg Exp $ */
/* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */
/*-
@@ -1446,8 +1446,10 @@ pool_gc_pages(void *null)
{
struct pool *pp;
struct pool_page_header *ph, *freeph;
+ int s;
rw_enter_read(&pool_lock);
+ s = splvm(); /* XXX go to splvm until all pools _setipl properly */
SIMPLEQ_FOREACH(pp, &pool_head, pr_poollist) {
if (pp->pr_nidle <= pp->pr_minpages || /* guess */
!mtx_enter_try(&pp->pr_mtx)) /* try */
@@ -1467,6 +1469,7 @@ pool_gc_pages(void *null)
if (freeph != NULL)
pool_p_free(pp, freeph);
}
+ splx(s);
rw_exit_read(&pool_lock);
timeout_add_sec(&pool_gc_tick, 1);