From 597645db6a2b138710f01ffe5e92e453117b987a Mon Sep 17 00:00:00 2001 From: dormando Date: Thu, 25 Aug 2022 10:17:34 -0700 Subject: core: make large item storage more reliable When allocating sub-max chunks for the tail end of a large item the allocator would only look at the exact slab class. If items in a cache are all exclusively large, these slab classes could be empty. Now as a fallback it will also check and evict from the largest slab class even if it doeesn't necessarily want the largest chunk. --- items.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/items.c b/items.c index e5347cc..c526310 100644 --- a/items.c +++ b/items.c @@ -226,8 +226,23 @@ item_chunk *do_item_alloc_chunk(item_chunk *ch, const size_t bytes_remain) { unsigned int id = slabs_clsid(size); item_chunk *nch = (item_chunk *) do_item_alloc_pull(size, id); - if (nch == NULL) - return NULL; + if (nch == NULL) { + // The final chunk in a large item will attempt to be a more + // appropriately sized chunk to minimize memory overhead. However, if + // there's no memory available in the lower slab classes we fail the + // SET. In these cases as a fallback we ensure we attempt to evict a + // max-size item and reuse a large chunk. + if (size == settings.slab_chunk_size_max) { + return NULL; + } else { + size = settings.slab_chunk_size_max; + id = slabs_clsid(size); + nch = (item_chunk *) do_item_alloc_pull(size, id); + + if (nch == NULL) + return NULL; + } + } // link in. // ITEM_CHUNK[ED] bits need to be protected by the slabs lock. -- cgit v1.2.1