From 9cde401f87937c1982f2355c8f81449514166376 Mon Sep 17 00:00:00 2001 From: John Naylor Date: Mon, 31 Oct 2022 13:59:30 +0700 Subject: [PATCH v1 2/2] Put all non-cold .text in huge pages Tell linker to align addresses on 2MB boundaries. The .init section will be so aligned, with the .text section soon after that. Therefore, the start address of .text should always be align up to nearly 2MB ahead of the actual start. The first nearly 2MB of .text will not map to huge pages. We count on cold sections linking to the front of the .text segment: Since the cold sections total about 600kB in size, we need ~1.4MB of additional padding to keep non-cold pages mappable to huge pages. Since PG has about 5.0MB of .text, we also need an additional 1MB to push the .text end just past an aligned boundary, so when we align the end down, only a small number of pages will remain un-remapped at their original 4kB size. --- meson.build | 3 +++ src/backend/port/filler.c | 29 +++++++++++++++++++++++++++++ src/backend/port/meson.build | 3 +++ 3 files changed, 35 insertions(+) create mode 100644 src/backend/port/filler.c diff --git a/meson.build b/meson.build index bfacbdc0af..450946370c 100644 --- a/meson.build +++ b/meson.build @@ -239,6 +239,9 @@ elif host_system == 'freebsd' elif host_system == 'linux' sema_kind = 'unnamed_posix' cppflags += '-D_GNU_SOURCE' + # WIP: debug builds are huge + # TODO: add portability check + ldflags += ['-Wl,-zcommon-page-size=2097152', '-Wl,-zmax-page-size=2097152'] elif host_system == 'netbsd' # We must resolve all dynamic linking in the core server at program start. diff --git a/src/backend/port/filler.c b/src/backend/port/filler.c new file mode 100644 index 0000000000..de4e33bb05 --- /dev/null +++ b/src/backend/port/filler.c @@ -0,0 +1,29 @@ +/* + * Add enough padding to .text segment to bring the end just + * past a 2MB alignment boundary. In practice, this means .text needs + * to be at least 8MB. It shouldn't be much larger than this, + * because then more hot pages will remain in 4kB pages. + * + * FIXME: With this filler added, if explicit huge pages are turned off + * in the kernel, attempting mmap() with MAP_HUGETLB causes a crash + * instead of reporting failure if the .text segment is larger than 8MB. + * + * See MapStaticCodeToLargePages() in large_page.c + * + * XXX: The exact amount of filler must be determined experimentally + * on platforms of interest, in non-assert builds. + * + */ +static void +__attribute__((used)) +__attribute__((cold)) +fill_function(int x) +{ + /* TODO: More architectures */ +#ifdef __x86_64__ +__asm__( + ".fill 3251000" +); +#endif + (void) x; +} \ No newline at end of file diff --git a/src/backend/port/meson.build b/src/backend/port/meson.build index 5ab65115e9..d876712e0c 100644 --- a/src/backend/port/meson.build +++ b/src/backend/port/meson.build @@ -16,6 +16,9 @@ if cdata.has('USE_WIN32_SEMAPHORES') endif if cdata.has('USE_SYSV_SHARED_MEMORY') + if host_system == 'linux' + backend_sources += files('filler.c') + endif backend_sources += files('large_page.c') backend_sources += files('sysv_shmem.c') endif -- 2.37.3