mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
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
(cherry picked from commit 176f73272e
)
This commit is contained in:
parent
933686348b
commit
3dcde32fed
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user