Index: sys/pool.h =================================================================== RCS file: /cvs/src/sys/sys/pool.h,v retrieving revision 1.71 diff -u -p -r1.71 pool.h --- sys/pool.h 16 Jun 2017 01:55:45 -0000 1.71 +++ sys/pool.h 16 Jun 2017 03:03:03 -0000 @@ -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 */ Index: kern/subr_pool.c =================================================================== RCS file: /cvs/src/sys/kern/subr_pool.c,v retrieving revision 1.214 diff -u -p -r1.214 subr_pool.c --- kern/subr_pool.c 16 Jun 2017 01:55:45 -0000 1.214 +++ kern/subr_pool.c 16 Jun 2017 03:03:03 -0000 @@ -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