1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-18 13:44:19 +03:00

Add support for basic NUMA awareness

Add basic NUMA awareness routines, using a minimal src/port/pg_numa.c
portability wrapper and an optional build dependency, enabled by
--with-libnuma configure option. For now this is Linux-only, other
platforms may be supported later.

A built-in SQL function pg_numa_available() allows checking NUMA
support, i.e. that the server was built/linked with the NUMA library.

The main function introduced is pg_numa_query_pages(), which allows
determining the NUMA node for individual memory pages. Internally the
function uses move_pages(2) syscall, as it allows batching, and is more
efficient than get_mempolicy(2).

Author: Jakub Wartak <jakub.wartak@enterprisedb.com>
Co-authored-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Discussion: https://postgr.es/m/CAKZiRmxh6KWo0aqRqvmcoaX2jUxZYb4kGp3N%3Dq1w%2BDiH-696Xw%40mail.gmail.com
This commit is contained in:
Tomas Vondra 2025-04-07 22:51:49 +02:00
parent 17bcf4f545
commit 65c298f61f
18 changed files with 444 additions and 3 deletions

View File

@ -471,6 +471,7 @@ task:
--enable-cassert --enable-injection-points --enable-debug \ --enable-cassert --enable-injection-points --enable-debug \
--enable-tap-tests --enable-nls \ --enable-tap-tests --enable-nls \
--with-segsize-blocks=6 \ --with-segsize-blocks=6 \
--with-libnuma \
--with-liburing \ --with-liburing \
\ \
${LINUX_CONFIGURE_FEATURES} \ ${LINUX_CONFIGURE_FEATURES} \
@ -523,6 +524,7 @@ task:
-Dllvm=disabled \ -Dllvm=disabled \
--pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
-DPERL=perl5.36-i386-linux-gnu \ -DPERL=perl5.36-i386-linux-gnu \
-Dlibnuma=disabled \
build-32 build-32
EOF EOF

187
configure vendored
View File

@ -708,6 +708,9 @@ XML2_LIBS
XML2_CFLAGS XML2_CFLAGS
XML2_CONFIG XML2_CONFIG
with_libxml with_libxml
LIBNUMA_LIBS
LIBNUMA_CFLAGS
with_libnuma
LIBCURL_LIBS LIBCURL_LIBS
LIBCURL_CFLAGS LIBCURL_CFLAGS
with_libcurl with_libcurl
@ -872,6 +875,7 @@ with_liburing
with_uuid with_uuid
with_ossp_uuid with_ossp_uuid
with_libcurl with_libcurl
with_libnuma
with_libxml with_libxml
with_libxslt with_libxslt
with_system_tzdata with_system_tzdata
@ -906,6 +910,8 @@ LIBURING_CFLAGS
LIBURING_LIBS LIBURING_LIBS
LIBCURL_CFLAGS LIBCURL_CFLAGS
LIBCURL_LIBS LIBCURL_LIBS
LIBNUMA_CFLAGS
LIBNUMA_LIBS
XML2_CONFIG XML2_CONFIG
XML2_CFLAGS XML2_CFLAGS
XML2_LIBS XML2_LIBS
@ -1588,6 +1594,7 @@ Optional Packages:
--with-uuid=LIB build contrib/uuid-ossp using LIB (bsd,e2fs,ossp) --with-uuid=LIB build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)
--with-ossp-uuid obsolete spelling of --with-uuid=ossp --with-ossp-uuid obsolete spelling of --with-uuid=ossp
--with-libcurl build with libcurl support --with-libcurl build with libcurl support
--with-libnuma build with libnuma support
--with-libxml build with XML support --with-libxml build with XML support
--with-libxslt use XSLT support when building contrib/xml2 --with-libxslt use XSLT support when building contrib/xml2
--with-system-tzdata=DIR --with-system-tzdata=DIR
@ -1629,6 +1636,10 @@ Some influential environment variables:
C compiler flags for LIBCURL, overriding pkg-config C compiler flags for LIBCURL, overriding pkg-config
LIBCURL_LIBS LIBCURL_LIBS
linker flags for LIBCURL, overriding pkg-config linker flags for LIBCURL, overriding pkg-config
LIBNUMA_CFLAGS
C compiler flags for LIBNUMA, overriding pkg-config
LIBNUMA_LIBS
linker flags for LIBNUMA, overriding pkg-config
XML2_CONFIG path to xml2-config utility XML2_CONFIG path to xml2-config utility
XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_CFLAGS C compiler flags for XML2, overriding pkg-config
XML2_LIBS linker flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config
@ -9063,6 +9074,182 @@ $as_echo "$as_me: WARNING: *** OAuth support tests require --with-python to run"
fi fi
#
# libnuma
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with libnuma support" >&5
$as_echo_n "checking whether to build with libnuma support... " >&6; }
# Check whether --with-libnuma was given.
if test "${with_libnuma+set}" = set; then :
withval=$with_libnuma;
case $withval in
yes)
$as_echo "#define USE_LIBNUMA 1" >>confdefs.h
;;
no)
:
;;
*)
as_fn_error $? "no argument expected for --with-libnuma option" "$LINENO" 5
;;
esac
else
with_libnuma=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_libnuma" >&5
$as_echo "$with_libnuma" >&6; }
if test "$with_libnuma" = yes ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for numa_available in -lnuma" >&5
$as_echo_n "checking for numa_available in -lnuma... " >&6; }
if ${ac_cv_lib_numa_numa_available+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lnuma $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char numa_available ();
int
main ()
{
return numa_available ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_numa_numa_available=yes
else
ac_cv_lib_numa_numa_available=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_numa_numa_available" >&5
$as_echo "$ac_cv_lib_numa_numa_available" >&6; }
if test "x$ac_cv_lib_numa_numa_available" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBNUMA 1
_ACEOF
LIBS="-lnuma $LIBS"
else
as_fn_error $? "library 'libnuma' is required for NUMA support" "$LINENO" 5
fi
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for numa" >&5
$as_echo_n "checking for numa... " >&6; }
if test -n "$LIBNUMA_CFLAGS"; then
pkg_cv_LIBNUMA_CFLAGS="$LIBNUMA_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"numa\""; } >&5
($PKG_CONFIG --exists --print-errors "numa") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LIBNUMA_CFLAGS=`$PKG_CONFIG --cflags "numa" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$LIBNUMA_LIBS"; then
pkg_cv_LIBNUMA_LIBS="$LIBNUMA_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"numa\""; } >&5
($PKG_CONFIG --exists --print-errors "numa") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LIBNUMA_LIBS=`$PKG_CONFIG --libs "numa" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
LIBNUMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "numa" 2>&1`
else
LIBNUMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "numa" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$LIBNUMA_PKG_ERRORS" >&5
as_fn_error $? "Package requirements (numa) were not met:
$LIBNUMA_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables LIBNUMA_CFLAGS
and LIBNUMA_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
Alternatively, you may set the environment variables LIBNUMA_CFLAGS
and LIBNUMA_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
See \`config.log' for more details" "$LINENO" 5; }
else
LIBNUMA_CFLAGS=$pkg_cv_LIBNUMA_CFLAGS
LIBNUMA_LIBS=$pkg_cv_LIBNUMA_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
fi
# #
# XML # XML
# #

View File

@ -1053,6 +1053,20 @@ if test "$with_libcurl" = yes ; then
fi fi
#
# libnuma
#
AC_MSG_CHECKING([whether to build with libnuma support])
PGAC_ARG_BOOL(with, libnuma, no, [build with libnuma support],
[AC_DEFINE([USE_LIBNUMA], 1, [Define to build with NUMA support. (--with-libnuma)])])
AC_MSG_RESULT([$with_libnuma])
AC_SUBST(with_libnuma)
if test "$with_libnuma" = yes ; then
AC_CHECK_LIB(numa, numa_available, [], [AC_MSG_ERROR([library 'libnuma' is required for NUMA support])])
PKG_CHECK_MODULES(LIBNUMA, numa)
fi
# #
# XML # XML
# #

View File

@ -25143,6 +25143,19 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
</para></entry> </para></entry>
</row> </row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>pg_numa_available</primary>
</indexterm>
<function>pg_numa_available</function> ()
<returnvalue>boolean</returnvalue>
</para>
<para>
Returns true if the server has been compiled with <acronym>NUMA</acronym> support.
</para></entry>
</row>
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm> <indexterm>

View File

@ -1156,6 +1156,17 @@ build-postgresql:
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="configure-option-with-libnuma">
<term><option>--with-libnuma</option></term>
<listitem>
<para>
Build with libnuma support for basic NUMA support.
Only supported on platforms for which the <productname>libnuma</productname>
library is implemented.
</para>
</listitem>
</varlistentry>
<varlistentry id="configure-option-with-liburing"> <varlistentry id="configure-option-with-liburing">
<term><option>--with-liburing</option></term> <term><option>--with-liburing</option></term>
<listitem> <listitem>
@ -2645,6 +2656,17 @@ ninja install
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="configure-with-libnuma-meson">
<term><option>-Dlibnuma={ auto | enabled | disabled }</option></term>
<listitem>
<para>
Build with libnuma support for basic NUMA support.
Only supported on platforms for which the <productname>libnuma</productname>
library is implemented. The default for this option is auto.
</para>
</listitem>
</varlistentry>
<varlistentry id="configure-with-libxml-meson"> <varlistentry id="configure-with-libxml-meson">
<term><option>-Dlibxml={ auto | enabled | disabled }</option></term> <term><option>-Dlibxml={ auto | enabled | disabled }</option></term>
<listitem> <listitem>

View File

@ -943,6 +943,27 @@ else
endif endif
###############################################################
# Library: libnuma
###############################################################
libnumaopt = get_option('libnuma')
if not libnumaopt.disabled()
# via pkg-config
libnuma = dependency('numa', required: false)
if not libnuma.found()
libnuma = cc.find_library('numa', required: libnumaopt)
endif
if not cc.has_header('numa.h', dependencies: libnuma, required: libnumaopt)
libnuma = not_found_dep
endif
if libnuma.found()
cdata.set('USE_LIBNUMA', 1)
endif
else
libnuma = not_found_dep
endif
############################################################### ###############################################################
# Library: liburing # Library: liburing
@ -3279,6 +3300,7 @@ backend_both_deps += [
icu_i18n, icu_i18n,
ldap, ldap,
libintl, libintl,
libnuma,
liburing, liburing,
libxml, libxml,
lz4, lz4,
@ -3935,6 +3957,7 @@ if meson.version().version_compare('>=0.57')
'icu': icu, 'icu': icu,
'ldap': ldap, 'ldap': ldap,
'libcurl': libcurl, 'libcurl': libcurl,
'libnuma': libnuma,
'liburing': liburing, 'liburing': liburing,
'libxml': libxml, 'libxml': libxml,
'libxslt': libxslt, 'libxslt': libxslt,

View File

@ -106,6 +106,9 @@ option('libcurl', type : 'feature', value: 'auto',
option('libedit_preferred', type: 'boolean', value: false, option('libedit_preferred', type: 'boolean', value: false,
description: 'Prefer BSD Libedit over GNU Readline') description: 'Prefer BSD Libedit over GNU Readline')
option('libnuma', type: 'feature', value: 'auto',
description: 'NUMA support')
option('liburing', type : 'feature', value: 'auto', option('liburing', type : 'feature', value: 'auto',
description: 'io_uring support, for asynchronous I/O') description: 'io_uring support, for asynchronous I/O')

View File

@ -196,6 +196,7 @@ with_gssapi = @with_gssapi@
with_krb_srvnam = @with_krb_srvnam@ with_krb_srvnam = @with_krb_srvnam@
with_ldap = @with_ldap@ with_ldap = @with_ldap@
with_libcurl = @with_libcurl@ with_libcurl = @with_libcurl@
with_libnuma = @with_libnuma@
with_liburing = @with_liburing@ with_liburing = @with_liburing@
with_libxml = @with_libxml@ with_libxml = @with_libxml@
with_libxslt = @with_libxslt@ with_libxslt = @with_libxslt@
@ -223,6 +224,9 @@ krb_srvtab = @krb_srvtab@
ICU_CFLAGS = @ICU_CFLAGS@ ICU_CFLAGS = @ICU_CFLAGS@
ICU_LIBS = @ICU_LIBS@ ICU_LIBS = @ICU_LIBS@
LIBNUMA_CFLAGS = @LIBNUMA_CFLAGS@
LIBNUMA_LIBS = @LIBNUMA_LIBS@
LIBURING_CFLAGS = @LIBURING_CFLAGS@ LIBURING_CFLAGS = @LIBURING_CFLAGS@
LIBURING_LIBS = @LIBURING_LIBS@ LIBURING_LIBS = @LIBURING_LIBS@
@ -250,7 +254,7 @@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
PG_SYSROOT = @PG_SYSROOT@ PG_SYSROOT = @PG_SYSROOT@
override CPPFLAGS := $(ICU_CFLAGS) $(LIBURING_CFLAGS) $(CPPFLAGS) override CPPFLAGS := $(ICU_CFLAGS) $(LIBNUMA_CFLAGS) $(LIBURING_CFLAGS) $(CPPFLAGS)
ifdef PGXS ifdef PGXS
override CPPFLAGS := -I$(includedir_server) -I$(includedir_internal) $(CPPFLAGS) override CPPFLAGS := -I$(includedir_server) -I$(includedir_internal) $(CPPFLAGS)

View File

@ -566,7 +566,7 @@ static int ssl_renegotiation_limit;
*/ */
int huge_pages = HUGE_PAGES_TRY; int huge_pages = HUGE_PAGES_TRY;
int huge_page_size; int huge_page_size;
static int huge_pages_status = HUGE_PAGES_UNKNOWN; int huge_pages_status = HUGE_PAGES_UNKNOWN;
/* /*
* These variables are all dummies that don't do anything, except in some * These variables are all dummies that don't do anything, except in some

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202504071 #define CATALOG_VERSION_NO 202504072
#endif #endif

View File

@ -8542,6 +8542,10 @@
proargnames => '{name,off,size,allocated_size}', proargnames => '{name,off,size,allocated_size}',
prosrc => 'pg_get_shmem_allocations' }, prosrc => 'pg_get_shmem_allocations' },
{ oid => '4099', descr => 'Is NUMA support available?',
proname => 'pg_numa_available', provolatile => 's', prorettype => 'bool',
proargtypes => '', prosrc => 'pg_numa_available' },
# memory context of local backend # memory context of local backend
{ oid => '2282', { oid => '2282',
descr => 'information about all memory contexts of local backend', descr => 'information about all memory contexts of local backend',

View File

@ -689,6 +689,9 @@
/* Define to 1 to build with libcurl support. (--with-libcurl) */ /* Define to 1 to build with libcurl support. (--with-libcurl) */
#undef USE_LIBCURL #undef USE_LIBCURL
/* Define to 1 to build with NUMA support. (--with-libnuma) */
#undef USE_LIBNUMA
/* Define to build with io_uring support. (--with-liburing) */ /* Define to build with io_uring support. (--with-liburing) */
#undef USE_LIBURING #undef USE_LIBURING

View File

@ -0,0 +1,40 @@
/*-------------------------------------------------------------------------
*
* pg_numa.h
* Basic NUMA portability routines
*
*
* Copyright (c) 2025, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/include/port/pg_numa.h
*
*-------------------------------------------------------------------------
*/
#ifndef PG_NUMA_H
#define PG_NUMA_H
#include "fmgr.h"
extern PGDLLIMPORT int pg_numa_init(void);
extern PGDLLIMPORT int pg_numa_query_pages(int pid, unsigned long count, void **pages, int *status);
extern PGDLLIMPORT int pg_numa_get_max_node(void);
extern PGDLLIMPORT Size pg_numa_get_pagesize(void);
#ifdef USE_LIBNUMA
/*
* This is required on Linux, before pg_numa_query_pages() as we
* need to page-fault before move_pages(2) syscall returns valid results.
*/
#define pg_numa_touch_mem_if_required(ro_volatile_var, ptr) \
ro_volatile_var = *(volatile uint64 *) ptr
#else
#define pg_numa_touch_mem_if_required(ro_volatile_var, ptr) \
do {} while(0)
#endif
#endif /* PG_NUMA_H */

View File

@ -45,6 +45,7 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
extern PGDLLIMPORT int shared_memory_type; extern PGDLLIMPORT int shared_memory_type;
extern PGDLLIMPORT int huge_pages; extern PGDLLIMPORT int huge_pages;
extern PGDLLIMPORT int huge_page_size; extern PGDLLIMPORT int huge_page_size;
extern PGDLLIMPORT int huge_pages_status;
/* Possible values for huge_pages and huge_pages_status */ /* Possible values for huge_pages and huge_pages_status */
typedef enum typedef enum

View File

@ -200,6 +200,8 @@ pgxs_empty = [
'ICU_LIBS', 'ICU_LIBS',
'LIBNUMA_CFLAGS', 'LIBNUMA_LIBS',
'LIBURING_CFLAGS', 'LIBURING_LIBS', 'LIBURING_CFLAGS', 'LIBURING_LIBS',
] ]
@ -232,6 +234,7 @@ pgxs_deps = {
'icu': icu, 'icu': icu,
'ldap': ldap, 'ldap': ldap,
'libcurl': libcurl, 'libcurl': libcurl,
'libnuma': libnuma,
'liburing': liburing, 'liburing': liburing,
'libxml': libxml, 'libxml': libxml,
'libxslt': libxslt, 'libxslt': libxslt,

View File

@ -45,6 +45,7 @@ OBJS = \
path.o \ path.o \
pg_bitutils.o \ pg_bitutils.o \
pg_localeconv_r.o \ pg_localeconv_r.o \
pg_numa.o \
pg_popcount_aarch64.o \ pg_popcount_aarch64.o \
pg_popcount_avx512.o \ pg_popcount_avx512.o \
pg_strong_random.o \ pg_strong_random.o \

View File

@ -8,6 +8,7 @@ pgport_sources = [
'path.c', 'path.c',
'pg_bitutils.c', 'pg_bitutils.c',
'pg_localeconv_r.c', 'pg_localeconv_r.c',
'pg_numa.c',
'pg_popcount_aarch64.c', 'pg_popcount_aarch64.c',
'pg_popcount_avx512.c', 'pg_popcount_avx512.c',
'pg_strong_random.c', 'pg_strong_random.c',

120
src/port/pg_numa.c Normal file
View File

@ -0,0 +1,120 @@
/*-------------------------------------------------------------------------
*
* pg_numa.c
* Basic NUMA portability routines
*
*
* Copyright (c) 2025, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src/port/pg_numa.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <unistd.h>
#ifdef WIN32
#include <windows.h>
#endif
#include "fmgr.h"
#include "miscadmin.h"
#include "port/pg_numa.h"
#include "storage/pg_shmem.h"
/*
* At this point we provide support only for Linux thanks to libnuma, but in
* future support for other platforms e.g. Win32 or FreeBSD might be possible
* too. For Win32 NUMA APIs see
* https://learn.microsoft.com/en-us/windows/win32/procthread/numa-support
*/
#ifdef USE_LIBNUMA
#include <numa.h>
#include <numaif.h>
Datum pg_numa_available(PG_FUNCTION_ARGS);
/* libnuma requires initialization as per numa(3) on Linux */
int
pg_numa_init(void)
{
int r = numa_available();
return r;
}
/*
* We use move_pages(2) syscall here - instead of get_mempolicy(2) - as the
* first one allows us to batch and query about many memory pages in one single
* giant system call that is way faster.
*/
int
pg_numa_query_pages(int pid, unsigned long count, void **pages, int *status)
{
return numa_move_pages(pid, count, pages, NULL, status, 0);
}
int
pg_numa_get_max_node(void)
{
return numa_max_node();
}
#else
Datum pg_numa_available(PG_FUNCTION_ARGS);
/* Empty wrappers */
int
pg_numa_init(void)
{
/* We state that NUMA is not available */
return -1;
}
int
pg_numa_query_pages(int pid, unsigned long count, void **pages, int *status)
{
return 0;
}
int
pg_numa_get_max_node(void)
{
return 0;
}
#endif
Datum
pg_numa_available(PG_FUNCTION_ARGS)
{
PG_RETURN_BOOL(pg_numa_init() != -1);
}
/* This should be used only after the server is started */
Size
pg_numa_get_pagesize(void)
{
Size os_page_size;
#ifdef WIN32
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
os_page_size = sysinfo.dwPageSize;
#else
os_page_size = sysconf(_SC_PAGESIZE);
#endif
Assert(IsUnderPostmaster);
Assert(huge_pages_status != HUGE_PAGES_UNKNOWN);
if (huge_pages_status == HUGE_PAGES_ON)
GetHugePageSize(&os_page_size, NULL);
return os_page_size;
}