You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.1 KiB
82 lines
3.1 KiB
2 years ago
|
From de72fa6b0582b95216215cc1400412fe91bc8ba3 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||
|
Date: Tue, 22 Jan 2019 16:12:52 +0100
|
||
|
Subject: [PATCH] journal: limit the number of entries in the cache based on
|
||
|
available memory
|
||
|
|
||
|
This is far from perfect, but should give mostly reasonable values. My
|
||
|
assumption is that if somebody has a few hundred MB of memory, they are
|
||
|
unlikely to have thousands of processes logging. A hundred would already be a
|
||
|
lot. So let's scale the cache size propritionally to the total memory size,
|
||
|
with clamping on both ends.
|
||
|
|
||
|
The formula gives 64 cache entries for each GB of RAM.
|
||
|
|
||
|
(cherry-picked from commit b12a480829c5ca8f4d4fa9cde8716b5f2f12a3ad)
|
||
|
|
||
|
Related: #1664976
|
||
|
---
|
||
|
src/journal/journald-context.c | 35 ++++++++++++++++++++++++++++++++--
|
||
|
1 file changed, 33 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
|
||
|
index ce07de1bfb..0f0dc1de4d 100644
|
||
|
--- a/src/journal/journald-context.c
|
||
|
+++ b/src/journal/journald-context.c
|
||
|
@@ -14,6 +14,7 @@
|
||
|
#include "journal-util.h"
|
||
|
#include "journald-context.h"
|
||
|
#include "process-util.h"
|
||
|
+#include "procfs-util.h"
|
||
|
#include "string-util.h"
|
||
|
#include "syslog-util.h"
|
||
|
#include "unaligned.h"
|
||
|
@@ -58,7 +59,37 @@
|
||
|
/* Keep at most 16K entries in the cache. (Note though that this limit may be violated if enough streams pin entries in
|
||
|
* the cache, in which case we *do* permit this limit to be breached. That's safe however, as the number of stream
|
||
|
* clients itself is limited.) */
|
||
|
-#define CACHE_MAX (16*1024)
|
||
|
+#define CACHE_MAX_FALLBACK 128U
|
||
|
+#define CACHE_MAX_MAX (16*1024U)
|
||
|
+#define CACHE_MAX_MIN 64U
|
||
|
+
|
||
|
+static size_t cache_max(void) {
|
||
|
+ static size_t cached = -1;
|
||
|
+
|
||
|
+ if (cached == (size_t) -1) {
|
||
|
+ uint64_t mem_total;
|
||
|
+ int r;
|
||
|
+
|
||
|
+ r = procfs_memory_get(&mem_total, NULL);
|
||
|
+ if (r < 0) {
|
||
|
+ log_warning_errno(r, "Cannot query /proc/meminfo for MemTotal: %m");
|
||
|
+ cached = CACHE_MAX_FALLBACK;
|
||
|
+ } else {
|
||
|
+ /* Cache entries are usually a few kB, but the process cmdline is controlled by the
|
||
|
+ * user and can be up to _SC_ARG_MAX, usually 2MB. Let's say that approximately up to
|
||
|
+ * 1/8th of memory may be used by the cache.
|
||
|
+ *
|
||
|
+ * In the common case, this formula gives 64 cache entries for each GB of RAM.
|
||
|
+ */
|
||
|
+ long l = sysconf(_SC_ARG_MAX);
|
||
|
+ assert(l > 0);
|
||
|
+
|
||
|
+ cached = CLAMP(mem_total / 8 / (uint64_t) l, CACHE_MAX_MIN, CACHE_MAX_MAX);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return cached;
|
||
|
+}
|
||
|
|
||
|
static int client_context_compare(const void *a, const void *b) {
|
||
|
const ClientContext *x = a, *y = b;
|
||
|
@@ -587,7 +618,7 @@ static int client_context_get_internal(
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
- client_context_try_shrink_to(s, CACHE_MAX-1);
|
||
|
+ client_context_try_shrink_to(s, cache_max()-1);
|
||
|
|
||
|
r = client_context_new(s, pid, &c);
|
||
|
if (r < 0)
|