Index: sys/pool.h =================================================================== RCS file: /cvs/src/sys/sys/pool.h,v retrieving revision 1.54 diff -u -p -r1.54 pool.h --- sys/pool.h 1 Nov 2014 23:58:07 -0000 1.54 +++ sys/pool.h 5 Nov 2014 23:31:17 -0000 @@ -128,6 +128,7 @@ struct pool { RB_HEAD(phtree, pool_item_header) pr_phtree; + u_int pr_maxcolors; /* Cache colouring */ int pr_phoffset; /* Offset in page of page header */ /* Index: kern/subr_pool.c =================================================================== RCS file: /cvs/src/sys/kern/subr_pool.c,v retrieving revision 1.164 diff -u -p -r1.164 subr_pool.c --- kern/subr_pool.c 1 Nov 2014 23:58:07 -0000 1.164 +++ kern/subr_pool.c 5 Nov 2014 23:31:17 -0000 @@ -82,6 +82,7 @@ struct pool_item_header { ph_node; /* Off-page page headers */ int ph_nmissing; /* # of chunks in use */ caddr_t ph_page; /* this page's address */ + caddr_t ph_colored; /* page's colored address */ u_long ph_magic; }; #define POOL_MAGICBIT (1 << 3) /* keep away from perturbed low bits */ @@ -216,7 +217,7 @@ void pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags, const char *wchan, struct pool_allocator *palloc) { - int off = 0; + int off = 0, space; unsigned int pgsize = PAGE_SIZE, items; #ifdef DIAGNOSTIC struct pool *iter; @@ -292,6 +293,14 @@ pool_init(struct pool *pp, size_t size, pp->pr_hardlimit_warning_last.tv_usec = 0; RB_INIT(&pp->pr_phtree); + /* + * Use the space between the chunks and the page header + * for "cache coloring". + */ + space = POOL_INPGHDR(pp) ? pp->pr_phoffset : pp->pr_pgsize; + space -= pp->pr_itemsperpage * pp->pr_size; + pp->pr_maxcolors = (space / align) + 1; + pp->pr_nget = 0; pp->pr_nfail = 0; pp->pr_nput = 0; @@ -740,6 +749,8 @@ pool_p_alloc(struct pool *pp, int flags) XSIMPLEQ_INIT(&ph->ph_itemlist); ph->ph_page = addr; + addr += pp->pr_align * (pp->pr_npagealloc % pp->pr_maxcolors); + ph->ph_colored = addr; ph->ph_nmissing = 0; arc4random_buf(&ph->ph_magic, sizeof(ph->ph_magic)); #ifdef DIAGNOSTIC @@ -986,8 +997,8 @@ pool_print_pagelist(struct pool_pagelist struct pool_item *pi; LIST_FOREACH(ph, pl, ph_pagelist) { - (*pr)("\t\tpage %p, nmissing %d\n", - ph->ph_page, ph->ph_nmissing); + (*pr)("\t\tpage %p, color %p, nmissing %d\n", + ph->ph_page, ph->ph_colored, ph->ph_nmissing); XSIMPLEQ_FOREACH(pi, &ph->ph_itemlist, pi_list) { if (pi->pi_magic != POOL_IMAGIC(ph, pi)) { (*pr)("\t\t\titem %p, magic 0x%lx\n", @@ -1011,8 +1022,8 @@ pool_print1(struct pool *pp, const char modif++; } - (*pr)("POOL %s: size %u, align %u, roflags 0x%08x\n", - pp->pr_wchan, pp->pr_size, pp->pr_align, + (*pr)("POOL %s: size %u, align %u, maxcolors %u, roflags 0x%08x\n", + pp->pr_wchan, pp->pr_size, pp->pr_align, pp->pr_maxcolors, pp->pr_roflags); (*pr)("\talloc %p\n", pp->pr_alloc); (*pr)("\tminitems %u, minpages %u, maxpages %u, npages %u\n", @@ -1222,7 +1233,7 @@ pool_walk(struct pool *pp, int full, int n; LIST_FOREACH(ph, &pp->pr_fullpages, ph_pagelist) { - cp = ph->ph_page; + cp = ph->ph_colored; n = ph->ph_nmissing; while (n--) { @@ -1232,7 +1243,7 @@ pool_walk(struct pool *pp, int full, } LIST_FOREACH(ph, &pp->pr_partpages, ph_pagelist) { - cp = ph->ph_page; + cp = ph->ph_colored; n = ph->ph_nmissing; do {