Index: subr_pool.c =================================================================== RCS file: /cvs/src/sys/kern/subr_pool.c,v retrieving revision 1.222 diff -u -p -r1.222 subr_pool.c --- subr_pool.c 6 Feb 2018 22:35:32 -0000 1.222 +++ subr_pool.c 6 Feb 2018 23:36:15 -0000 @@ -277,6 +277,14 @@ int pool_wait_gc = 8; RBT_PROTOTYPE(phtree, pool_page_header, ph_node, phtree_compare); +#define POOL_RBYTES 128 /* XXX magic */ +#define POOL_RBITS (POOL_RBYTES * NBBY) + +static unsigned int pool_rbytes[POOL_RBYTES / sizeof(unsigned int)]; +static unsigned int pool_rbit = 0; + +static int pool_getrbit(void); + static inline int phtree_compare(const struct pool_page_header *a, const struct pool_page_header *b) @@ -460,6 +468,8 @@ pool_init(struct pool *pp, size_t size, TAILQ_INIT(&pp->pr_requests); if (phpool.pr_size == 0) { + arc4random_buf(pool_rbytes, sizeof(pool_rbytes)); + pool_init(&phpool, sizeof(struct pool_page_header), 0, IPL_HIGH, 0, "phpool", NULL); @@ -851,7 +861,11 @@ pool_do_put(struct pool *pp, void *v) #endif /* DIAGNOSTIC */ pi->pi_magic = POOL_IMAGIC(ph, pi); - XSIMPLEQ_INSERT_HEAD(&ph->ph_items, pi, pi_list); + if (pool_getrbit()) + XSIMPLEQ_INSERT_HEAD(&ph->ph_items, pi, pi_list); + else + XSIMPLEQ_INSERT_TAIL(&ph->ph_items, pi, pi_list); + #ifdef DIAGNOSTIC if (POOL_PHPOISON(ph)) poison_mem(pi + 1, pp->pr_size - sizeof(*pi)); @@ -1840,7 +1854,10 @@ pool_cache_list_free(struct pool *pp, st pp->pr_cache_tick = ticks; pp->pr_cache_nitems += POOL_CACHE_ITEM_NITEMS(ci); - TAILQ_INSERT_TAIL(&pp->pr_cache_lists, ci, ci_nextl); + if (pool_getrbit()) + TAILQ_INSERT_HEAD(&pp->pr_cache_lists, ci, ci_nextl); + else + TAILQ_INSERT_TAIL(&pp->pr_cache_lists, ci, ci_nextl); pc->pc_nlput++; @@ -2296,3 +2313,25 @@ static const struct pool_lock_ops pool_l pool_lock_rw_assert_unlocked, pool_lock_rw_sleep, }; + +static int +pool_getrbit(void) +{ + unsigned int rbit; + unsigned int word; + unsigned int bit; + + rbit = atomic_inc_int_nv(&pool_rbit) % POOL_RBITS; + if (rbit == 0) { + /* + * the next, but concurrent reader will get stale bits, but + * that is hard to predict, ie, sort of random? + */ + arc4random_buf(pool_rbytes, sizeof(pool_rbytes)); + } + + word = rbit / (sizeof(word) * NBBY); + bit = rbit % (sizeof(word) * NBBY); + + return (ISSET(pool_rbytes[word], 1 << bit)); +}