split returning an item to the pool pages out of pool_put as pool_do_put.
authordlg <dlg@openbsd.org>
Fri, 16 Jun 2017 01:33:20 +0000 (01:33 +0000)
committerdlg <dlg@openbsd.org>
Fri, 16 Jun 2017 01:33:20 +0000 (01:33 +0000)
this lets pool_cache_list_put return items to the pages. currently,
if pool_cache_list_put is called while the per cpu caches are
enabled, the items on the list will put put straight back onto
another list in the cpu cache. this also avoids counting puts for
these items twice. a put for the items have already been coutned
when the items went to a cpu cache, it doesnt need to be counted
again when it goes back to the pool pages.

another side effect of this is that pool_cache_list_put can take
the pool mutex once when returning all the items in the list with
pool_do_put, rather than once per item.

ok visa@

sys/kern/subr_pool.c

index 69bdf35..975d0d5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: subr_pool.c,v 1.212 2017/06/15 03:50:50 dlg Exp $     */
+/*     $OpenBSD: subr_pool.c,v 1.213 2017/06/16 01:33:20 dlg Exp $     */
 /*     $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $       */
 
 /*-
@@ -156,6 +156,7 @@ void         pool_p_free(struct pool *, struct pool_page_header *);
 
 void    pool_update_curpage(struct pool *);
 void   *pool_do_get(struct pool *, int, int *);
+void    pool_do_put(struct pool *, void *);
 int     pool_chk_page(struct pool *, struct pool_page_header *, int);
 int     pool_chk(struct pool *);
 void    pool_get_done(void *, void *);
@@ -711,7 +712,6 @@ pool_do_get(struct pool *pp, int flags, int *slowdown)
 void
 pool_put(struct pool *pp, void *v)
 {
-       struct pool_item *pi = v;
        struct pool_page_header *ph, *freeph = NULL;
 
 #ifdef DIAGNOSTIC
@@ -728,6 +728,37 @@ pool_put(struct pool *pp, void *v)
 
        mtx_enter(&pp->pr_mtx);
 
+       pool_do_put(pp, v);
+
+       pp->pr_nout--;
+       pp->pr_nput++;
+
+       /* is it time to free a page? */
+       if (pp->pr_nidle > pp->pr_maxpages &&
+           (ph = TAILQ_FIRST(&pp->pr_emptypages)) != NULL &&
+           (ticks - ph->ph_tick) > (hz * pool_wait_free)) {
+               freeph = ph;
+               pool_p_remove(pp, freeph);
+       }
+
+       mtx_leave(&pp->pr_mtx);
+
+       if (freeph != NULL)
+               pool_p_free(pp, freeph);
+
+       if (!TAILQ_EMPTY(&pp->pr_requests)) {
+               mtx_enter(&pp->pr_requests_mtx);
+               pool_runqueue(pp, PR_NOWAIT);
+               mtx_leave(&pp->pr_requests_mtx);
+       }
+}
+
+void
+pool_do_put(struct pool *pp, void *v)
+{
+       struct pool_item *pi = v;
+       struct pool_page_header *ph;
+
        splassert(pp->pr_ipl);
 
        ph = pr_find_pagehead(pp, v);
@@ -771,27 +802,6 @@ pool_put(struct pool *pp, void *v)
                TAILQ_INSERT_TAIL(&pp->pr_emptypages, ph, ph_entry);
                pool_update_curpage(pp);
        }
-
-       pp->pr_nout--;
-       pp->pr_nput++;
-
-       /* is it time to free a page? */
-       if (pp->pr_nidle > pp->pr_maxpages &&
-           (ph = TAILQ_FIRST(&pp->pr_emptypages)) != NULL &&
-           (ticks - ph->ph_tick) > (hz * pool_wait_free)) {
-               freeph = ph;
-               pool_p_remove(pp, freeph);
-       }
-       mtx_leave(&pp->pr_mtx);
-
-       if (freeph != NULL)
-               pool_p_free(pp, freeph);
-
-       if (!TAILQ_EMPTY(&pp->pr_requests)) {
-               mtx_enter(&pp->pr_requests_mtx);
-               pool_runqueue(pp, PR_NOWAIT);
-               mtx_leave(&pp->pr_requests_mtx);
-       }
 }
 
 /*
@@ -1864,11 +1874,13 @@ pool_cache_list_put(struct pool *pp, struct pool_cache_item *pl)
 
        rpl = TAILQ_NEXT(pl, ci_nextl);
 
+       mtx_enter(&pp->pr_mtx);
        do {
                next = pl->ci_next;
-               pool_put(pp, pl);
+               pool_do_put(pp, pl);
                pl = next;
        } while (pl != NULL);
+       mtx_leave(&pp->pr_mtx);
 
        return (rpl);
 }