diff --git a/lib/isc/hp.c b/lib/isc/hp.c index 894d1ceb3f..f46398c7ca 100644 --- a/lib/isc/hp.c +++ b/lib/isc/hp.c @@ -111,7 +111,7 @@ isc_hp_new(isc_mem_t *mctx, size_t max_hps, isc_hp_deletefunc_t *deletefunc) { isc_hp_uintptr_t *hps; hps = isc_mem_get_aligned(mctx, hp->max_hps * sizeof(*hps), - ISC_OS_CACHELINE_SIZE); + isc_os_cacheline()); for (int j = 0; j < hp->max_hps; j++) { atomic_init(&hps[j], 0); } @@ -124,8 +124,7 @@ isc_hp_new(isc_mem_t *mctx, size_t max_hps, isc_hp_deletefunc_t *deletefunc) { for (int i = 0; i < isc__hp_max_threads; i++) { retirelist_t *rl; - rl = isc_mem_get_aligned(mctx, sizeof(*rl), - ISC_OS_CACHELINE_SIZE); + rl = isc_mem_get_aligned(mctx, sizeof(*rl), isc_os_cacheline()); rl->size = 0; rl->list = isc_mem_get(hp->mctx, hp->max_retired * sizeof(uintptr_t)); @@ -149,12 +148,12 @@ isc_hp_destroy(isc_hp_t *hp) { isc_mem_put(hp->mctx, rl->list, hp->max_retired * sizeof(uintptr_t)); isc_mem_put_aligned(hp->mctx, rl, sizeof(*rl), - ISC_OS_CACHELINE_SIZE); + isc_os_cacheline()); } for (int i = 0; i < isc__hp_max_threads; i++) { isc_hp_uintptr_t *hps = hp->hp[i]; isc_mem_put_aligned(hp->mctx, hps, hp->max_hps * sizeof(*hps), - ISC_OS_CACHELINE_SIZE); + isc_os_cacheline()); } isc_mem_put(hp->mctx, hp->hp, isc__hp_max_threads * sizeof(hp->hp[0])); isc_mem_put(hp->mctx, hp->rl, isc__hp_max_threads * sizeof(hp->rl[0])); diff --git a/lib/isc/include/isc/os.h b/lib/isc/include/isc/os.h index 8185a8ed79..b0a7d7cc9b 100644 --- a/lib/isc/include/isc/os.h +++ b/lib/isc/include/isc/os.h @@ -34,4 +34,12 @@ isc_os_ncpus(void); * be determined. */ +unsigned long +isc_os_cacheline(void); +/*%< + * Return L1 caheline size of the CPU. + * If L1 cache is greater than ISC_OS_CACHELINE_SIZE, ensure it is used + * instead of constant. Is common on ppc64le architecture. + */ + ISC_LANG_ENDDECLS diff --git a/lib/isc/mem.c b/lib/isc/mem.c index b559aa4953..890b4dd0ab 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -459,7 +459,7 @@ mem_create(isc_mem_t **ctxp, unsigned int flags) { REQUIRE(ctxp != NULL && *ctxp == NULL); - ctx = mallocx(sizeof(*ctx), MALLOCX_ALIGN(ISC_OS_CACHELINE_SIZE)); + ctx = mallocx(sizeof(*ctx), MALLOCX_ALIGN(isc_os_cacheline())); INSIST(ctx != NULL); *ctx = (isc_mem_t){ @@ -578,7 +578,7 @@ destroy(isc_mem_t *ctx) { if (ctx->checkfree) { INSIST(malloced == 0); } - sdallocx(ctx, sizeof(*ctx), MALLOCX_ALIGN(ISC_OS_CACHELINE_SIZE)); + sdallocx(ctx, sizeof(*ctx), MALLOCX_ALIGN(isc_os_cacheline())); } void diff --git a/lib/isc/os.c b/lib/isc/os.c index 9e2b08ce16..f4731ab292 100644 --- a/lib/isc/os.c +++ b/lib/isc/os.c @@ -20,6 +20,7 @@ #include "os_p.h" static unsigned int isc__os_ncpus = 0; +static unsigned long isc__os_cacheline = ISC_OS_CACHELINE_SIZE; #ifdef HAVE_SYSCONF @@ -76,12 +77,19 @@ isc_os_ncpus(void) { return (isc__os_ncpus); } +unsigned long +isc_os_cacheline(void) { + return (isc__os_cacheline); +} + void isc__os_initialize(void) { ncpus_initialize(); #if defined(HAVE_SYSCONF) && defined(_SC_LEVEL1_DCACHE_LINESIZE) long s = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); - RUNTIME_CHECK((size_t)s == (size_t)ISC_OS_CACHELINE_SIZE || s <= 0); + if (s > 0 && (unsigned long)s > isc__os_cacheline) { + isc__os_cacheline = s; + } #endif } diff --git a/lib/isc/queue.c b/lib/isc/queue.c index b305980603..d7856c156d 100644 --- a/lib/isc/queue.c +++ b/lib/isc/queue.c @@ -94,8 +94,7 @@ isc_queue_new(isc_mem_t *mctx) { isc_queue_t *queue = NULL; node_t *sentinel = NULL; - queue = isc_mem_get_aligned(mctx, sizeof(*queue), - ISC_OS_CACHELINE_SIZE); + queue = isc_mem_get_aligned(mctx, sizeof(*queue), isc_os_cacheline()); *queue = (isc_queue_t){ 0 }; @@ -211,5 +210,5 @@ isc_queue_destroy(isc_queue_t *queue) { isc_hp_destroy(queue->hp); isc_mem_putanddetach_aligned(&queue->mctx, queue, sizeof(*queue), - ISC_OS_CACHELINE_SIZE); + isc_os_cacheline()); }