From: Vito Caputo Date: Sat, 21 Sep 2024 19:30:49 +0000 (-0700) Subject: mmap-cache: enforce an unused windows minimum X-Git-Tag: v257-rc1~243^2~1 X-Git-Url: http://git-history.diyao.me/?a=commitdiff_plain;h=176f73272e6e3116caab3900eb553be54f520a68;p=systemd%2F.git mmap-cache: enforce an unused windows minimum With many fds the global windows count generally exceeds the minimum. This results in always reusing the unused entry if there is one, which becomes a sort of degenerate case where we're just constantly unmapping->mapping. Instead let's try always have at least several unused windows on the unused list before we resort to churning through it. Fixes #34516 --- diff --git a/src/libsystemd/sd-journal/mmap-cache.c b/src/libsystemd/sd-journal/mmap-cache.c index 973ade64c0..249b98a968 100644 --- a/src/libsystemd/sd-journal/mmap-cache.c +++ b/src/libsystemd/sd-journal/mmap-cache.c @@ -64,11 +64,13 @@ struct MMapCache { LIST_HEAD(Window, unused); Window *last_unused; + unsigned n_unused; Window *windows_by_category[_MMAP_CACHE_CATEGORY_MAX]; }; #define WINDOWS_MIN 64 +#define UNUSED_MIN 4 #if ENABLE_DEBUG_MMAP_CACHE /* Tiny windows increase mmap activity and the chance of exposing unsafe use. */ @@ -103,6 +105,7 @@ static Window* window_unlink(Window *w) { if (m->last_unused == w) m->last_unused = w->unused_prev; LIST_REMOVE(unused, m->unused, w); + m->n_unused--; } for (unsigned i = 0; i < _MMAP_CACHE_CATEGORY_MAX; i++) @@ -160,7 +163,7 @@ static Window* window_add(MMapFileDescriptor *f, uint64_t offset, size_t size, v MMapCache *m = mmap_cache_fd_cache(f); Window *w; - if (!m->last_unused || m->n_windows <= WINDOWS_MIN) { + if (!m->last_unused || m->n_windows < WINDOWS_MIN || m->n_unused < UNUSED_MIN) { /* Allocate a new window */ w = new(Window, 1); if (!w) @@ -202,6 +205,7 @@ static void category_detach_window(MMapCache *m, MMapCacheCategory c) { LIST_PREPEND(unused, m->unused, w); if (!m->last_unused) m->last_unused = w; + m->n_unused++; w->flags |= WINDOW_IN_UNUSED; #endif } @@ -222,6 +226,7 @@ static void category_attach_window(MMapCache *m, MMapCacheCategory c, Window *w) if (m->last_unused == w) m->last_unused = w->unused_prev; LIST_REMOVE(unused, m->unused, w); + m->n_unused--; w->flags &= ~WINDOW_IN_UNUSED; } @@ -239,7 +244,7 @@ static MMapCache* mmap_cache_free(MMapCache *m) { assert(hashmap_isempty(m->fds)); hashmap_free(m->fds); - assert(!m->unused); + assert(!m->unused && m->n_unused == 0); assert(m->n_windows == 0); return mfree(m);