diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2017-06-19 23:57:13 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2017-06-19 23:57:13 +0000 |
commit | 315d0e97dae2c6527e82bb42cb97ec3e9717ed7f (patch) | |
tree | e61b22193642b5eef7f68645e5b4d320bd3b525e | |
parent | 5883ffe7715bd86751a8af15047e485fd4509102 (diff) |
dynamically scale the size of the per cpu cache lists.
if the lock around the global depot of extra cache lists is contented
a lot in between the gc task runs, consider growing the number of
entries a free list can hold.
the size of the list is bounded by the number of pool items the
current set of pages can represent to avoid having cpus starve each
other. im not sure this semantic is right (or the least worst) but
we're putting it in now to see what happens.
this also means reality matches the documentation i just committed
in pool_cache_init.9.
tested by hrvoje popovski and amit kulkarni
ok visa@
-rw-r--r-- | sys/kern/subr_pool.c | 23 | ||||
-rw-r--r-- | sys/sys/pool.h | 3 |
2 files changed, 24 insertions, 2 deletions
diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c index 62ac8cc6564..72d73633dfc 100644 --- a/sys/kern/subr_pool.c +++ b/sys/kern/subr_pool.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_pool.c,v 1.214 2017/06/16 01:55:45 dlg Exp $ */ +/* $OpenBSD: subr_pool.c,v 1.215 2017/06/19 23:57:12 dlg Exp $ */ /* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */ /*- @@ -1926,6 +1926,8 @@ pool_cache_destroy(struct pool *pp) void pool_cache_gc(struct pool *pp) { + unsigned int contention; + if ((ticks - pp->pr_cache_tick) > (hz * pool_wait_gc) && !TAILQ_EMPTY(&pp->pr_cache_lists) && mtx_enter_try(&pp->pr_cache_mtx)) { @@ -1944,6 +1946,25 @@ pool_cache_gc(struct pool *pp) pool_cache_list_put(pp, pl); } + + /* + * if there's a lot of contention on the pr_cache_mtx then consider + * growing the length of the list to reduce the need to access the + * global pool. + */ + + contention = pp->pr_cache_contention; + if ((contention - pp->pr_cache_contention_prev) > 8 /* magic */) { + unsigned int limit = pp->pr_npages * pp->pr_itemsperpage; + unsigned int items = pp->pr_cache_items + 8; + unsigned int cache = ncpusfound * items * 2; + + /* are there enough items around so every cpu can hold some? */ + + if (cache < limit) + pp->pr_cache_items = items; + } + pp->pr_cache_contention_prev = contention; } void diff --git a/sys/sys/pool.h b/sys/sys/pool.h index 82aa9ba42bc..e98a9cda75f 100644 --- a/sys/sys/pool.h +++ b/sys/sys/pool.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pool.h,v 1.71 2017/06/16 01:55:45 dlg Exp $ */ +/* $OpenBSD: pool.h,v 1.72 2017/06/19 23:57:12 dlg Exp $ */ /* $NetBSD: pool.h,v 1.27 2001/06/06 22:00:17 rafal Exp $ */ /*- @@ -189,6 +189,7 @@ struct pool { u_int pr_cache_nlist; /* # of idle lists */ u_int pr_cache_items; /* target list length */ u_int pr_cache_contention; + u_int pr_cache_contention_prev; int pr_cache_tick; /* time idle list was empty */ int pr_cache_nout; uint64_t pr_cache_ngc; /* # of times the gc released a list */ |