summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2022-08-09 11:12:13 +0100
committerPhil Jones <philj56@gmail.com>2022-08-09 12:30:24 +0100
commit81025108db445ab31d7506a88e8919a5eebcadcb (patch)
tree19901e9897b7305fe553089cd05837295ce4bbfc
parent33ec439ca9d1f6a2467703333d8a6189e42bd446 (diff)
Add Transparent HugePage support on Linux.
Currently, this is unlikely to be enabled for shared memory mappings on any user's system, so will not make a difference. If `/sys/kernel/mm/transparent_hugepage/shmem_enabled` is set to `advise` or higher, however, this commit should enable the use of hugepages. This can greatly speed up startup for large windows - for a 2880x1800 fullscreen window on my laptop, enabling hugepages halves startup time. From the kernel mailing lists, it looks like there's some work towards allowing applications to opt-in to THP support regardless of whether they're enabled, via `madvise(MADV_COLLAPSE)`, so this may be more useful in future.
-rw-r--r--src/shm.c12
-rw-r--r--src/surface.c14
2 files changed, 26 insertions, 0 deletions
diff --git a/src/shm.c b/src/shm.c
index e145d4a..9e0833f 100644
--- a/src/shm.c
+++ b/src/shm.c
@@ -34,7 +34,19 @@ static int create_shm_file(void)
int shm_allocate_file(size_t size)
{
+#ifdef __linux__
+ /*
+ * On linux, we can just use memfd_create(). This is both simpler and
+ * potentially allows usage of Transparent HugePages, which speed up
+ * the first paint of a large screen buffer.
+ *
+ * This isn't available on *BSD, which we could conceivably be running
+ * on.
+ */
+ int fd = memfd_create("wl_shm", 0);
+#else
int fd = create_shm_file();
+#endif
if (fd < 0)
return -1;
int ret;
diff --git a/src/surface.c b/src/surface.c
index e640c40..b8ed88e 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -32,6 +32,20 @@ void surface_init(
MAP_SHARED,
surface->shm_pool_fd,
0);
+#ifdef __linux__
+ /*
+ * On linux, ask for Transparent HugePages if available and our
+ * buffer's at least 2MiB. This can greatly speed up the first
+ * cairo_paint() by reducing page faults, but unfortunately is disabled
+ * for shared memory at the time of writing.
+ *
+ * MADV_HUGEPAGE isn't available on *BSD, which we could conceivably be
+ * running on.
+ */
+ if (surface->shm_pool_size >= (2 << 20)) {
+ madvise(surface->shm_pool_data, surface->shm_pool_size, MADV_HUGEPAGE);
+ }
+#endif
surface->wl_shm_pool = wl_shm_create_pool(
wl_shm,
surface->shm_pool_fd,