mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +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:
		@@ -471,6 +471,7 @@ task:
 | 
			
		||||
            --enable-cassert --enable-injection-points --enable-debug \
 | 
			
		||||
            --enable-tap-tests --enable-nls \
 | 
			
		||||
            --with-segsize-blocks=6 \
 | 
			
		||||
            --with-libnuma \
 | 
			
		||||
            --with-liburing \
 | 
			
		||||
            \
 | 
			
		||||
            ${LINUX_CONFIGURE_FEATURES} \
 | 
			
		||||
@@ -523,6 +524,7 @@ task:
 | 
			
		||||
            -Dllvm=disabled \
 | 
			
		||||
            --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
 | 
			
		||||
            -DPERL=perl5.36-i386-linux-gnu \
 | 
			
		||||
            -Dlibnuma=disabled \
 | 
			
		||||
            build-32
 | 
			
		||||
        EOF
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										187
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										187
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@@ -708,6 +708,9 @@ XML2_LIBS
 | 
			
		||||
XML2_CFLAGS
 | 
			
		||||
XML2_CONFIG
 | 
			
		||||
with_libxml
 | 
			
		||||
LIBNUMA_LIBS
 | 
			
		||||
LIBNUMA_CFLAGS
 | 
			
		||||
with_libnuma
 | 
			
		||||
LIBCURL_LIBS
 | 
			
		||||
LIBCURL_CFLAGS
 | 
			
		||||
with_libcurl
 | 
			
		||||
@@ -872,6 +875,7 @@ with_liburing
 | 
			
		||||
with_uuid
 | 
			
		||||
with_ossp_uuid
 | 
			
		||||
with_libcurl
 | 
			
		||||
with_libnuma
 | 
			
		||||
with_libxml
 | 
			
		||||
with_libxslt
 | 
			
		||||
with_system_tzdata
 | 
			
		||||
@@ -906,6 +910,8 @@ LIBURING_CFLAGS
 | 
			
		||||
LIBURING_LIBS
 | 
			
		||||
LIBCURL_CFLAGS
 | 
			
		||||
LIBCURL_LIBS
 | 
			
		||||
LIBNUMA_CFLAGS
 | 
			
		||||
LIBNUMA_LIBS
 | 
			
		||||
XML2_CONFIG
 | 
			
		||||
XML2_CFLAGS
 | 
			
		||||
XML2_LIBS
 | 
			
		||||
@@ -1588,6 +1594,7 @@ Optional Packages:
 | 
			
		||||
  --with-uuid=LIB         build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)
 | 
			
		||||
  --with-ossp-uuid        obsolete spelling of --with-uuid=ossp
 | 
			
		||||
  --with-libcurl          build with libcurl support
 | 
			
		||||
  --with-libnuma          build with libnuma support
 | 
			
		||||
  --with-libxml           build with XML support
 | 
			
		||||
  --with-libxslt          use XSLT support when building contrib/xml2
 | 
			
		||||
  --with-system-tzdata=DIR
 | 
			
		||||
@@ -1629,6 +1636,10 @@ Some influential environment variables:
 | 
			
		||||
              C compiler flags for LIBCURL, overriding pkg-config
 | 
			
		||||
  LIBCURL_LIBS
 | 
			
		||||
              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_CFLAGS C compiler 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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# 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
 | 
			
		||||
#
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								configure.ac
									
									
									
									
									
								
							@@ -1053,6 +1053,20 @@ if test "$with_libcurl" = yes ; then
 | 
			
		||||
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
 | 
			
		||||
#
 | 
			
		||||
 
 | 
			
		||||
@@ -25143,6 +25143,19 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
 | 
			
		||||
       </para></entry>
 | 
			
		||||
      </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>
 | 
			
		||||
       <entry role="func_table_entry"><para role="func_signature">
 | 
			
		||||
        <indexterm>
 | 
			
		||||
 
 | 
			
		||||
@@ -1156,6 +1156,17 @@ build-postgresql:
 | 
			
		||||
       </listitem>
 | 
			
		||||
      </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">
 | 
			
		||||
       <term><option>--with-liburing</option></term>
 | 
			
		||||
       <listitem>
 | 
			
		||||
@@ -2645,6 +2656,17 @@ ninja install
 | 
			
		||||
      </listitem>
 | 
			
		||||
     </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">
 | 
			
		||||
      <term><option>-Dlibxml={ auto | enabled | disabled }</option></term>
 | 
			
		||||
      <listitem>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								meson.build
									
									
									
									
									
								
							@@ -943,6 +943,27 @@ else
 | 
			
		||||
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
 | 
			
		||||
@@ -3279,6 +3300,7 @@ backend_both_deps += [
 | 
			
		||||
  icu_i18n,
 | 
			
		||||
  ldap,
 | 
			
		||||
  libintl,
 | 
			
		||||
  libnuma,
 | 
			
		||||
  liburing,
 | 
			
		||||
  libxml,
 | 
			
		||||
  lz4,
 | 
			
		||||
@@ -3935,6 +3957,7 @@ if meson.version().version_compare('>=0.57')
 | 
			
		||||
      'icu': icu,
 | 
			
		||||
      'ldap': ldap,
 | 
			
		||||
      'libcurl': libcurl,
 | 
			
		||||
      'libnuma': libnuma,
 | 
			
		||||
      'liburing': liburing,
 | 
			
		||||
      'libxml': libxml,
 | 
			
		||||
      'libxslt': libxslt,
 | 
			
		||||
 
 | 
			
		||||
@@ -106,6 +106,9 @@ option('libcurl', type : 'feature', value: 'auto',
 | 
			
		||||
option('libedit_preferred', type: 'boolean', value: false,
 | 
			
		||||
  description: 'Prefer BSD Libedit over GNU Readline')
 | 
			
		||||
 | 
			
		||||
option('libnuma', type: 'feature', value: 'auto',
 | 
			
		||||
  description: 'NUMA support')
 | 
			
		||||
 | 
			
		||||
option('liburing', type : 'feature', value: 'auto',
 | 
			
		||||
  description: 'io_uring support, for asynchronous I/O')
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -196,6 +196,7 @@ with_gssapi	= @with_gssapi@
 | 
			
		||||
with_krb_srvnam	= @with_krb_srvnam@
 | 
			
		||||
with_ldap	= @with_ldap@
 | 
			
		||||
with_libcurl	= @with_libcurl@
 | 
			
		||||
with_libnuma	= @with_libnuma@
 | 
			
		||||
with_liburing	= @with_liburing@
 | 
			
		||||
with_libxml	= @with_libxml@
 | 
			
		||||
with_libxslt	= @with_libxslt@
 | 
			
		||||
@@ -223,6 +224,9 @@ krb_srvtab = @krb_srvtab@
 | 
			
		||||
ICU_CFLAGS		= @ICU_CFLAGS@
 | 
			
		||||
ICU_LIBS		= @ICU_LIBS@
 | 
			
		||||
 | 
			
		||||
LIBNUMA_CFLAGS		= @LIBNUMA_CFLAGS@
 | 
			
		||||
LIBNUMA_LIBS		= @LIBNUMA_LIBS@
 | 
			
		||||
 | 
			
		||||
LIBURING_CFLAGS		= @LIBURING_CFLAGS@
 | 
			
		||||
LIBURING_LIBS		= @LIBURING_LIBS@
 | 
			
		||||
 | 
			
		||||
@@ -250,7 +254,7 @@ CPP = @CPP@
 | 
			
		||||
CPPFLAGS = @CPPFLAGS@
 | 
			
		||||
PG_SYSROOT = @PG_SYSROOT@
 | 
			
		||||
 | 
			
		||||
override CPPFLAGS := $(ICU_CFLAGS) $(LIBURING_CFLAGS) $(CPPFLAGS)
 | 
			
		||||
override CPPFLAGS := $(ICU_CFLAGS) $(LIBNUMA_CFLAGS) $(LIBURING_CFLAGS) $(CPPFLAGS)
 | 
			
		||||
 | 
			
		||||
ifdef PGXS
 | 
			
		||||
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_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
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,6 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*							yyyymmddN */
 | 
			
		||||
#define CATALOG_VERSION_NO	202504071
 | 
			
		||||
#define CATALOG_VERSION_NO	202504072
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -8542,6 +8542,10 @@
 | 
			
		||||
  proargnames => '{name,off,size,allocated_size}',
 | 
			
		||||
  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
 | 
			
		||||
{ oid => '2282',
 | 
			
		||||
  descr => 'information about all memory contexts of local backend',
 | 
			
		||||
 
 | 
			
		||||
@@ -689,6 +689,9 @@
 | 
			
		||||
/* Define to 1 to build with libcurl support. (--with-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) */
 | 
			
		||||
#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 huge_pages;
 | 
			
		||||
extern PGDLLIMPORT int huge_page_size;
 | 
			
		||||
extern PGDLLIMPORT int huge_pages_status;
 | 
			
		||||
 | 
			
		||||
/* Possible values for huge_pages and huge_pages_status */
 | 
			
		||||
typedef enum
 | 
			
		||||
 
 | 
			
		||||
@@ -200,6 +200,8 @@ pgxs_empty = [
 | 
			
		||||
 | 
			
		||||
  'ICU_LIBS',
 | 
			
		||||
 | 
			
		||||
  'LIBNUMA_CFLAGS', 'LIBNUMA_LIBS',
 | 
			
		||||
 | 
			
		||||
  'LIBURING_CFLAGS', 'LIBURING_LIBS',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@@ -232,6 +234,7 @@ pgxs_deps = {
 | 
			
		||||
  'icu': icu,
 | 
			
		||||
  'ldap': ldap,
 | 
			
		||||
  'libcurl': libcurl,
 | 
			
		||||
  'libnuma': libnuma,
 | 
			
		||||
  'liburing': liburing,
 | 
			
		||||
  'libxml': libxml,
 | 
			
		||||
  'libxslt': libxslt,
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,7 @@ OBJS = \
 | 
			
		||||
	path.o \
 | 
			
		||||
	pg_bitutils.o \
 | 
			
		||||
	pg_localeconv_r.o \
 | 
			
		||||
	pg_numa.o \
 | 
			
		||||
	pg_popcount_aarch64.o \
 | 
			
		||||
	pg_popcount_avx512.o \
 | 
			
		||||
	pg_strong_random.o \
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ pgport_sources = [
 | 
			
		||||
  'path.c',
 | 
			
		||||
  'pg_bitutils.c',
 | 
			
		||||
  'pg_localeconv_r.c',
 | 
			
		||||
  'pg_numa.c',
 | 
			
		||||
  'pg_popcount_aarch64.c',
 | 
			
		||||
  'pg_popcount_avx512.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;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user