aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Hill <daniel@gluo.nz>2023-11-21 01:43:52 +1300
committerKent Overstreet <kent.overstreet@linux.dev>2023-11-24 19:54:11 -0500
commit326d7c1b3b8ff8e0bd1dda46ad83a5bf27080e21 (patch)
treeee936c8c615d4632da0ba1b5de03e94a306c5c3f
parentfbad1bfdf3ebbe70afd3f936de59fa3fc47614d7 (diff)
downloadbcachefs-tools-326d7c1b3b8ff8e0bd1dda46ad83a5bf27080e21.tar.gz
improve kmalloc performance
Reading from /proc/meminfo is really slow We don't want to start swapping to disk. Deceptively, memory available goes up when we start to swap to disk making performance even worse. To mitigate this: 1. replace reading from meminfo with proper system calls. 2. attempt to lock allocations in physical memory space. 3. check our own allocated memory instead of available memory. 4. still check available memory in the off chance we're trying to play nice with other apps. Signed-off-by: Daniel Hill <daniel@gluo.nz> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--bcachefs.c2
-rw-r--r--linux/shrinker.c44
2 files changed, 12 insertions, 34 deletions
diff --git a/bcachefs.c b/bcachefs.c
index 4efe29ed..b209f63c 100644
--- a/bcachefs.c
+++ b/bcachefs.c
@@ -187,6 +187,8 @@ static int subvolume_cmds(int argc, char *argv[])
int main(int argc, char *argv[])
{
+ /* we don't want to swap */
+ mlockall(MCL_FUTURE);
raid_init();
full_cmd = argv[0];
diff --git a/linux/shrinker.c b/linux/shrinker.c
index eae2df6a..dae3d293 100644
--- a/linux/shrinker.c
+++ b/linux/shrinker.c
@@ -1,5 +1,6 @@
#include <stdio.h>
+#include <unistd.h>
#include <linux/kthread.h>
#include <linux/list.h>
@@ -37,39 +38,14 @@ struct meminfo {
u64 available;
};
-static u64 parse_meminfo_line(const char *line)
-{
- u64 v;
-
- if (sscanf(line, " %llu kB", &v) < 1)
- die("sscanf error");
- return v << 10;
-}
-
void si_meminfo(struct sysinfo *val)
{
- size_t len, n = 0;
- char *line = NULL;
- const char *v;
- FILE *f;
-
+ long page_size = sysconf(_SC_PAGESIZE);
memset(val, 0, sizeof(*val));
val->mem_unit = 1;
- f = fopen("/proc/meminfo", "r");
- if (!f)
- return;
-
- while ((len = getline(&line, &n, f)) != -1) {
- if ((v = strcmp_prefix(line, "MemTotal:")))
- val->totalram = parse_meminfo_line(v);
-
- if ((v = strcmp_prefix(line, "MemAvailable:")))
- val->freeram = parse_meminfo_line(v);
- }
-
- fclose(f);
- free(line);
+ val->totalram = sysconf(_SC_PHYS_PAGES) * page_size;
+ val->freeram = sysconf(_SC_AVPHYS_PAGES) * page_size;
}
static void run_shrinkers_allocation_failed(gfp_t gfp_mask)
@@ -93,6 +69,7 @@ void run_shrinkers(gfp_t gfp_mask, bool allocation_failed)
{
struct shrinker *shrinker;
struct sysinfo info;
+ struct mallinfo2 malloc_info = mallinfo2();
s64 want_shrink;
if (!(gfp_mask & GFP_KERNEL))
@@ -109,16 +86,15 @@ void run_shrinkers(gfp_t gfp_mask, bool allocation_failed)
si_meminfo(&info);
- if (info.totalram && info.freeram) {
- want_shrink = (info.totalram >> 2) - info.freeram;
+ if (info.totalram && info.totalram >> 4 < info.freeram) {
+ /* freeram goes up when system swaps, use malloced data instead */
+ want_shrink = -malloc_info.arena + (info.totalram / 10 * 8);
if (want_shrink <= 0)
return;
} else {
- /* If we weren't able to read /proc/meminfo, we must be pretty
- * low: */
-
- want_shrink = 8 << 20;
+ /* We want to play nice with other apps keep 6% avaliable, free 3% */
+ want_shrink = (info.totalram >> 5);
}
mutex_lock(&shrinker_lock);