dynamically scale the size of the per cpu cache lists.
authordlg <dlg@openbsd.org>
Mon, 19 Jun 2017 23:57:12 +0000 (23:57 +0000)
committerdlg <dlg@openbsd.org>
Mon, 19 Jun 2017 23:57:12 +0000 (23:57 +0000)
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@

sys/kern/subr_pool.c
sys/sys/pool.h

index 62ac8cc..72d7363 100644 (file)
@@ -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
index 82aa9ba..e98a9cd 100644 (file)
@@ -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 */