summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/subr_pool.c')
-rw-r--r--sys/kern/subr_pool.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c
index 975d0d55720..62ac8cc6564 100644
--- a/sys/kern/subr_pool.c
+++ b/sys/kern/subr_pool.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_pool.c,v 1.213 2017/06/16 01:33:20 dlg Exp $ */
+/* $OpenBSD: subr_pool.c,v 1.214 2017/06/16 01:55:45 dlg Exp $ */
/* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */
/*-
@@ -135,6 +135,7 @@ struct pool_cache {
void *pool_cache_get(struct pool *);
void pool_cache_put(struct pool *, void *);
void pool_cache_destroy(struct pool *);
+void pool_cache_gc(struct pool *);
#endif
void pool_cache_pool_info(struct pool *, struct kinfo_pool *);
int pool_cache_info(struct pool *, void *, size_t *);
@@ -1476,6 +1477,11 @@ pool_gc_pages(void *null)
rw_enter_read(&pool_lock);
s = splvm(); /* XXX go to splvm until all pools _setipl properly */
SIMPLEQ_FOREACH(pp, &pool_head, pr_poollist) {
+#ifdef MULTIPROCESSOR
+ if (pp->pr_cache != NULL)
+ pool_cache_gc(pp);
+#endif
+
if (pp->pr_nidle <= pp->pr_minpages || /* guess */
!mtx_enter_try(&pp->pr_mtx)) /* try */
continue;
@@ -1642,8 +1648,10 @@ pool_cache_init(struct pool *pp)
arc4random_buf(pp->pr_cache_magic, sizeof(pp->pr_cache_magic));
TAILQ_INIT(&pp->pr_cache_lists);
pp->pr_cache_nlist = 0;
+ pp->pr_cache_tick = ticks;
pp->pr_cache_items = 8;
pp->pr_cache_contention = 0;
+ pp->pr_cache_ngc = 0;
CPUMEM_FOREACH(pc, &i, cm) {
pc->pc_actv = NULL;
@@ -1659,6 +1667,8 @@ pool_cache_init(struct pool *pp)
pc->pc_nout = 0;
}
+ membar_producer();
+
pp->pr_cache = cm;
}
@@ -1740,6 +1750,9 @@ pool_cache_list_free(struct pool *pp, struct pool_cache *pc,
struct pool_cache_item *ci)
{
pool_list_enter(pp);
+ if (TAILQ_EMPTY(&pp->pr_cache_lists))
+ pp->pr_cache_tick = ticks;
+
TAILQ_INSERT_TAIL(&pp->pr_cache_lists, ci, ci_nextl);
pp->pr_cache_nlist++;
@@ -1893,8 +1906,10 @@ pool_cache_destroy(struct pool *pp)
struct cpumem_iter i;
struct cpumem *cm;
+ rw_enter_write(&pool_lock); /* serialise with the gc */
cm = pp->pr_cache;
pp->pr_cache = NULL; /* make pool_put avoid the cache */
+ rw_exit_write(&pool_lock);
CPUMEM_FOREACH(pc, &i, cm) {
pool_cache_list_put(pp, pc->pc_actv);
@@ -1909,6 +1924,29 @@ pool_cache_destroy(struct pool *pp)
}
void
+pool_cache_gc(struct pool *pp)
+{
+ if ((ticks - pp->pr_cache_tick) > (hz * pool_wait_gc) &&
+ !TAILQ_EMPTY(&pp->pr_cache_lists) &&
+ mtx_enter_try(&pp->pr_cache_mtx)) {
+ struct pool_cache_item *pl = NULL;
+
+ pl = TAILQ_FIRST(&pp->pr_cache_lists);
+ if (pl != NULL) {
+ TAILQ_REMOVE(&pp->pr_cache_lists, pl, ci_nextl);
+ pp->pr_cache_tick = ticks;
+ pp->pr_cache_nlist--;
+
+ pp->pr_cache_ngc++;
+ }
+
+ mtx_leave(&pp->pr_cache_mtx);
+
+ pool_cache_list_put(pp, pl);
+ }
+}
+
+void
pool_cache_pool_info(struct pool *pp, struct kinfo_pool *pi)
{
struct pool_cache *pc;
@@ -1955,7 +1993,7 @@ pool_cache_info(struct pool *pp, void *oldp, size_t *oldlenp)
memset(&kpc, 0, sizeof(kpc)); /* don't leak padding */
mtx_enter(&pp->pr_cache_mtx);
- kpc.pr_ngc = 0; /* notyet */
+ kpc.pr_ngc = pp->pr_cache_ngc;
kpc.pr_len = pp->pr_cache_items;
kpc.pr_nlist = pp->pr_cache_nlist;
kpc.pr_contention = pp->pr_cache_contention;