From 752ac39efb03e516b8dfd5bb94f440298076f59f Mon Sep 17 00:00:00 2001 From: Igor Ivanov Date: Wed, 10 Feb 2016 14:27:47 +0200 Subject: [PATCH 1/3] opal/memory: Move Memory Allocation Hooks usage from openib These changes fix issue https://github.com/open-mpi/ompi/issues/1336 - improve abstractions: opal/memory/linux component should be single place that opeartes with Memory Allocation Hooks. - avoid collisions in case dynamic component open/close: it is safe because it is linked statically. - does not change original behaivour. --- ompi/runtime/ompi_mpi_init.c | 2 +- opal/mca/btl/openib/btl_openib.h | 5 - opal/mca/btl/openib/btl_openib_component.c | 61 +------- opal/mca/btl/openib/btl_openib_mca.c | 42 ++---- opal/mca/btl/openib/configure.m4 | 22 --- opal/mca/memory/base/empty.h | 13 +- opal/mca/memory/base/memory_base_empty.c | 8 ++ opal/mca/memory/base/memory_base_open.c | 3 + opal/mca/memory/linux/configure.m4 | 36 +++++ .../memory/linux/help-opal-memory-linux.txt | 7 + opal/mca/memory/linux/hooks.c | 6 +- opal/mca/memory/linux/memory_linux.h | 14 +- .../mca/memory/linux/memory_linux_component.c | 136 +++++++++++++++++- .../memory_malloc_solaris_component.c | 3 + opal/mca/memory/memory.h | 12 +- 15 files changed, 252 insertions(+), 118 deletions(-) diff --git a/ompi/runtime/ompi_mpi_init.c b/ompi/runtime/ompi_mpi_init.c index 48fb11ea3c..46012d93ae 100644 --- a/ompi/runtime/ompi_mpi_init.c +++ b/ompi/runtime/ompi_mpi_init.c @@ -100,7 +100,7 @@ from here, since any MPI code is going to call MPI_Init... */ OPAL_DECLSPEC void (*__malloc_initialize_hook) (void) = opal_memory_linux_malloc_init_hook; -#endif +#endif /* defined(MEMORY_LINUX_PTMALLOC2) && MEMORY_LINUX_PTMALLOC2 */ /* This is required for the boundaries of the hash tables used to store * the F90 types returned by the MPI_Type_create_f90_XXX functions. diff --git a/opal/mca/btl/openib/btl_openib.h b/opal/mca/btl/openib/btl_openib.h index 9b6464b272..61f756f81b 100644 --- a/opal/mca/btl/openib/btl_openib.h +++ b/opal/mca/btl/openib/btl_openib.h @@ -302,11 +302,6 @@ struct mca_btl_openib_component_t { #if BTL_OPENIB_FAILOVER_ENABLED int verbose_failover; #endif -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED - int use_memalign; - size_t memalign_threshold; - void* (*previous_malloc_hook)(size_t __size, const void*); -#endif #if OPAL_CUDA_SUPPORT bool cuda_async_send; bool cuda_async_recv; diff --git a/opal/mca/btl/openib/btl_openib_component.c b/opal/mca/btl/openib/btl_openib_component.c index b111e792b4..0455071526 100644 --- a/opal/mca/btl/openib/btl_openib_component.c +++ b/opal/mca/btl/openib/btl_openib_component.c @@ -42,7 +42,7 @@ #include #include #include -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED /* * The include of malloc.h below breaks abstractions in OMPI (by * directly including a header file from another component), but has @@ -55,7 +55,7 @@ * Internally, OMPI uses the built-in ptmalloc from the linux memory * component anyway. */ -#include "opal/mca/memory/linux/malloc.h" +#include "opal/mca/memory/linux/memory_linux.h" #endif #include "opal/mca/event/event.h" @@ -123,7 +123,6 @@ static void btl_openib_handle_incoming_completion(mca_btl_base_module_t* btl, * Local variables */ static mca_btl_openib_device_t *receive_queues_device = NULL; -static bool malloc_hook_set = false; static int num_devices_intentionally_ignored = 0; mca_btl_openib_component_t mca_btl_openib_component = { @@ -147,30 +146,6 @@ mca_btl_openib_component_t mca_btl_openib_component = { } }; -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED -/* This is a memory allocator hook. The purpose of this is to make - * every malloc aligned since this speeds up IB HCA work. - * There two basic cases here: - * - * 1. Memory manager for Open MPI is enabled. Then memalign below will - * be overridden by __memalign_hook which is set to - * opal_memory_linux_memalign_hook. Thus, _malloc_hook is going to - * use opal_memory_linux_memalign_hook. - * - * 2. No memory manager support. The memalign below is just regular glibc - * memalign which will be called through __malloc_hook instead of malloc. - */ -static void *btl_openib_malloc_hook(size_t sz, const void* caller) -{ - if (sz < mca_btl_openib_component.memalign_threshold && - malloc_hook_set) { - return mca_btl_openib_component.previous_malloc_hook(sz, caller); - } else { - return memalign(mca_btl_openib_component.use_memalign, sz); - } -} -#endif - static int btl_openib_component_register(void) { int ret; @@ -257,16 +232,6 @@ static int btl_openib_component_close(void) free(mca_btl_openib_component.default_recv_qps); } -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED - /* Must check to see whether the malloc hook was set before - assigning it back because ompi_info will call _register() and - then _close() (which won't set the hook) */ - if (malloc_hook_set) { - __malloc_hook = mca_btl_openib_component.previous_malloc_hook; - malloc_hook_set = false; - } -#endif - /* close memory registration debugging output */ opal_output_close (mca_btl_openib_component.memory_registration_verbose); @@ -2538,19 +2503,14 @@ btl_openib_component_init(int *num_btl_modules, *num_btl_modules = 0; num_devs = 0; -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED /* If we got this far, then setup the memory alloc hook (because we're most likely going to be using this component). The hook is to be set up as early as possible in this function since we - want most of the allocated resources be aligned.*/ - if (mca_btl_openib_component.use_memalign > 0 && - (opal_mem_hooks_support_level() & - (OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_CHUNK_SUPPORT)) != 0) { - mca_btl_openib_component.previous_malloc_hook = __malloc_hook; - __malloc_hook = btl_openib_malloc_hook; - malloc_hook_set = true; - } -#endif + want most of the allocated resources be aligned. + */ + opal_memory_linux_malloc_set_alignment(32, mca_btl_openib_module.super.btl_eager_limit); +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ /* Per https://svn.open-mpi.org/trac/ompi/ticket/1305, check to see if $sysfsdir/class/infiniband exists. If it does not, @@ -2951,13 +2911,6 @@ btl_openib_component_init(int *num_btl_modules, mca_btl_openib_component.ib_num_btls = 0; btl_openib_modex_send(); -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED - /*Unset malloc hook since the component won't start*/ - if (malloc_hook_set) { - __malloc_hook = mca_btl_openib_component.previous_malloc_hook; - malloc_hook_set = false; - } -#endif if (NULL != btls) { free(btls); } diff --git a/opal/mca/btl/openib/btl_openib_mca.c b/opal/mca/btl/openib/btl_openib_mca.c index c3c97d9226..8782331e11 100644 --- a/opal/mca/btl/openib/btl_openib_mca.c +++ b/opal/mca/btl/openib/btl_openib_mca.c @@ -703,26 +703,19 @@ int btl_openib_register_mca_params(void) 0, &mca_btl_openib_component.gid_index, REGINT_GE_ZERO)); -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED - CHECK(reg_int("memalign", NULL, - "[64 | 32 | 0] - Enable (64bit or 32bit)/Disable(0) memory" - "alignment for all malloc calls if btl openib is used.", - 32, &mca_btl_openib_component.use_memalign, - REGINT_GE_ZERO)); +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + tmp = mca_base_var_find ("opal", "memory", "linux", "memalign"); + if (0 <= tmp) { + (void) mca_base_var_register_synonym(tmp, "opal", "btl", "openib", "memalign", + MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + } - mca_btl_openib_component.memalign_threshold = - mca_btl_openib_module.super.btl_eager_limit; - tmp = mca_base_component_var_register(&mca_btl_openib_component.super.btl_version, - "memalign_threshold", - "Allocating memory more than btl_openib_memalign_threshhold" - "bytes will automatically be algined to the value of btl_openib_memalign bytes." - "memalign_threshhold defaults to the same value as mca_btl_openib_eager_limit.", - MCA_BASE_VAR_TYPE_SIZE_T, NULL, 0, 0, - OPAL_INFO_LVL_9, - MCA_BASE_VAR_SCOPE_READONLY, - &mca_btl_openib_component.memalign_threshold); - if (0 > tmp) ret = tmp; -#endif + tmp = mca_base_var_find ("opal", "memory", "linux", "memalign_threshold"); + if (0 <= tmp) { + (void) mca_base_var_register_synonym(tmp, "opal", "btl", "openib", "memalign_threshold", + MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + } +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ /* Register any MCA params for the connect pseudo-components */ if (OPAL_SUCCESS == ret) { @@ -823,16 +816,5 @@ int btl_openib_verify_mca_params (void) } #endif -#if BTL_OPENIB_MALLOC_HOOKS_ENABLED - if (mca_btl_openib_component.use_memalign != 32 - && mca_btl_openib_component.use_memalign != 64 - && mca_btl_openib_component.use_memalign != 0){ - opal_show_help("help-mpi-btl-openib.txt", "invalid mca param value", - true, "Wrong btl_openib_memalign parameter value. Allowed values: 64, 32, 0.", - "btl_openib_memalign is reset to 32"); - mca_btl_openib_component.use_memalign = 32; - } -#endif - return OPAL_SUCCESS; } diff --git a/opal/mca/btl/openib/configure.m4 b/opal/mca/btl/openib/configure.m4 index 1d07ae81cb..9c3d9025c6 100644 --- a/opal/mca/btl/openib/configure.m4 +++ b/opal/mca/btl/openib/configure.m4 @@ -120,28 +120,6 @@ AC_DEFUN([MCA_opal_btl_openib_CONFIG],[ [enable openib BTL failover]) AM_CONDITIONAL([MCA_btl_openib_enable_failover], [test "x$btl_openib_failover_enabled" = "x1"]) - # Check for __malloc_hook availability - AC_ARG_ENABLE(btl-openib-malloc-alignment, - AC_HELP_STRING([--enable-btl-openib-malloc-alignment], [Enable support for allocated memory alignment. Default: enabled if supported, disabled otherwise.])) - - btl_openib_malloc_hooks_enabled=0 - AS_IF([test "$enable_btl_openib_malloc_alignment" != "no"], - [AC_CHECK_HEADER([malloc.h], - [AC_CHECK_FUNC([__malloc_hook], - [AC_CHECK_FUNC([__realloc_hook], - [AC_CHECK_FUNC([__free_hook], - [btl_openib_malloc_hooks_enabled=1])])])])]) - - AS_IF([test "$enable_btl_openib_malloc_alignment" = "yes" && test "$btl_openib_malloc_hooks_enabled" = "0"], - [AC_MSG_ERROR([openib malloc alignment is requested but __malloc_hook is not available])]) - AC_MSG_CHECKING([whether the openib BTL will use malloc hooks]) - AS_IF([test "$btl_openib_malloc_hooks_enabled" = "0"], - [AC_MSG_RESULT([no])], - [AC_MSG_RESULT([yes])]) - - AC_DEFINE_UNQUOTED(BTL_OPENIB_MALLOC_HOOKS_ENABLED, [$btl_openib_malloc_hooks_enabled], - [Whether the openib BTL malloc hooks are enabled]) - # make sure that CUDA-aware checks have been done AC_REQUIRE([OPAL_CHECK_CUDA]) diff --git a/opal/mca/memory/base/empty.h b/opal/mca/memory/base/empty.h index 564f29648f..46cacc56e3 100644 --- a/opal/mca/memory/base/empty.h +++ b/opal/mca/memory/base/empty.h @@ -1,5 +1,7 @@ /* - * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -51,6 +53,15 @@ OPAL_DECLSPEC int opal_memory_base_component_deregister_empty(void *start, size_t len, uint64_t cookie); +/** + * Default (empty) implementation of the memoryc_set_alignment function + * + * See opal/mca/memory/memory.h for a description of the parameters. + */ +OPAL_DECLSPEC void opal_memory_base_component_set_alignment_empty(int use_memalign, + size_t memalign_threshold); + + END_C_DECLS #endif diff --git a/opal/mca/memory/base/memory_base_empty.c b/opal/mca/memory/base/memory_base_empty.c index d9833374a9..c31db23487 100644 --- a/opal/mca/memory/base/memory_base_empty.c +++ b/opal/mca/memory/base/memory_base_empty.c @@ -9,6 +9,8 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -34,3 +36,9 @@ int opal_memory_base_component_deregister_empty(void *base, size_t len, { return OPAL_SUCCESS; } + +void opal_memory_base_component_set_alignment_empty(int use_memalign, + size_t memalign_threshold) +{ +} + diff --git a/opal/mca/memory/base/memory_base_open.c b/opal/mca/memory/base/memory_base_open.c index 1cf1400ec3..b27b1ae61d 100644 --- a/opal/mca/memory/base/memory_base_open.c +++ b/opal/mca/memory/base/memory_base_open.c @@ -11,6 +11,8 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -54,6 +56,7 @@ static opal_memory_base_component_2_0_0_t empty_component = { empty_process, opal_memory_base_component_register_empty, opal_memory_base_component_deregister_empty, + opal_memory_base_component_set_alignment_empty, }; diff --git a/opal/mca/memory/linux/configure.m4 b/opal/mca/memory/linux/configure.m4 index 93525b9ca9..e44786e1eb 100644 --- a/opal/mca/memory/linux/configure.m4 +++ b/opal/mca/memory/linux/configure.m4 @@ -63,6 +63,42 @@ AC_DEFUN([MCA_opal_memory_linux_CONFIG],[ [memory_linux_ptmalloc2_happy=no memory_linux_ummu_happy=no])]) + + ###################################################################### + # if memory hook available + ###################################################################### + memory_hook_found=1 + AS_IF([test "$memory_hook_found" -eq 1], + [memory_hook_found=0 AC_CHECK_HEADER([malloc.h], + [AC_CHECK_FUNC([__malloc_initialize_hook], + [AC_CHECK_FUNC([__malloc_hook], + [AC_CHECK_FUNC([__realloc_hook], + [AC_CHECK_FUNC([__free_hook], + [memory_hook_found=1])])])])])]) + AC_MSG_CHECKING([whether the system can use malloc hooks]) + AS_IF([test "$memory_hook_found" = "0"], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([yes])]) + AC_DEFINE_UNQUOTED([MEMORY_LINUX_HAVE_MALLOC_HOOK_SUPPORT], [$memory_hook_found], + [Whether the system has Memory Allocation Hooks]) + + AC_ARG_ENABLE(memory-linux-malloc-alignment, + AC_HELP_STRING([--enable-memory-linux-malloc-alignment], [Enable support for allocated memory alignment. Default: enabled if supported, disabled otherwise.])) + + malloc_align_enabled=0 + AS_IF([test "$enable_memory_linux_malloc_alignment" != "no"], + [malloc_align_enabled=$memory_hook_found]) + + AS_IF([test "$enable_memory_linux_malloc_alignment" = "yes" && test "$malloc_align_enabled" = "0"], + [AC_MSG_ERROR([memory linux malloc alignment is requested but __malloc_hook is not available])]) + AC_MSG_CHECKING([whether the memory linux will use malloc alignment]) + AS_IF([test "$malloc_align_enabled" = "0"], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([yes])]) + + AC_DEFINE_UNQUOTED(MEMORY_LINUX_MALLOC_ALIGN_ENABLED, [$malloc_align_enabled], + [Whether the memory linux malloc alignment is enabled]) + ###################################################################### # ptmalloc2 ###################################################################### diff --git a/opal/mca/memory/linux/help-opal-memory-linux.txt b/opal/mca/memory/linux/help-opal-memory-linux.txt index b3327c7356..4e16124dc0 100644 --- a/opal/mca/memory/linux/help-opal-memory-linux.txt +++ b/opal/mca/memory/linux/help-opal-memory-linux.txt @@ -27,3 +27,10 @@ alternate memory hook manager *may* be used instead (if available). Local host: %s UMMU device: %s Error: %s (%d) +# +[invalid mca param value] +WARNING: An invalid MCA parameter value was found for memory/linux +component. + + Problem: %s + Resolution: %s diff --git a/opal/mca/memory/linux/hooks.c b/opal/mca/memory/linux/hooks.c index 02fffb6b4c..910d8e6e20 100644 --- a/opal/mca/memory/linux/hooks.c +++ b/opal/mca/memory/linux/hooks.c @@ -33,6 +33,7 @@ #include "opal/mca/mca.h" #include "opal/mca/memory/memory.h" #include "opal/constants.h" +#include "opal/memoryhooks/memory.h" #include "opal/mca/memory/linux/memory_linux.h" @@ -734,7 +735,10 @@ static check_result_t check(const char *name) } } -/* OMPI's init function */ + +/* This function is called on loading libmpi in case system has Memory Allocation Hooks + * (see ompi/runtime/ompi_mpi_init.c for details) + */ void opal_memory_linux_malloc_init_hook(void) { check_result_t r1, lp, lpp; diff --git a/opal/mca/memory/linux/memory_linux.h b/opal/mca/memory/linux/memory_linux.h index 24cb303c1f..22685c1478 100644 --- a/opal/mca/memory/linux/memory_linux.h +++ b/opal/mca/memory/linux/memory_linux.h @@ -31,6 +31,11 @@ typedef struct opal_memory_linux_component_t { int ummunotify_fd; #endif +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + int use_memalign; + size_t memalign_threshold; +#endif + #if MEMORY_LINUX_PTMALLOC2 /* Ptmalloc2-specific data. Note that these variables are all marked as volatile. * This is needed because of what may be a buggy optimization in the GCC 4.9.2 @@ -64,13 +69,20 @@ int opal_memory_linux_ummunotify_close(void); /* memory_linux_ptmalloc2.c */ int opal_memory_linux_ptmalloc2_open(void); int opal_memory_linux_ptmalloc2_close(void); -OPAL_DECLSPEC void opal_memory_linux_malloc_init_hook(void); /* memory_linux_munmap.c */ OPAL_DECLSPEC int opal_memory_linux_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc); OPAL_DECLSPEC int munmap(void* addr, size_t len); #endif /* !MEMORY_LINUX_PTMALLOC2 */ +#if MEMORY_LINUX_HAVE_MALLOC_HOOK_SUPPORT +OPAL_DECLSPEC void opal_memory_linux_malloc_init_hook(void); +#endif /* MEMORY_LINUX_HAVE_MALLOC_HOOK_SUPPORT */ + +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED +OPAL_DECLSPEC void opal_memory_linux_malloc_set_alignment(int use_memalign, size_t memalign_threshold); +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ + END_C_DECLS #endif diff --git a/opal/mca/memory/linux/memory_linux_component.c b/opal/mca/memory/linux/memory_linux_component.c index ad14eb9851..3319066bbb 100644 --- a/opal/mca/memory/linux/memory_linux_component.c +++ b/opal/mca/memory/linux/memory_linux_component.c @@ -13,6 +13,8 @@ * Copyright (c) 2009-2014 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2013-2015 Los Alamos National Security, LLC. All rights * reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -39,12 +41,17 @@ #include "opal_config.h" +#if HAVE_MALLOC_H +#include +#endif + #include "opal/constants.h" #include "opal/mca/base/mca_base_var.h" #include "opal/mca/memory/memory.h" #include "opal/mca/memory/base/empty.h" #include "opal/memoryhooks/memory.h" #include "opal/util/output.h" +#include "opal/util/show_help.h" #include "opal/mca/memory/linux/memory_linux.h" #undef opal_memory_changed @@ -91,6 +98,11 @@ opal_memory_linux_component_t mca_memory_linux_component = { end up using ummunotify support. */ .memoryc_register = opal_memory_base_component_register_empty, .memoryc_deregister = opal_memory_base_component_deregister_empty, +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + .memoryc_set_alignment = opal_memory_linux_malloc_set_alignment, +#else + .memoryc_set_alignment = opal_memory_base_component_set_alignment_empty, +#endif }, /* Component-specific data, filled in later (compiler will 0/NULL @@ -100,6 +112,26 @@ opal_memory_linux_component_t mca_memory_linux_component = { static bool ptmalloc2_available = MEMORY_LINUX_PTMALLOC2; static bool ummunotify_available = MEMORY_LINUX_UMMUNOTIFY; +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + +static void *(*prev_malloc_hook)(size_t, const void *); + +/* This is a memory allocator hook. The purpose of this is to make + * every malloc aligned. + * There two basic cases here: + * + * 1. Memory manager for Open MPI is enabled. Then memalign below will + * be overridden by __memalign_hook which is set to + * opal_memory_linux_memalign_hook. Thus, _malloc_hook is going to + * use opal_memory_linux_memalign_hook. + * + * 2. No memory manager support. The memalign below is just regular glibc + * memalign which will be called through __malloc_hook instead of malloc. + */ +static void *_opal_memory_linux_malloc_align_hook(size_t sz, const void* caller); +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ + + /* * Register MCA params */ @@ -162,6 +194,53 @@ static int linux_register(void) OPAL_INFO_LVL_3, MCA_BASE_VAR_SCOPE_READONLY, &opal_memory_linux_disable); + if (0 > ret) { + return ret; + } + +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + mca_memory_linux_component.use_memalign = -1; + ret = mca_base_component_var_register(&mca_memory_linux_component.super.memoryc_version, + "memalign", + "[64 | 32 | 0] - Enable memory alignment for all malloc calls (default: disabled).", + MCA_BASE_VAR_TYPE_INT, + NULL, + 0, + 0, + OPAL_INFO_LVL_5, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_memory_linux_component.use_memalign); + if (0 > ret) { + return ret; + } + + mca_memory_linux_component.memalign_threshold = 12288; + ret = mca_base_component_var_register(&mca_memory_linux_component.super.memoryc_version, + "memalign_threshold", + "Allocating memory more than memory_linux_memalign_threshold" + "bytes will automatically be aligned to the value of memory_linux_memalign bytes." + "(default: 12288)", + MCA_BASE_VAR_TYPE_SIZE_T, + NULL, + 0, + 0, + OPAL_INFO_LVL_5, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_memory_linux_component.memalign_threshold); + if (0 > ret) { + return ret; + } + + if (mca_memory_linux_component.use_memalign != -1 + && mca_memory_linux_component.use_memalign != 32 + && mca_memory_linux_component.use_memalign != 64 + && mca_memory_linux_component.use_memalign != 0){ + opal_show_help("help-opal-memory-linux.txt", "invalid mca param value", + true, "Wrong memalign parameter value. Allowed values: 64, 32, 0.", + "memory_linux_memalign is reset to 32"); + mca_memory_linux_component.use_memalign = 32; + } +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ return (0 > ret) ? ret : OPAL_SUCCESS; } @@ -188,7 +267,7 @@ static int linux_open(void) if (mca_memory_linux_component.verbose_level >= 10) { opal_output(0, "memory:linux: ummunotify successfully initialized; we'll use that"); } - return OPAL_SUCCESS; + goto done; } if (mca_memory_linux_component.verbose_level >= 10) { opal_output(0, "memory:linux: ummunotify failed to initialize"); @@ -206,7 +285,7 @@ static int linux_open(void) if (mca_memory_linux_component.verbose_level >= 10) { opal_output(0, "memory:linux: ptmalloc2 successfully initialized; we'll use that"); } - return OPAL_SUCCESS; + goto done; } if (mca_memory_linux_component.verbose_level >= 10) { opal_output(0, "memory:linux: ptmalloc2 failed to initialize"); @@ -222,12 +301,36 @@ static int linux_open(void) opal_output(0, "memory:linux: no memory hooks available in this process"); } return OPAL_ERR_NOT_AVAILABLE; + +done: + +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + /* save original call */ + prev_malloc_hook = NULL; + + if (mca_memory_linux_component.use_memalign > 0 && + (opal_mem_hooks_support_level() & + (OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_CHUNK_SUPPORT)) != 0) { + prev_malloc_hook = __malloc_hook; + __malloc_hook = _opal_memory_linux_malloc_align_hook; + } +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ + + return OPAL_SUCCESS; } static int linux_close(void) { int v = mca_memory_linux_component.verbose_level; +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + /* restore original call */ + if (prev_malloc_hook) { + __malloc_hook = prev_malloc_hook; + prev_malloc_hook = NULL; + } +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ + #if MEMORY_LINUX_UMMUNOTIFY if (ummunotify_opened) { if (v >= 10) { @@ -249,3 +352,32 @@ static int linux_close(void) return OPAL_SUCCESS; } + +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED +void opal_memory_linux_malloc_set_alignment(int use_memalign, size_t memalign_threshold) +{ + /* ignore cases when this capability is enabled explicitly using + * mca variables + */ + if ((NULL == prev_malloc_hook) && (-1 == mca_memory_linux_component.use_memalign)) { + if (use_memalign == 0 || use_memalign == 32 || use_memalign == 64) { + mca_memory_linux_component.use_memalign = use_memalign; + mca_memory_linux_component.memalign_threshold = memalign_threshold; + if ((opal_mem_hooks_support_level() & + (OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_CHUNK_SUPPORT)) != 0) { + prev_malloc_hook = __malloc_hook; + __malloc_hook = _opal_memory_linux_malloc_align_hook; + } + } + } +} + +static void *_opal_memory_linux_malloc_align_hook(size_t sz, const void* caller) +{ + if (sz < mca_memory_linux_component.memalign_threshold) { + return prev_malloc_hook(sz, caller); + } else { + return memalign(mca_memory_linux_component.use_memalign, sz); + } +} +#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ diff --git a/opal/mca/memory/malloc_solaris/memory_malloc_solaris_component.c b/opal/mca/memory/malloc_solaris/memory_malloc_solaris_component.c index dd35feb081..15fa63468d 100644 --- a/opal/mca/memory/malloc_solaris/memory_malloc_solaris_component.c +++ b/opal/mca/memory/malloc_solaris/memory_malloc_solaris_component.c @@ -14,6 +14,8 @@ * Copyright (c) 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -68,6 +70,7 @@ const opal_memory_base_component_2_0_0_t mca_memory_malloc_solaris_component = { provide safe/empty register/deregister functions to call */ .memoryc_register = opal_memory_base_component_register_empty, .memoryc_deregister = opal_memory_base_component_deregister_empty, + .memoryc_set_alignment = opal_memory_base_component_set_alignment_empty, }; /* diff --git a/opal/mca/memory/memory.h b/opal/mca/memory/memory.h index 2b5c62f1f3..ab9ac49d78 100644 --- a/opal/mca/memory/memory.h +++ b/opal/mca/memory/memory.h @@ -13,6 +13,8 @@ * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -92,7 +94,7 @@ typedef int (*opal_memory_base_component_register_fn_t)(void *base, /** - * Prototype for a function that is the opposite of + * Prototype for a function that is the opposite of * opal_memory_base_component_register_fn_t: this function is invoked * when Open MPI stops to "caring" about a specific memory region. * That is, Open MPI declares that it no longer wants to be notified @@ -111,6 +113,12 @@ typedef int (*opal_memory_base_component_deregister_fn_t)(void *base, uint64_t cookie); +/** + * Prototype for a function that set the memory alignment + */ +typedef void (*opal_memory_base_component_set_alignment_fn_t)(int use_memalign, + size_t memalign_threshold); + /** * Structure for memory components. */ @@ -132,6 +140,8 @@ typedef struct opal_memory_base_component_2_0_0_t { /** Function invoked when Open MPI stops "caring" about a specific memory region */ opal_memory_base_component_deregister_fn_t memoryc_deregister; + /** Function invoked in order to set malloc'ed memory alignment */ + opal_memory_base_component_set_alignment_fn_t memoryc_set_alignment; } opal_memory_base_component_2_0_0_t; OPAL_DECLSPEC extern opal_memory_base_component_2_0_0_t *opal_memory; From b5f85831e6a5fc179d8d4f4bc6e7bb3ba1adb93a Mon Sep 17 00:00:00 2001 From: Gilles Gouaillardet Date: Thu, 18 Feb 2016 10:33:14 +0900 Subject: [PATCH 2/3] btl/openib: fix abstraction violation and use opal_memory->memoryc_set_alignment --- opal/mca/btl/openib/btl_openib_component.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/opal/mca/btl/openib/btl_openib_component.c b/opal/mca/btl/openib/btl_openib_component.c index 0455071526..da7702fdf5 100644 --- a/opal/mca/btl/openib/btl_openib_component.c +++ b/opal/mca/btl/openib/btl_openib_component.c @@ -19,7 +19,7 @@ * Copyright (c) 2011-2015 NVIDIA Corporation. All rights reserved. * Copyright (c) 2012 Oak Ridge National Laboratory. All rights reserved * Copyright (c) 2013-2015 Intel, Inc. All rights reserved - * Copyright (c) 2014-2015 Research Organization for Information Science + * Copyright (c) 2014-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2014 Bull SAS. All rights reserved. * $COPYRIGHT$ @@ -42,22 +42,8 @@ #include #include #include -#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED -/* - * The include of malloc.h below breaks abstractions in OMPI (by - * directly including a header file from another component), but has - * been ruled "ok" because the openib component is only supported on - * Linux. - * - * The malloc hooks in newer glibc were deprecated, including stock - * malloc.h causes compilation warnings. Instead, we use the internal - * linux component malloc.h which does not cause these warnings. - * Internally, OMPI uses the built-in ptmalloc from the linux memory - * component anyway. - */ -#include "opal/mca/memory/linux/memory_linux.h" -#endif +#include "opal/mca/memory/memory.h" #include "opal/mca/event/event.h" #include "opal/align.h" #include "opal/util/output.h" @@ -2503,14 +2489,12 @@ btl_openib_component_init(int *num_btl_modules, *num_btl_modules = 0; num_devs = 0; -#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED /* If we got this far, then setup the memory alloc hook (because we're most likely going to be using this component). The hook is to be set up as early as possible in this function since we want most of the allocated resources be aligned. */ - opal_memory_linux_malloc_set_alignment(32, mca_btl_openib_module.super.btl_eager_limit); -#endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ + opal_memory->memoryc_set_alignment(32, mca_btl_openib_module.super.btl_eager_limit); /* Per https://svn.open-mpi.org/trac/ompi/ticket/1305, check to see if $sysfsdir/class/infiniband exists. If it does not, From 6780bb025a779dba58f1a27bb21a3e3598e92e25 Mon Sep 17 00:00:00 2001 From: Gilles Gouaillardet Date: Wed, 2 Mar 2016 14:19:06 +0900 Subject: [PATCH 3/3] memory/linux: make memory_linux_memalign an enum Thanks Igor Ivanov for the review. --- .../memory/linux/help-opal-memory-linux.txt | 7 ----- .../mca/memory/linux/memory_linux_component.c | 27 ++++++++++--------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/opal/mca/memory/linux/help-opal-memory-linux.txt b/opal/mca/memory/linux/help-opal-memory-linux.txt index 4e16124dc0..b3327c7356 100644 --- a/opal/mca/memory/linux/help-opal-memory-linux.txt +++ b/opal/mca/memory/linux/help-opal-memory-linux.txt @@ -27,10 +27,3 @@ alternate memory hook manager *may* be used instead (if available). Local host: %s UMMU device: %s Error: %s (%d) -# -[invalid mca param value] -WARNING: An invalid MCA parameter value was found for memory/linux -component. - - Problem: %s - Resolution: %s diff --git a/opal/mca/memory/linux/memory_linux_component.c b/opal/mca/memory/linux/memory_linux_component.c index 3319066bbb..d883f10f2a 100644 --- a/opal/mca/memory/linux/memory_linux_component.c +++ b/opal/mca/memory/linux/memory_linux_component.c @@ -129,6 +129,14 @@ static void *(*prev_malloc_hook)(size_t, const void *); * memalign which will be called through __malloc_hook instead of malloc. */ static void *_opal_memory_linux_malloc_align_hook(size_t sz, const void* caller); + +static mca_base_var_enum_value_t align_values[] = { + {-1, "disabled"}, + {0, "0"}, + {32, "32"}, + {64, "64"}, + {0, NULL} +}; #endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ @@ -137,6 +145,9 @@ static void *_opal_memory_linux_malloc_align_hook(size_t sz, const void* caller) */ static int linux_register(void) { +#if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + mca_base_var_enum_t *new_enum; +#endif int ret; /* Information only */ ret = mca_base_component_var_register (&mca_memory_linux_component.super.memoryc_version, @@ -199,17 +210,19 @@ static int linux_register(void) } #if MEMORY_LINUX_MALLOC_ALIGN_ENABLED + (void)mca_base_var_enum_create("memory_linux_memalign", align_values, &new_enum); mca_memory_linux_component.use_memalign = -1; ret = mca_base_component_var_register(&mca_memory_linux_component.super.memoryc_version, "memalign", - "[64 | 32 | 0] - Enable memory alignment for all malloc calls (default: disabled).", + "[64 | 32 | 0] - Enable memory alignment for all malloc calls.", MCA_BASE_VAR_TYPE_INT, - NULL, + new_enum, 0, 0, OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_READONLY, &mca_memory_linux_component.use_memalign); + OBJ_RELEASE(new_enum); if (0 > ret) { return ret; } @@ -230,16 +243,6 @@ static int linux_register(void) if (0 > ret) { return ret; } - - if (mca_memory_linux_component.use_memalign != -1 - && mca_memory_linux_component.use_memalign != 32 - && mca_memory_linux_component.use_memalign != 64 - && mca_memory_linux_component.use_memalign != 0){ - opal_show_help("help-opal-memory-linux.txt", "invalid mca param value", - true, "Wrong memalign parameter value. Allowed values: 64, 32, 0.", - "memory_linux_memalign is reset to 32"); - mca_memory_linux_component.use_memalign = 32; - } #endif /* MEMORY_LINUX_MALLOC_ALIGN_ENABLED */ return (0 > ret) ? ret : OPAL_SUCCESS;