From: dlg Date: Mon, 19 Jun 2017 23:57:12 +0000 (+0000) Subject: dynamically scale the size of the per cpu cache lists. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=a11cecbbcfd10e2b38201d497c4c3514a5acf20d;p=openbsd 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@ --- 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 */