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:
parent
17bcf4f545
commit
65c298f61f
@ -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
187
configure
vendored
@ -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
|
||||||
#
|
#
|
||||||
|
14
configure.ac
14
configure.ac
@ -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
|
||||||
#
|
#
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
23
meson.build
23
meson.build
@ -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,
|
||||||
|
@ -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')
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202504071
|
#define CATALOG_VERSION_NO 202504072
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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',
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
40
src/include/port/pg_numa.h
Normal file
40
src/include/port/pg_numa.h
Normal 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 */
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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 \
|
||||||
|
@ -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
120
src/port/pg_numa.c
Normal 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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user