]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- local-zone regional allocations outside of chunk to prevent large 329/head
authorRalph Dolmans <ralph@nlnetlabs.nl>
Fri, 16 Oct 2020 15:12:08 +0000 (17:12 +0200)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Fri, 16 Oct 2020 15:12:08 +0000 (17:12 +0200)
chunk per small local-zone allocations.

services/localzone.c
util/regional.c
util/regional.h

index 6aaf0c05518cb357fd46446ff5eec9c33b29f898..cad46066334c90bd8f22308de10420b3dbec6d5f 100644 (file)
@@ -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;
index ff36d0e212416c0dc7b695881060f28f8b0fa884..01a042b6156a495dd98055c840be36a16df00ea2 100644 (file)
@@ -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",
index e8b2cb8d00ca48ad32c1d5c8b435657f7922d689..eeb7de7b528acd90ee80bef433fdd29f48183749 100644 (file)
@@ -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