From: tedu Date: Thu, 1 May 2014 04:25:02 +0000 (+0000) Subject: with some random chance, swizzle the current page for the pool to avoid X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=80f0d99cbd92c2a609c0943848841fbb4bc75f1d;p=openbsd with some random chance, swizzle the current page for the pool to avoid fully deterministic behavior. ok deraadt --- diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c index 3e065b61bf1..5cae063a964 100644 --- a/sys/kern/subr_pool.c +++ b/sys/kern/subr_pool.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_pool.c,v 1.126 2014/04/03 21:36:59 tedu Exp $ */ +/* $OpenBSD: subr_pool.c,v 1.127 2014/05/01 04:25:02 tedu Exp $ */ /* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */ /*- @@ -101,6 +101,7 @@ unsigned int pool_serial; int pool_catchup(struct pool *); void pool_prime_page(struct pool *, caddr_t, struct pool_item_header *); void pool_update_curpage(struct pool *); +void pool_swizzle_curpage(struct pool *); void *pool_do_get(struct pool *, int); void pool_do_put(struct pool *, void *); void pr_rmpage(struct pool *, struct pool_item_header *, @@ -568,6 +569,7 @@ startover: return (NULL); } + pool_swizzle_curpage(pp); /* * The convention we use is that if `curpage' is not NULL, then * it points at a non-empty bucket. In particular, `curpage' @@ -813,17 +815,13 @@ pool_do_put(struct pool *pp, void *v) pool_update_curpage(pp); } } - /* * If the page was previously completely full, move it to the - * partially-full list and make it the current page. The next - * allocation will get the item from this page, instead of - * further fragmenting the pool. + * partially-full list. */ else if (ph->ph_nmissing == (pp->pr_itemsperpage - 1)) { LIST_REMOVE(ph, ph_pagelist); LIST_INSERT_HEAD(&pp->pr_partpages, ph, ph_pagelist); - pp->pr_curpage = ph; } } @@ -981,6 +979,27 @@ pool_update_curpage(struct pool *pp) } } +void +pool_swizzle_curpage(struct pool *pp) +{ + struct pool_item_header *ph, *next; + + if ((ph = pp->pr_curpage) == NULL) + return; + if (arc4random_uniform(16) != 0) + return; + next = LIST_FIRST(&pp->pr_partpages); + if (next == ph) + next = LIST_NEXT(next, ph_pagelist); + if (next == NULL) { + next = LIST_FIRST(&pp->pr_emptypages); + if (next == ph) + next = LIST_NEXT(next, ph_pagelist); + } + if (next != NULL) + pp->pr_curpage = next; +} + void pool_setlowat(struct pool *pp, int n) {