diff options
author | dormando <dormando@rydia.net> | 2022-08-25 10:17:34 -0700 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2022-08-26 16:35:12 -0700 |
commit | 597645db6a2b138710f01ffe5e92e453117b987a (patch) | |
tree | 5b7cc7f7b42de79e875836376099ae2d81e100bf /items.c | |
parent | e31abc34f990e12efa57218a3b72d38969c6b142 (diff) | |
download | memcached-597645db6a2b138710f01ffe5e92e453117b987a.tar.gz |
core: make large item storage more reliable1.6.17
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.
Diffstat (limited to 'items.c')
-rw-r--r-- | items.c | 19 |
1 files changed, 17 insertions, 2 deletions
@@ -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. |