From: Yu Watanabe Date: Fri, 29 Sep 2023 19:49:53 +0000 (+0900) Subject: mmap-cache: drop Context and boolean flags in Window X-Git-Tag: v255-rc1~11^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ebc9cc8674c1f3389babb5d6c5d808b6086cd93;p=thirdparty%2Fsystemd.git mmap-cache: drop Context and boolean flags in Window No functional change, just refactoring. --- diff --git a/src/libsystemd/sd-journal/mmap-cache.c b/src/libsystemd/sd-journal/mmap-cache.c index e5e03bf83ca..c4741b2291c 100644 --- a/src/libsystemd/sd-journal/mmap-cache.c +++ b/src/libsystemd/sd-journal/mmap-cache.c @@ -16,14 +16,23 @@ #include "sigbus.h" typedef struct Window Window; -typedef struct Context Context; + +typedef enum WindowFlags { + WINDOW_KEEP_ALWAYS = 1u << (MMAP_CACHE_MAX_CONTEXTS + 0), + WINDOW_IN_UNUSED = 1u << (MMAP_CACHE_MAX_CONTEXTS + 1), + WINDOW_INVALIDATED = 1u << (MMAP_CACHE_MAX_CONTEXTS + 2), + + _WINDOW_USED_MASK = WINDOW_IN_UNUSED - 1, /* The mask contains all bits that indicate the windows + * is currently in use. Covers the all the object types + * and the additional WINDOW_KEEP_ALWAYS flag. */ +} WindowFlags; + +#define WINDOW_IS_UNUSED(w) (((w)->flags & _WINDOW_USED_MASK) == 0) struct Window { MMapFileDescriptor *fd; - bool invalidated:1; - bool keep_always:1; - bool in_unused:1; + WindowFlags flags; void *ptr; uint64_t offset; @@ -31,21 +40,15 @@ struct Window { LIST_FIELDS(Window, windows); LIST_FIELDS(Window, unused); - - LIST_HEAD(Context, contexts); -}; - -struct Context { - Window *window; - - LIST_FIELDS(Context, by_window); }; struct MMapFileDescriptor { MMapCache *cache; + int fd; int prot; bool sigbus; + LIST_HEAD(Window, windows); }; @@ -62,7 +65,7 @@ struct MMapCache { LIST_HEAD(Window, unused); Window *last_unused; - Context contexts[MMAP_CACHE_MAX_CONTEXTS]; + Window *windows_by_context[MMAP_CACHE_MAX_CONTEXTS]; }; #define WINDOWS_MIN 64 @@ -96,17 +99,15 @@ static Window* window_unlink(Window *w) { if (w->ptr) munmap(w->ptr, w->size); - if (w->in_unused) { + if (FLAGS_SET(w->flags, WINDOW_IN_UNUSED)) { if (m->last_unused == w) m->last_unused = w->unused_prev; - LIST_REMOVE(unused, m->unused, w); } - LIST_FOREACH(by_window, c, w->contexts) { - assert(c->window == w); - c->window = NULL; - } + for (unsigned i = 0; i < MMAP_CACHE_MAX_CONTEXTS; i++) + if (FLAGS_SET(w->flags, 1u << i)) + assert_se(TAKE_PTR(m->windows_by_context[i]) == w); return LIST_REMOVE(windows, w->fd->windows, w); } @@ -115,14 +116,14 @@ static void window_invalidate(Window *w) { assert(w); assert(w->fd); - if (w->invalidated) + if (FLAGS_SET(w->flags, WINDOW_INVALIDATED)) return; /* Replace the window with anonymous pages. This is useful when we hit a SIGBUS and want to make sure * the file cannot trigger any further SIGBUS, possibly overrunning the sigbus queue. */ assert_se(mmap(w->ptr, w->size, w->fd->prot, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0) == w->ptr); - w->invalidated = true; + w->flags |= WINDOW_INVALIDATED; } static Window* window_free(Window *w) { @@ -169,19 +170,20 @@ static Window* window_add(MMapFileDescriptor *f, uint64_t offset, size_t size, v return LIST_PREPEND(windows, f->windows, w); } -static void context_detach_window(MMapCache *m, Context *c) { +static void context_detach_window(MMapCache *m, unsigned c) { Window *w; assert(m); - assert(c); + assert(c < MMAP_CACHE_MAX_CONTEXTS); - if (!c->window) - return; + w = TAKE_PTR(m->windows_by_context[c]); + if (!w) + return; /* Nothing attached. */ - w = TAKE_PTR(c->window); - LIST_REMOVE(by_window, w->contexts, c); + assert(FLAGS_SET(w->flags, 1u << c)); + w->flags &= ~(1u << c); - if (!w->contexts && !w->keep_always) { + if (WINDOW_IS_UNUSED(w)) { /* Not used anymore? */ #if ENABLE_DEBUG_MMAP_CACHE /* Unmap unused windows immediately to expose use-after-unmap by SIGSEGV. */ @@ -190,33 +192,31 @@ static void context_detach_window(MMapCache *m, Context *c) { LIST_PREPEND(unused, m->unused, w); if (!m->last_unused) m->last_unused = w; - - w->in_unused = true; + w->flags |= WINDOW_IN_UNUSED; #endif } } -static void context_attach_window(MMapCache *m, Context *c, Window *w) { +static void context_attach_window(MMapCache *m, unsigned c, Window *w) { assert(m); - assert(c); + assert(c < MMAP_CACHE_MAX_CONTEXTS); assert(w); - if (c->window == w) - return; + if (m->windows_by_context[c] == w) + return; /* Already attached. */ context_detach_window(m, c); - if (w->in_unused) { + if (FLAGS_SET(w->flags, WINDOW_IN_UNUSED)) { /* Used again? */ if (m->last_unused == w) m->last_unused = w->unused_prev; LIST_REMOVE(unused, m->unused, w); - - w->in_unused = false; + w->flags &= ~WINDOW_IN_UNUSED; } - c->window = w; - LIST_PREPEND(by_window, w->contexts, c); + m->windows_by_context[c] = w; + w->flags |= (1u << c); } static MMapCache* mmap_cache_free(MMapCache *m) { @@ -322,7 +322,7 @@ static int add_mmap( int mmap_cache_fd_get( MMapFileDescriptor *f, - unsigned context, + unsigned c, bool keep_always, uint64_t offset, size_t size, @@ -330,23 +330,20 @@ int mmap_cache_fd_get( void **ret) { MMapCache *m = mmap_cache_fd_cache(f); - Context *c; Window *w; int r; - assert(context < MMAP_CACHE_MAX_CONTEXTS); assert(size > 0); + assert(c < MMAP_CACHE_MAX_CONTEXTS); assert(ret); if (f->sigbus) return -EIO; - c = &f->cache->contexts[context]; - /* Check whether the current context is the right one already */ - if (window_matches(c->window, f, offset, size)) { + if (window_matches(m->windows_by_context[c], f, offset, size)) { m->n_context_cache_hit++; - w = c->window; + w = m->windows_by_context[c]; goto found; } @@ -369,7 +366,9 @@ int mmap_cache_fd_get( return r; found: - w->keep_always = w->keep_always || keep_always; + if (keep_always) + w->flags |= WINDOW_KEEP_ALWAYS; + context_attach_window(m, c, w); *ret = (uint8_t*) w->ptr + (offset - w->offset); return 0;