From: werner@suse.de Upstream: marked as openSUSE-specific fix originally, but may well worth be to be sent upstream. Original description: (none) Notes [jengelh@inai.de]: MAP_NONBLOCK is documented (mmap(2) in man-pages-3.69+) to render MAP_POPULATE ineffective. Why do we have it? What is the rationale for MAP_STACK? --- src/journal/catalog.c | 12 +++++++++++- src/journal/journal-authenticate.c | 7 +++++-- src/journal/journald-kmsg.c | 3 ++- src/journal/mmap-cache.c | 16 +++++++++++++++- 4 files changed, 33 insertions(+), 5 deletions(-) Index: systemd/src/journal/catalog.c =================================================================== --- systemd.orig/src/journal/catalog.c +++ systemd/src/journal/catalog.c @@ -470,6 +470,10 @@ finish: static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p) { const CatalogHeader *h; + static const unsigned int advice[] = + {MADV_WILLNEED, MADV_SEQUENTIAL, MADV_DONTDUMP, MADV_DONTFORK}; + unsigned int n; + size_t psize; int fd; void *p; struct stat st; @@ -492,12 +496,18 @@ static int open_mmap(const char *databas return -EINVAL; } - p = mmap(NULL, PAGE_ALIGN(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + psize = PAGE_ALIGN(st.st_size); + p = mmap(NULL, psize, PROT_READ, MAP_SHARED | MAP_POPULATE | + MAP_NONBLOCK, fd, 0); if (p == MAP_FAILED) { safe_close(fd); return -errno; } + for (n = 0; n < sizeof(advice) / sizeof(*advice); ++n) + if (madvise(p, psize, advice[n]) < 0) + log_warning("Failed to give advice about use of memory: %m"); + h = p; if (memcmp(h->signature, CATALOG_SIGNATURE, sizeof(h->signature)) != 0 || le64toh(h->header_size) < sizeof(CatalogHeader) || Index: systemd/src/journal/journal-authenticate.c =================================================================== --- systemd.orig/src/journal/journal-authenticate.c +++ systemd/src/journal/journal-authenticate.c @@ -355,7 +355,8 @@ int journal_file_fss_load(JournalFile *f goto finish; } - m = mmap(NULL, PAGE_ALIGN(sizeof(FSSHeader)), PROT_READ, MAP_SHARED, fd, 0); + m = mmap(NULL, PAGE_ALIGN(sizeof(FSSHeader)), PROT_READ, + MAP_SHARED | MAP_STACK, fd, 0); if (m == MAP_FAILED) { m = NULL; r = -errno; @@ -399,7 +400,9 @@ int journal_file_fss_load(JournalFile *f goto finish; } - f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_STACK, + fd, 0); if (f->fss_file == MAP_FAILED) { f->fss_file = NULL; r = -errno; Index: systemd/src/journal/journald-kmsg.c =================================================================== --- systemd.orig/src/journal/journald-kmsg.c +++ systemd/src/journal/journald-kmsg.c @@ -454,7 +454,8 @@ int server_open_kernel_seqnum(Server *s) return 0; } - p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + p = mmap(NULL, sizeof(uint64_t), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_STACK, fd, 0); if (p == MAP_FAILED) { log_error_errno(errno, "Failed to map sequential number file, ignoring: %m"); return 0; Index: systemd/src/journal/mmap-cache.c =================================================================== --- systemd.orig/src/journal/mmap-cache.c +++ systemd/src/journal/mmap-cache.c @@ -467,11 +467,14 @@ static int add_mmap( struct stat *st, void **ret) { + static const unsigned int advice[] = + {MADV_WILLNEED, MADV_SEQUENTIAL, MADV_DONTDUMP, MADV_DONTFORK}; uint64_t woffset, wsize; Context *c; FileDescriptor *f; Window *w; void *d; + unsigned int n; int r; assert(m); @@ -510,7 +513,8 @@ static int add_mmap( } for (;;) { - d = mmap(NULL, wsize, prot, MAP_SHARED, fd, woffset); + d = mmap(NULL, wsize, prot, MAP_SHARED | MAP_POPULATE | + MAP_NONBLOCK, fd, woffset); if (d != MAP_FAILED) break; if (errno != ENOMEM) @@ -523,6 +527,16 @@ static int add_mmap( return -ENOMEM; } + for (n = 0; n < sizeof(advice) / sizeof(*advice); ++n) { + if (advice[n] == MADV_DONTFORK) { + int flags = fcntl(fd, F_GETFD); + if (flags < 0 || !(flags & FD_CLOEXEC)) + continue; + } + if (madvise(d, wsize, advice[n]) < 0) + log_warning("Failed to give advice about use of memory: %m"); + } + c = context_add(m, context); if (!c) goto outofmem;