From e77ffa76d9ec0d05d73a2776430d9092957e90c2 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 21 Mar 2021 19:27:48 -0400 Subject: [PATCH] add initial malloc_trim slab quarantine purging This currently only purges the quarantines for extended size classes. --- h_malloc.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/h_malloc.c b/h_malloc.c index 3d13278..d5daf64 100644 --- a/h_malloc.c +++ b/h_malloc.c @@ -113,6 +113,8 @@ static const size_t MAX_SLAB_SIZE_CLASS = 131072; static const size_t max_empty_slabs_total = MAX_SLAB_SIZE_CLASS; #endif +static const size_t min_extended_size_class = 20480; + static const u32 size_classes[] = { /* 0 */ 0, /* 16 */ 16, 32, 48, 64, 80, 96, 112, 128, @@ -1738,9 +1740,11 @@ EXPORT int h_malloc_trim(UNUSED size_t pad) { // skip zero byte size class since there's nothing to change for (unsigned class = 1; class < N_SIZE_CLASSES; class++) { struct size_class *c = &ro.size_class_metadata[arena][class]; - size_t slab_size = get_slab_size(size_class_slots[class], size_classes[class]); + size_t size = size_classes[class]; + size_t slab_size = get_slab_size(size_class_slots[class], size); mutex_lock(&c->lock); + struct slab_metadata *iterator = c->empty_slabs; while (iterator) { void *slab = get_slab(c, slab_size, iterator); @@ -1759,6 +1763,33 @@ EXPORT int h_malloc_trim(UNUSED size_t pad) { is_trimmed = true; } c->empty_slabs = iterator; + +#if SLAB_QUARANTINE && CONFIG_EXTENDED_SIZE_CLASSES + if (size >= min_extended_size_class) { + size_t quarantine_shift = __builtin_clzl(size) - (63 - MAX_SLAB_SIZE_CLASS_SHIFT); + +#if SLAB_QUARANTINE_RANDOM_LENGTH > 0 + size_t slab_quarantine_random_length = SLAB_QUARANTINE_RANDOM_LENGTH << quarantine_shift; + for (size_t i = 0; i < slab_quarantine_random_length; i++) { + void *p = c->quarantine_random[i]; + if (p != NULL) { + madvise(p, size, MADV_DONTNEED); + } + } +#endif + +#if SLAB_QUARANTINE_QUEUE_LENGTH > 0 + size_t slab_quarantine_queue_length = SLAB_QUARANTINE_QUEUE_LENGTH << quarantine_shift; + for (size_t i = 0; i < slab_quarantine_queue_length; i++) { + void *p = c->quarantine_queue[i]; + if (p != NULL) { + madvise(p, size, MADV_DONTNEED); + } + } +#endif + } +#endif + mutex_unlock(&c->lock); } }