diff --git a/config/opal_check_ofi.m4 b/config/opal_check_ofi.m4 index 072d6ab1e7c..311eb9619c0 100644 --- a/config/opal_check_ofi.m4 +++ b/config/opal_check_ofi.m4 @@ -3,6 +3,8 @@ dnl dnl Copyright (c) 2015-2020 Cisco Systems, Inc. All rights reserved. dnl Copyright (c) 2016-2017 Los Alamos National Security, LLC. All rights dnl reserved. +dnl Copyright (c) 2021 Amazon.com, Inc. or its affiliates. All rights +dnl reserved. dnl $COPYRIGHT$ dnl dnl Additional copyrights may follow @@ -155,6 +157,18 @@ AC_DEFUN([_OPAL_CHECK_OFI],[ [AC_MSG_WARN([OFI libfabric support requested (via --with-ofi or --with-libfabric), but not found.]) AC_MSG_ERROR([Cannot continue.])]) ]) + opal_ofi_import_monitor=no + AS_IF([test $opal_ofi_happy = "yes"], + [OPAL_CHECK_OFI_VERSION_GE([1,13], + [opal_ofi_import_monitor=yes], + [opal_ofi_import_monitor=no])]) + + +if test "$opal_ofi_import_monitor" = "yes"; then + AC_DEFINE_UNQUOTED([OPAL_OFI_IMPORT_MONITOR_SUPPORT],1, + [Whether libfabric supports monitor import]) +fi + ])dnl diff --git a/ompi/mca/mtl/ofi/mtl_ofi_component.c b/ompi/mca/mtl/ofi/mtl_ofi_component.c index 244e1e61dbe..b76633e6a3a 100644 --- a/ompi/mca/mtl/ofi/mtl_ofi_component.c +++ b/ompi/mca/mtl/ofi/mtl_ofi_component.c @@ -5,8 +5,8 @@ * Copyright (c) 2014-2021 Cisco Systems, Inc. All rights reserved * Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved. - * Copyright (c) 2020 Triad National Security, LLC. All rights + * Copyright (c) 2018-2021 Amazon.com, Inc. or its affiliates. All Rights reserved. + * Copyright (c) 2020-2021 Triad National Security, LLC. All rights * reserved. * $COPYRIGHT$ * @@ -285,8 +285,7 @@ ompi_mtl_ofi_component_open(void) "provider_exclude")) { return OMPI_ERR_NOT_AVAILABLE; } - - return OMPI_SUCCESS; + return opal_common_ofi_init(); } static int @@ -304,6 +303,7 @@ ompi_mtl_ofi_component_close(void) mca_common_cuda_fini(); #endif opal_common_ofi_mca_deregister(); + opal_common_ofi_fini(); return OMPI_SUCCESS; } diff --git a/opal/mca/btl/ofi/btl_ofi_component.c b/opal/mca/btl/ofi/btl_ofi_component.c index 8d9f3f4025e..cd1816b273a 100644 --- a/opal/mca/btl/ofi/btl_ofi_component.c +++ b/opal/mca/btl/ofi/btl_ofi_component.c @@ -14,7 +14,7 @@ * reserved. * Copyright (c) 2018-2019 Intel, Inc. All rights reserved. * - * Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved. + * Copyright (c) 2018-2021 Amazon.com, Inc. or its affiliates. All Rights reserved. * Copyright (c) 2020 Triad National Security, LLC. All rights * reserved. * $COPYRIGHT$ @@ -199,7 +199,7 @@ static int mca_btl_ofi_component_register(void) static int mca_btl_ofi_component_open(void) { mca_btl_ofi_component.module_count = 0; - return OPAL_SUCCESS; + return opal_common_ofi_init(); } /* @@ -208,6 +208,7 @@ static int mca_btl_ofi_component_open(void) static int mca_btl_ofi_component_close(void) { opal_common_ofi_mca_deregister(); + opal_common_ofi_fini(); /* If we don't sleep, sockets provider freaks out. Ummm this is a scary comment */ sleep(1); return OPAL_SUCCESS; diff --git a/opal/mca/common/ofi/common_ofi.c b/opal/mca/common/ofi/common_ofi.c index 58b033009df..1a5d0fb72f5 100644 --- a/opal/mca/common/ofi/common_ofi.c +++ b/opal/mca/common/ofi/common_ofi.c @@ -6,6 +6,8 @@ * reserved. * Copyright (c) 2020-2021 Cisco Systems, Inc. All rights reserved * Copyright (c) 2021 Nanook Consulting. All rights reserved. + * Copyright (c) 2021 Amazon.com, Inc. or its affiliates. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -33,6 +35,120 @@ OPAL_DECLSPEC opal_common_ofi_module_t opal_common_ofi = {.prov_include = NULL, static const char default_prov_exclude_list[] = "shm,sockets,tcp,udp,rstream,usnic"; static opal_mutex_t opal_common_ofi_mutex = OPAL_MUTEX_STATIC_INIT; +static bool opal_common_ofi_initialized = false; +static int opal_common_ofi_init_ref_cnt = 0; + +#if OPAL_OFI_IMPORT_MONITOR_SUPPORT + +static int opal_common_ofi_monitor_start(struct fid_mem_monitor *monitor) +{ + return 0; +} +static void opal_common_ofi_monitor_stop(struct fid_mem_monitor *monitor) +{ + return; +} +static int opal_common_ofi_monitor_subscribe(struct fid_mem_monitor *monitor, + const void *addr, size_t len) +{ + return 0; +} +static void opal_common_ofi_monitor_unsubscribe(struct fid_mem_monitor *monitor, + const void *addr, size_t len) +{ + return; +} +static bool opal_common_ofi_monitor_valid(struct fid_mem_monitor *monitor, + const void *addr, size_t len) +{ + return true; +} + +static struct fid_mem_monitor *opal_common_ofi_monitor; +static struct fid *opal_common_ofi_cache_fid; +static struct fi_ops_mem_monitor opal_common_ofi_export_ops = { + .size = sizeof(struct fi_ops_mem_monitor), + .start = opal_common_ofi_monitor_start, + .stop = opal_common_ofi_monitor_stop, + .subscribe = opal_common_ofi_monitor_subscribe, + .unsubscribe = opal_common_ofi_monitor_unsubscribe, + .valid = opal_common_ofi_monitor_valid, +}; + +OPAL_DECLSPEC void opal_common_ofi_mem_release_cb(void *buf, size_t length, + void *cbdata, bool from_alloc) +{ + opal_common_ofi_monitor->import_ops->notify(opal_common_ofi_monitor, + buf, length); +} +#endif /* OPAL_OFI_IMPORT_MONITOR_SUPPORT */ + +OPAL_DECLSPEC int opal_common_ofi_init(void) +{ + int ret; + + opal_common_ofi_init_ref_cnt++; + if (opal_common_ofi_initialized) { + return OPAL_SUCCESS; + } +#if OPAL_OFI_IMPORT_MONITOR_SUPPORT + + mca_base_framework_open(&opal_memory_base_framework, 0); + if ((OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_MUNMAP_SUPPORT) + != (((OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_MUNMAP_SUPPORT)) + & opal_mem_hooks_support_level())) { + return OPAL_SUCCESS; + } + + ret = fi_open(FI_VERSION(1,13), "mr_cache", NULL, 0, 0, &opal_common_ofi_cache_fid, NULL); + if (ret) { + goto err; + } + + opal_common_ofi_monitor = calloc(1, sizeof(*opal_common_ofi_monitor)); + if (!opal_common_ofi_monitor) { + goto err; + } + + opal_common_ofi_monitor->fid.fclass = FI_CLASS_MEM_MONITOR; + opal_common_ofi_monitor->export_ops = &opal_common_ofi_export_ops; + ret = fi_import_fid(opal_common_ofi_cache_fid, &opal_common_ofi_monitor->fid, 0); + if (ret) { + goto err; + } + opal_mem_hooks_register_release(opal_common_ofi_mem_release_cb, NULL); + opal_common_ofi_initialized = true; + + return OPAL_SUCCESS; +err: + if (opal_common_ofi_cache_fid) { + fi_close(opal_common_ofi_cache_fid); + } + if (opal_common_ofi_monitor) { + free(opal_common_ofi_monitor); + } + + return OPAL_ERROR; +#else + opal_common_ofi_initialized = true; + return OPAL_SUCCESS; +#endif +} + +OPAL_DECLSPEC int opal_common_ofi_fini(void) +{ + if (opal_common_ofi_initialized && !--opal_common_ofi_init_ref_cnt) { +#if OPAL_OFI_IMPORT_MONITOR_SUPPORT + opal_mem_hooks_unregister_release(opal_common_ofi_mem_release_cb); + fi_close(opal_common_ofi_cache_fid); + fi_close(&opal_common_ofi_monitor->fid); + free(opal_common_ofi_monitor); +#endif + opal_common_ofi_initialized = false; + } + + return OPAL_SUCCESS; +} OPAL_DECLSPEC int opal_common_ofi_is_in_list(char **list, char *item) { diff --git a/opal/mca/common/ofi/common_ofi.h b/opal/mca/common/ofi/common_ofi.h index 2ec8ae5db10..d2e17c57ebe 100644 --- a/opal/mca/common/ofi/common_ofi.h +++ b/opal/mca/common/ofi/common_ofi.h @@ -5,6 +5,8 @@ * reserved. * Copyright (c) 2020 Triad National Security, LLC. All rights * reserved. + * Copyright (c) 2021 Amazon.com, Inc. or its affiliates. All rights + * reserved. * * $COPYRIGHT$ * @@ -20,7 +22,11 @@ #include "opal/mca/base/mca_base_framework.h" #include "opal/mca/base/mca_base_var.h" #include "opal/util/proc.h" +#include "opal/memoryhooks/memory.h" #include +#if OPAL_OFI_IMPORT_MONITOR_SUPPORT +#include +#endif BEGIN_C_DECLS @@ -33,6 +39,7 @@ typedef struct opal_common_ofi_module { } opal_common_ofi_module_t; extern opal_common_ofi_module_t opal_common_ofi; +extern mca_base_framework_t opal_memory_base_framework; OPAL_DECLSPEC int opal_common_ofi_register_mca_variables(const mca_base_component_t *component); OPAL_DECLSPEC void opal_common_ofi_mca_register(void); @@ -54,6 +61,34 @@ OPAL_DECLSPEC void opal_common_ofi_mca_deregister(void); */ OPAL_DECLSPEC int opal_common_ofi_is_in_list(char **list, char *item); +#if OPAL_OFI_IMPORT_MONITOR_SUPPORT +/* + * @param buf (IN) Pointer to the start of the allocation + * @param length (IN) Length of the allocation + * @param cbdata (IN) Data passed to memory hooks when callback + * was registered + * @param from_alloc (IN) True if the callback is caused by a call to the + * general allocation routines (malloc, calloc, free, + * etc.) or directly from the user (mmap, munmap, etc.) + * + * Callback function triggered when memory is about to be freed. + * is about to be freed. The callback will be triggered according to + * the note in opal_mem_hooks_register_release(). + * + */ +OPAL_DECLSPEC void opal_common_ofi_mem_release_cb(void *buf, size_t length, void *cbdata, bool from_alloc); +#endif /* OPAL_OFI_IMPORT_MONITOR_SUPPORT */ + +/* + * Initializes common objects for libfabric + */ +OPAL_DECLSPEC int opal_common_ofi_init(void); + +/* + * Cleans up common objects for libfabric + */ +OPAL_DECLSPEC int opal_common_ofi_fini(void); + END_C_DECLS struct fi_info *opal_mca_common_ofi_select_provider(struct fi_info *provider_list,