From: Ralph Dolmans Date: Fri, 16 Oct 2020 15:12:08 +0000 (+0200) Subject: - local-zone regional allocations outside of chunk to prevent large X-Git-Tag: release-1.13.0rc1~31^2~4^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F329%2Fhead;p=thirdparty%2Funbound.git - local-zone regional allocations outside of chunk to prevent large chunk per small local-zone allocations. --- diff --git a/services/localzone.c b/services/localzone.c index 6aaf0c055..cad460663 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -157,7 +157,7 @@ local_zone_create(uint8_t* nm, size_t len, int labs, z->namelen = len; z->namelabs = labs; lock_rw_init(&z->lock); - z->region = regional_create_custom(sizeof(struct regional)); + z->region = regional_create_nochunk(sizeof(struct regional)); if(!z->region) { free(z); return NULL; diff --git a/util/regional.c b/util/regional.c index ff36d0e21..01a042b61 100644 --- a/util/regional.c +++ b/util/regional.c @@ -80,18 +80,38 @@ regional_init(struct regional* r) r->total_large = 0; } -struct regional* -regional_create_custom(size_t size) +/** + * Create a new region, with custom first block and large-object sizes. + * @param size: length of first block. + * @param large_object_size: outside of chunk allocation threshold. + * @return: newly allocated regional. + */ +static struct regional* +regional_create_custom_large_object(size_t size, size_t large_object_size) { struct regional* r = (struct regional*)malloc(size); size = ALIGN_UP(size, ALIGNMENT); log_assert(sizeof(struct regional) <= size); if(!r) return NULL; r->first_size = size; + r->large_object_size = large_object_size; regional_init(r); return r; } +struct regional* +regional_create_custom(size_t size) +{ + return regional_create_custom_large_object(size, + REGIONAL_LARGE_OBJECT_SIZE); +} + +struct regional* +regional_create_nochunk(size_t size) +{ + return regional_create_custom_large_object(size, 0); +} + void regional_free_all(struct regional *r) { @@ -134,7 +154,7 @@ regional_alloc(struct regional *r, size_t size) malloc and ALIGN_UP */ a = ALIGN_UP(size, ALIGNMENT); /* large objects */ - if(a > REGIONAL_LARGE_OBJECT_SIZE) { + if(a > r->large_object_size) { s = malloc(ALIGNMENT + size); if(!s) return NULL; r->total_large += ALIGNMENT+size; @@ -219,7 +239,7 @@ regional_log_stats(struct regional *r) /* some basic assertions put here (non time critical code) */ log_assert(ALIGNMENT >= sizeof(char*)); log_assert(REGIONAL_CHUNK_SIZE > ALIGNMENT); - log_assert(REGIONAL_CHUNK_SIZE-ALIGNMENT > REGIONAL_LARGE_OBJECT_SIZE); + log_assert(REGIONAL_CHUNK_SIZE-ALIGNMENT > r->large_object_size); log_assert(REGIONAL_CHUNK_SIZE >= sizeof(struct regional)); /* debug print */ log_info("regional %u chunks, %u large", diff --git a/util/regional.h b/util/regional.h index e8b2cb8d0..eeb7de7b5 100644 --- a/util/regional.h +++ b/util/regional.h @@ -74,6 +74,8 @@ struct regional size_t available; /** current chunk data position. */ char* data; + /** threshold for outside of chunk allocations */ + size_t large_object_size; }; /** @@ -88,6 +90,14 @@ struct regional* regional_create(void); * @return: newly allocated regional. */ struct regional* regional_create_custom(size_t size); + +/** + * Create a new region, with custom settings, that will allocate everything + * outside the region chunk. + * @param size: length of first block. + * @return: newly allocated regional. + */ +struct regional* regional_create_nochunk(size_t size); /** * Free all memory associated with regional. Only keeps the first block with