Index: subr_pool.c =================================================================== RCS file: /cvs/src/sys/kern/subr_pool.c,v retrieving revision 1.173 diff -u -p -r1.173 subr_pool.c --- subr_pool.c 22 Dec 2014 00:33:40 -0000 1.173 +++ subr_pool.c 22 Dec 2014 01:44:52 -0000 @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include @@ -160,6 +162,12 @@ void pool_print1(struct pool *, const c #define pool_sleep(pl) msleep(pl, &pl->pr_mtx, PSWP, pl->pr_wchan, 0) +/* stale page garbage collectors */ +void pool_gc_sched(void *); +void pool_gc_pages(void *, void *); +struct timeout pool_gc_tick; +struct task pool_gc_task = TASK_INITIALIZER(pool_gc_pages, NULL, NULL); + static inline int phtree_compare(struct pool_item_header *a, struct pool_item_header *b) { @@ -312,6 +320,10 @@ pool_init(struct pool *pp, size_t size, /* make sure phpool wont "recurse" */ KASSERT(POOL_INPGHDR(&phpool)); + + /* set up GC while here */ + timeout_set(&pool_gc_tick, pool_gc_sched, NULL); + timeout_add_sec(&pool_gc_tick, 1); } /* pglistalloc/constraint parameters */ @@ -1337,6 +1349,45 @@ done: rw_exit_read(&pool_lock); return (rv); +} + +void +pool_gc_sched(void *x) +{ + task_add(systq, &pool_gc_task); +} + +void +pool_gc_pages(void *x, void *y) +{ + extern int ticks; + struct pool *pp; + struct pool_item_header *ph, *freeph; + int s; + + rw_enter_read(&pool_lock); + s = splvm(); + SIMPLEQ_FOREACH(pp, &pool_head, pr_poollist) { + mtx_enter(&pp->pr_mtx); + + /* is it time to free a page? */ + if (pp->pr_nidle > pp->pr_minpages && + (ph = TAILQ_FIRST(&pp->pr_emptypages)) != NULL && + (ticks - ph->ph_tick) > (hz * 8)) { + freeph = ph; + pool_p_remove(pp, freeph); + } else + freeph = NULL; + + mtx_leave(&pp->pr_mtx); + + if (freeph != NULL) + pool_p_free(pp, freeph); + } + splx(s); /* XXX */ + rw_exit_read(&pool_lock); + + timeout_add_sec(&pool_gc_tick, 1); } /*