From c7c3de87f5b214c61e3063c620f19bb939a2006f Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Tue, 11 May 2010 21:43:19 +0000 Subject: [PATCH] Add ummunotify support to Open MPI. See http://marc.info/?l=linux-mm-commits&m=127352503417787&w=2 for more details. * Remove the ptmalloc memory component; replace it with a new "linux" memory component. * The linux memory component will conditionally compile in support for ummunotify. At run-time, if it has ummunotify support and finds run-time support for ummunotify (i.e., /dev/ummunotify), it uses it. If not, it tries to use ptmalloc via the glibc memory hooks. * Add some more API functions to the memory framework to accomodate the ummunotify model (i.e., poll to see if memory has "changed"). * Add appropriate calls in the rcache to the new memory APIs to see if memory has changed, and to react accordingly. * Add a few comments in the openib BTL to indicate why we don't need to notify the OPAL memory framework about specific instances of registered memory. * Add dummy API calls in the solaris malloc component (since it doesn't have polling/"did memory change" support). This commit was SVN r23113. --- ompi/mca/btl/openib/btl_openib_component.c | 5 +- .../openib/connect/btl_openib_connect_base.c | 9 +- ompi/mca/mpool/rdma/mpool_rdma_module.c | 3 +- ompi/mca/rcache/rb/rcache_rb.c | 34 ++- ompi/mca/rcache/vma/rcache_vma.c | 44 +++- opal/mca/memory/base/Makefile.am | 7 +- opal/mca/memory/base/empty.h | 56 +++++ .../memory_base_empty.c} | 26 +- opal/mca/memory/base/memory_base_open.c | 25 +- opal/mca/memory/configure.m4 | 10 + .../COPYRIGHT-ptmalloc2.txt} | 0 .../ChangeLog-ptmalloc2.txt} | 0 .../memory/{ptmalloc2 => linux}/Makefile.am | 73 +++--- .../{ptmalloc2 => linux}/README-open-mpi.txt | 0 .../README => linux/README-ptmalloc2.txt} | 0 opal/mca/memory/{ptmalloc2 => linux}/arena.c | 18 +- opal/mca/memory/linux/configure.m4 | 196 +++++++++++++++ .../{ptmalloc2 => linux}/configure.params | 2 +- .../memory/linux/help-opal-memory-linux.txt | 42 ++++ opal/mca/memory/{ptmalloc2 => linux}/hooks.c | 76 +++--- opal/mca/memory/{ptmalloc2 => linux}/lran2.h | 0 .../{ptmalloc2 => linux}/malloc-stats.c | 7 +- opal/mca/memory/{ptmalloc2 => linux}/malloc.c | 88 +++---- opal/mca/memory/{ptmalloc2 => linux}/malloc.h | 0 opal/mca/memory/linux/memory_linux.h | 67 +++++ .../mca/memory/linux/memory_linux_component.c | 210 ++++++++++++++++ .../memory_linux_munmap.c} | 53 ++-- .../mca/memory/linux/memory_linux_ptmalloc2.c | 136 ++++++++++ .../memory/linux/memory_linux_ummunotify.c | 234 ++++++++++++++++++ opal/mca/memory/linux/public.h | 24 ++ opal/mca/memory/{ptmalloc2 => linux}/rename.h | 0 .../sysdeps/generic/atomic.h | 0 .../sysdeps/generic/malloc-machine.h | 0 .../sysdeps/generic/thread-st.h | 0 .../sysdeps/pthread/malloc-machine.h | 0 .../sysdeps/pthread/thread-st.h | 0 .../sysdeps/solaris/malloc-machine.h | 0 .../sysdeps/solaris/thread-st.h | 0 .../sysdeps/sproc/malloc-machine.h | 0 .../sysdeps/sproc/thread-st.h | 0 opal/mca/memory/{ptmalloc2 => linux}/t-test.h | 0 .../mca/memory/{ptmalloc2 => linux}/t-test1.c | 0 .../mca/memory/{ptmalloc2 => linux}/t-test2.c | 0 .../{ptmalloc2 => linux}/tst-mallocstate.c | 0 .../memory/{ptmalloc2 => linux}/tst-mstats.c | 0 .../memory_malloc_solaris_component.c | 8 + opal/mca/memory/memory.h | 115 +++++++-- opal/mca/memory/ptmalloc2/configure.m4 | 133 ---------- .../ptmalloc2/help-opal-memory-ptmalloc2.txt | 23 -- .../ptmalloc2/opal_ptmalloc2_component.c | 150 ----------- 50 files changed, 1362 insertions(+), 512 deletions(-) create mode 100644 opal/mca/memory/base/empty.h rename opal/mca/memory/{ptmalloc2/opal_ptmalloc2_munmap.h => base/memory_base_empty.c} (60%) rename opal/mca/memory/{ptmalloc2/ptmalloc2-COPYRIGHT => linux/COPYRIGHT-ptmalloc2.txt} (100%) rename opal/mca/memory/{ptmalloc2/ChangeLog => linux/ChangeLog-ptmalloc2.txt} (100%) rename opal/mca/memory/{ptmalloc2 => linux}/Makefile.am (55%) rename opal/mca/memory/{ptmalloc2 => linux}/README-open-mpi.txt (100%) rename opal/mca/memory/{ptmalloc2/README => linux/README-ptmalloc2.txt} (100%) rename opal/mca/memory/{ptmalloc2 => linux}/arena.c (97%) create mode 100644 opal/mca/memory/linux/configure.m4 rename opal/mca/memory/{ptmalloc2 => linux}/configure.params (96%) create mode 100644 opal/mca/memory/linux/help-opal-memory-linux.txt rename opal/mca/memory/{ptmalloc2 => linux}/hooks.c (92%) rename opal/mca/memory/{ptmalloc2 => linux}/lran2.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/malloc-stats.c (97%) rename opal/mca/memory/{ptmalloc2 => linux}/malloc.c (98%) rename opal/mca/memory/{ptmalloc2 => linux}/malloc.h (100%) create mode 100644 opal/mca/memory/linux/memory_linux.h create mode 100644 opal/mca/memory/linux/memory_linux_component.c rename opal/mca/memory/{ptmalloc2/opal_ptmalloc2_munmap.c => linux/memory_linux_munmap.c} (63%) create mode 100644 opal/mca/memory/linux/memory_linux_ptmalloc2.c create mode 100644 opal/mca/memory/linux/memory_linux_ummunotify.c create mode 100644 opal/mca/memory/linux/public.h rename opal/mca/memory/{ptmalloc2 => linux}/rename.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/generic/atomic.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/generic/malloc-machine.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/generic/thread-st.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/pthread/malloc-machine.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/pthread/thread-st.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/solaris/malloc-machine.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/solaris/thread-st.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/sproc/malloc-machine.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/sysdeps/sproc/thread-st.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/t-test.h (100%) rename opal/mca/memory/{ptmalloc2 => linux}/t-test1.c (100%) rename opal/mca/memory/{ptmalloc2 => linux}/t-test2.c (100%) rename opal/mca/memory/{ptmalloc2 => linux}/tst-mallocstate.c (100%) rename opal/mca/memory/{ptmalloc2 => linux}/tst-mstats.c (100%) delete mode 100644 opal/mca/memory/ptmalloc2/configure.m4 delete mode 100644 opal/mca/memory/ptmalloc2/help-opal-memory-ptmalloc2.txt delete mode 100644 opal/mca/memory/ptmalloc2/opal_ptmalloc2_component.c diff --git a/ompi/mca/btl/openib/btl_openib_component.c b/ompi/mca/btl/openib/btl_openib_component.c index d44abd4e75..a7a9b81b6c 100644 --- a/ompi/mca/btl/openib/btl_openib_component.c +++ b/ompi/mca/btl/openib/btl_openib_component.c @@ -45,7 +45,6 @@ const char *ibv_get_sysfs_path(void); #include #include -#include "ompi/constants.h" #include "opal/event/event.h" #include "opal/align.h" #include "opal/util/output.h" @@ -66,6 +65,7 @@ const char *ibv_get_sysfs_path(void); #include "orte/runtime/orte_globals.h" #include "orte/mca/notifier/notifier.h" +#include "ompi/constants.h" #include "ompi/proc/proc.h" #include "ompi/mca/btl/btl.h" #include "ompi/mca/mpool/base/base.h" @@ -518,8 +518,9 @@ static int openib_reg_mr(void *reg_data, void *base, size_t size, openib_reg->mr = ibv_reg_mr(device->ib_pd, base, size, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ); - if(NULL == openib_reg->mr) + if (NULL == openib_reg->mr) { return OMPI_ERR_OUT_OF_RESOURCE; + } return OMPI_SUCCESS; } diff --git a/ompi/mca/btl/openib/connect/btl_openib_connect_base.c b/ompi/mca/btl/openib/connect/btl_openib_connect_base.c index 43385f5d9e..03dc5f5eb2 100644 --- a/ompi/mca/btl/openib/connect/btl_openib_connect_base.c +++ b/ompi/mca/btl/openib/connect/btl_openib_connect_base.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2007-2009 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2007 Mellanox Technologies, Inc. All rights reserved. * * $COPYRIGHT$ @@ -430,6 +430,10 @@ int ompi_btl_openib_connect_base_alloc_cts(mca_btl_base_endpoint_t *endpoint) BTL_ERROR(("Failed to reg mr!")); return OMPI_ERR_OUT_OF_RESOURCE; } + /* NOTE: We do not need to register this memory with the + opal_memory subsystem, because this is OMPI-controlled memory + -- we do not need to worry about this memory being freed out + from underneath us. */ /* Copy the lkey where it needs to go */ endpoint->endpoint_cts_frag.super.sg_entry.lkey = @@ -453,6 +457,9 @@ int ompi_btl_openib_connect_base_alloc_cts(mca_btl_base_endpoint_t *endpoint) int ompi_btl_openib_connect_base_free_cts(mca_btl_base_endpoint_t *endpoint) { + /* NOTE: We don't need to deregister this memory with opal_memory + because it was not registered there in the first place (see + comment above, near call to ibv_reg_mr). */ if (NULL != endpoint->endpoint_cts_mr) { ibv_dereg_mr(endpoint->endpoint_cts_mr); endpoint->endpoint_cts_mr = NULL; diff --git a/ompi/mca/mpool/rdma/mpool_rdma_module.c b/ompi/mca/mpool/rdma/mpool_rdma_module.c index 8a2f7430fb..9c4b9a22b2 100644 --- a/ompi/mca/mpool/rdma/mpool_rdma_module.c +++ b/ompi/mca/mpool/rdma/mpool_rdma_module.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology @@ -10,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2006-2008 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2006-2009 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2006 Voltaire. All rights reserved. * Copyright (c) 2007 Mellanox Technologies. All rights reserved. * Copyright (c) 2010 IBM Corporation. All rights reserved. diff --git a/ompi/mca/rcache/rb/rcache_rb.c b/ompi/mca/rcache/rb/rcache_rb.c index 99571e65da..dda993d24f 100644 --- a/ompi/mca/rcache/rb/rcache_rb.c +++ b/ompi/mca/rcache/rb/rcache_rb.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology @@ -10,6 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -18,6 +18,9 @@ */ #include "ompi_config.h" + +#include MCA_memory_IMPLEMENTATION_HEADER +#include "opal/mca/memory/memory.h" #include "ompi/mca/rcache/rcache.h" #include "rcache_rb.h" #include "rcache_rb_tree.h" @@ -55,6 +58,13 @@ int mca_rcache_rb_find( struct mca_rcache_base_module_t* rcache, OPAL_THREAD_LOCK(&rcache->lock); *cnt = 0; + /* Check to ensure that the cache is valid */ + if (OPAL_UNLIKELY(opal_memory_changed() && + NULL != opal_memory->memoryc_process && + OPAL_SUCCESS != (rc = opal_memory->memoryc_process()))) { + return rc; + } + if(ompi_rb_tree_size(&((mca_rcache_rb_module_t*)rcache)->rb_tree) == 0) { OPAL_THREAD_UNLOCK(&rcache->lock); return OMPI_SUCCESS; @@ -100,6 +110,14 @@ int mca_rcache_rb_insert ( OPAL_THREAD_LOCK(&rcache->lock); reg->flags = flags; + + /* Check to ensure that the cache is valid */ + if (OPAL_UNLIKELY(opal_memory_changed() && + NULL != opal_memory->memoryc_process && + OPAL_SUCCESS != (rc = opal_memory->memoryc_process()))) { + return rc; + } + if(flags & MCA_MPOOL_FLAGS_CACHE) { rc = mca_rcache_rb_mru_insert( (mca_rcache_rb_module_t*) rcache, reg); if(OMPI_SUCCESS != rc) { @@ -119,6 +137,15 @@ int mca_rcache_rb_insert ( } rc = mca_rcache_rb_tree_insert((mca_rcache_rb_module_t*)rcache, reg); OPAL_THREAD_ADD32((int32_t*) ®->ref_count, 1); + + if (OPAL_LIKELY(OMPI_SUCCESS == rc)) { + /* If we successfully registered, then tell the memory manager + to start monitoring this region */ + opal_memory->memoryc_register(reg->base, + (uint64_t) reg->bound - reg->base + 1, + (uint64_t) reg); + } + OPAL_THREAD_UNLOCK(&rcache->lock); return rc; } @@ -133,6 +160,11 @@ int mca_rcache_rb_delete ( assert(reg->ref_count >= 1); OPAL_THREAD_LOCK(&rcache->lock); + /* Tell the memory manager that we no longer care about this + region */ + opal_memory->memoryc_deregister(reg->base, + (uint64_t) (reg->bound - reg->base), + (uint64_t) reg); if(flags & MCA_MPOOL_FLAGS_CACHE) { assert(reg->ref_count >= 2); OPAL_THREAD_ADD32((int32_t*)®->ref_count, -1); diff --git a/ompi/mca/rcache/vma/rcache_vma.c b/ompi/mca/rcache/vma/rcache_vma.c index a338a6e189..a1623c56c9 100644 --- a/ompi/mca/rcache/vma/rcache_vma.c +++ b/ompi/mca/rcache/vma/rcache_vma.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology @@ -10,8 +9,8 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * * Copyright (c) 2006 Voltaire. All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2009 IBM Corporation. All rights reserved. * * $COPYRIGHT$ @@ -23,6 +22,8 @@ #include "ompi_config.h" +#include MCA_memory_IMPLEMENTATION_HEADER +#include "opal/mca/memory/memory.h" #include "ompi/mca/rcache/rcache.h" #include "rcache_vma.h" #include "rcache_vma_tree.h" @@ -46,6 +47,7 @@ void mca_rcache_vma_module_init( mca_rcache_vma_module_t* rcache ) { int mca_rcache_vma_find(struct mca_rcache_base_module_t* rcache, void* addr, size_t size, mca_mpool_base_registration_t **reg) { + int rc; void* base_addr; void* bound_addr; @@ -56,6 +58,13 @@ int mca_rcache_vma_find(struct mca_rcache_base_module_t* rcache, base_addr = down_align_addr(addr, mca_mpool_base_page_size_log); bound_addr = up_align_addr((void*) ((unsigned long) addr + size - 1), mca_mpool_base_page_size_log); + /* Check to ensure that the cache is valid */ + if (OPAL_UNLIKELY(opal_memory_changed() && + NULL != opal_memory->memoryc_process && + OPAL_SUCCESS != (rc = opal_memory->memoryc_process()))) { + return rc; + } + *reg = mca_rcache_vma_tree_find((mca_rcache_vma_module_t*)rcache, (unsigned char*)base_addr, (unsigned char*)bound_addr); @@ -66,6 +75,7 @@ int mca_rcache_vma_find_all(struct mca_rcache_base_module_t* rcache, void* addr, size_t size, mca_mpool_base_registration_t **regs, int reg_cnt) { + int rc; void *base_addr, *bound_addr; if(size == 0) { @@ -75,6 +85,13 @@ int mca_rcache_vma_find_all(struct mca_rcache_base_module_t* rcache, base_addr = down_align_addr(addr, mca_mpool_base_page_size_log); bound_addr = up_align_addr((void*) ((unsigned long) addr + size - 1), mca_mpool_base_page_size_log); + /* Check to ensure that the cache is valid */ + if (OPAL_UNLIKELY(opal_memory_changed() && + NULL != opal_memory->memoryc_process && + OPAL_SUCCESS != (rc = opal_memory->memoryc_process()))) { + return rc; + } + return mca_rcache_vma_tree_find_all((mca_rcache_vma_module_t*)rcache, (unsigned char*)base_addr, (unsigned char*)bound_addr, regs, reg_cnt); @@ -83,6 +100,7 @@ int mca_rcache_vma_find_all(struct mca_rcache_base_module_t* rcache, int mca_rcache_vma_insert(struct mca_rcache_base_module_t* rcache, mca_mpool_base_registration_t* reg, size_t limit) { + int rc; size_t reg_size = reg->bound - reg->base + 1; mca_rcache_vma_module_t *vma_rcache = (mca_rcache_vma_module_t*)rcache; @@ -92,13 +110,33 @@ int mca_rcache_vma_insert(struct mca_rcache_base_module_t* rcache, return OMPI_ERR_OUT_OF_RESOURCE; } - return mca_rcache_vma_tree_insert(vma_rcache, reg, limit); + /* Check to ensure that the cache is valid */ + if (OPAL_UNLIKELY(opal_memory_changed() && + NULL != opal_memory->memoryc_process && + OPAL_SUCCESS != (rc = opal_memory->memoryc_process()))) { + return rc; + } + + rc = mca_rcache_vma_tree_insert(vma_rcache, reg, limit); + if (OPAL_LIKELY(OMPI_SUCCESS == rc)) { + /* If we successfully registered, then tell the memory manager + to start monitoring this region */ + opal_memory->memoryc_register(reg->base, + (uint64_t) reg_size, (uint64_t) reg); + } + + return rc; } int mca_rcache_vma_delete(struct mca_rcache_base_module_t* rcache, mca_mpool_base_registration_t* reg) { mca_rcache_vma_module_t *vma_rcache = (mca_rcache_vma_module_t*)rcache; + /* Tell the memory manager that we no longer care about this + region */ + opal_memory->memoryc_deregister(reg->base, + (uint64_t) (reg->bound - reg->base), + (uint64_t) reg); return mca_rcache_vma_tree_delete(vma_rcache, reg); } diff --git a/opal/mca/memory/base/Makefile.am b/opal/mca/memory/base/Makefile.am index 6cf374490b..65c0cac529 100644 --- a/opal/mca/memory/base/Makefile.am +++ b/opal/mca/memory/base/Makefile.am @@ -9,6 +9,7 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. +# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -17,8 +18,10 @@ # headers += \ - base/base.h + base/base.h \ + base/empty.h libmca_memory_la_SOURCES += \ base/memory_base_close.c \ - base/memory_base_open.c + base/memory_base_open.c \ + base/memory_base_empty.c diff --git a/opal/mca/memory/base/empty.h b/opal/mca/memory/base/empty.h new file mode 100644 index 0000000000..5067bf2f07 --- /dev/null +++ b/opal/mca/memory/base/empty.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_MEMCPY_BASE_MEMORY_BASE_DEFAULT_H +#define OPAL_MCA_MEMCPY_BASE_MEMORY_BASE_DEFAULT_H + +#include "opal_config.h" + +/** + * Provided for memory components that don't provide an asynchronous + * method for determining if memory mappings have changed. If a + * component only has a synchronous / interactive method of checking, + * then it can override this macro with some logic to do a (hopefully) + * cheap check to see if memory mappings have changed. The intent is + * that if this cheap check returns true, the upper layer will then + * invoke the memoryc_process() function to actually process what + * changed. This function will be invoked by the upper layer with the + * syntax: + * + * if (opal_memory_changed()) { ... } + * + * Hence, if you need any kind of sophisticated logic, you might want + * to put it in an inline function and have the #define call the + * inline function. + */ +#define opal_memory_changed() 0 + +BEGIN_C_DECLS + +/** + * Default (empty) implementation of the memoryc_register function. + * + * See opal/mca/memory/memory.h for a description of the parameters. + */ +OPAL_DECLSPEC int opal_memory_base_component_register_empty(void *start, + size_t len, + uint64_t cookie); + +/** + * Default (empty) implementation of the memoryc_deregister function + * + * See opal/mca/memory/memory.h for a description of the parameters. + */ +OPAL_DECLSPEC int opal_memory_base_component_deregister_empty(void *start, + size_t len, + uint64_t cookie); + +END_C_DECLS + +#endif diff --git a/opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.h b/opal/mca/memory/base/memory_base_empty.c similarity index 60% rename from opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.h rename to opal/mca/memory/base/memory_base_empty.c index 1b154bd134..804116a47b 100644 --- a/opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.h +++ b/opal/mca/memory/base/memory_base_empty.c @@ -5,11 +5,10 @@ * Copyright (c) 2004-2005 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. - * Copyright (c) 2004-2007 High Performance Computing Center Stuttgart, + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -17,18 +16,21 @@ * $HEADER$ */ -#ifndef OPAL_PTMALLOC2_MUNMAP_H -#define OPAL_PTMALLOC2_MUNMAP_H - #include "opal_config.h" -BEGIN_C_DECLS - -OPAL_DECLSPEC int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int call_hooks); - -OPAL_DECLSPEC int munmap(void* addr, size_t len); +#include "opal/constants.h" +#include "opal/mca/memory/base/empty.h" -END_C_DECLS +int opal_memory_base_component_register_empty(void *base, size_t len, + uint64_t cookie) +{ + return OPAL_SUCCESS; +} -#endif /* !OPAL_PTMALLOC2_MUNMAP_H */ + +int opal_memory_base_component_deregister_empty(void *base, size_t len, + uint64_t cookie) +{ + return OPAL_SUCCESS; +} diff --git a/opal/mca/memory/base/memory_base_open.c b/opal/mca/memory/base/memory_base_open.c index 0abb8b4da2..4eaa06b919 100644 --- a/opal/mca/memory/base/memory_base_open.c +++ b/opal/mca/memory/base/memory_base_open.c @@ -9,6 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -25,6 +26,7 @@ #include "opal/mca/base/mca_base_param.h" #include "opal/mca/memory/memory.h" #include "opal/mca/memory/base/base.h" +#include "opal/mca/memory/base/empty.h" /* @@ -34,12 +36,31 @@ */ #include "opal/mca/memory/base/static-components.h" +static int empty_process(void) +{ + return OPAL_SUCCESS; +} + + +/* + * Local variables + */ +static opal_memory_base_component_2_0_0_t empty_component = { + /* Don't care about the version info */ + { 0, }, + /* Don't care about the data */ + { 0, }, + /* Empty / safe functions to call if no memory componet is selected */ + empty_process, + opal_memory_base_component_register_empty, + opal_memory_base_component_deregister_empty, +}; /* * Globals */ opal_list_t opal_memory_base_components_opened; -opal_memory_base_component_2_0_0_t *opal_memory_active_component = NULL; +opal_memory_base_component_2_0_0_t *opal_memory = &empty_component; /* * Function for finding and opening either all MCA components, or the one @@ -61,7 +82,7 @@ int opal_memory_base_open(void) mca_base_component_list_item_t *item; item = (mca_base_component_list_item_t*) opal_list_get_first(&opal_memory_base_components_opened); - opal_memory_active_component = (opal_memory_base_component_2_0_0_t*) + opal_memory = (opal_memory_base_component_2_0_0_t*) item->cli_component; } diff --git a/opal/mca/memory/configure.m4 b/opal/mca/memory/configure.m4 index e3f0426d88..bc945e4e6c 100644 --- a/opal/mca/memory/configure.m4 +++ b/opal/mca/memory/configure.m4 @@ -10,6 +10,7 @@ dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, dnl University of Stuttgart. All rights reserved. dnl Copyright (c) 2004-2005 The Regents of the University of California. dnl All rights reserved. +dnl Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. dnl $COPYRIGHT$ dnl dnl Additional copyrights may follow @@ -33,4 +34,13 @@ AC_DEFUN([MCA_memory_CONFIG],[ AC_DEFINE_UNQUOTED([OMPI_MEMORY_HAVE_COMPONENT], [$memory_base_found], [Whether any opal memory mca components were found]) + + # See if someone set to use their header file + if test "$memory_base_include" = "" ; then + memory_base_include="base/empty.h" + fi + + AC_DEFINE_UNQUOTED([MCA_memory_IMPLEMENTATION_HEADER], + ["opal/mca/memory/$memory_base_include"], + [Header to include for parts of the memory implementation]) ]) diff --git a/opal/mca/memory/ptmalloc2/ptmalloc2-COPYRIGHT b/opal/mca/memory/linux/COPYRIGHT-ptmalloc2.txt similarity index 100% rename from opal/mca/memory/ptmalloc2/ptmalloc2-COPYRIGHT rename to opal/mca/memory/linux/COPYRIGHT-ptmalloc2.txt diff --git a/opal/mca/memory/ptmalloc2/ChangeLog b/opal/mca/memory/linux/ChangeLog-ptmalloc2.txt similarity index 100% rename from opal/mca/memory/ptmalloc2/ChangeLog rename to opal/mca/memory/linux/ChangeLog-ptmalloc2.txt diff --git a/opal/mca/memory/ptmalloc2/Makefile.am b/opal/mca/memory/linux/Makefile.am similarity index 55% rename from opal/mca/memory/ptmalloc2/Makefile.am rename to opal/mca/memory/linux/Makefile.am index 4bce900ad9..41c20dd618 100644 --- a/opal/mca/memory/ptmalloc2/Makefile.am +++ b/opal/mca/memory/linux/Makefile.am @@ -9,6 +9,7 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. +# Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -36,52 +37,60 @@ AM_CPPFLAGS += -I$(srcdir)/sysdeps/generic # copyright notices. docdir = $(datadir)/openmpi/doc -doc_DATA = ptmalloc2-COPYRIGHT - -# These are the files from ptmalloc2 that we care about -ptmalloc2_sources = \ - malloc.c \ - malloc-stats.c \ - malloc.h +doc_DATA = COPYRIGHT-ptmalloc2.txt # Help file -dist_pkgdata_DATA = help-opal-memory-ptmalloc2.txt +dist_pkgdata_DATA = help-opal-memory-linux.txt # This component is only ever built statically (i.e., slurped into # libopen-pal) -- it is never built as a DSO. -noinst_LTLIBRARIES = libmca_memory_ptmalloc2.la -libmca_memory_ptmalloc2_la_SOURCES = \ - opal_ptmalloc2_component.c \ - opal_ptmalloc2_munmap.c \ - rename.h \ - $(ptmalloc2_sources) -libmca_memory_ptmalloc2_la_LDFLAGS = \ - -module -avoid-version $(memory_ptmalloc2_LDFLAGS) -libmca_memory_ptmalloc2_la_LIBADD = $(memory_ptmalloc2_LIBS) +noinst_LTLIBRARIES = libmca_memory_linux.la +libmca_memory_linux_la_SOURCES = \ + memory_linux.h \ + memory_linux_component.c +libmca_memory_linux_la_LDFLAGS = \ + -module -avoid-version $(memory_linux_LDFLAGS) +libmca_memory_linux_la_LIBADD = $(memory_linux_LIBS) + +# Do we have ptmalloc2 support? +if MEMORY_LINUX_PTMALLOC2 +libmca_memory_linux_la_SOURCES += \ + memory_linux_ptmalloc2.c \ + memory_linux_munmap.c \ + rename.h \ + malloc.c \ + malloc-stats.c \ + malloc.h +endif + +# Do we have ummunotify support? +if MEMORY_LINUX_UMMUNOTIFY +libmca_memory_linux_la_SOURCES += memory_linux_ummunotify.c public.h +endif # these are included directly and shouldn't be built solo -EXTRA_libmca_memory_ptmalloc2_la_SOURCES = \ +EXTRA_libmca_memory_linux_la_SOURCES = \ arena.c \ hooks.c EXTRA_DIST = \ - ChangeLog \ - README \ - ChangeLog \ + README-open-mpi.txt \ + README-ptmalloc2.txt \ + ChangeLog-ptmalloc2.txt \ + COPYRIGHT-ptmalloc2.txt \ lran2.h \ - opal_ptmalloc2_munmap.h \ t-test.h \ t-test1.c \ t-test2.c \ tst-mallocstate.c \ tst-mstats.c \ - sysdeps/sproc/malloc-machine.h \ - sysdeps/sproc/thread-st.h \ - sysdeps/pthread/malloc-machine.h \ - sysdeps/pthread/thread-st.h \ - sysdeps/solaris/malloc-machine.h \ - sysdeps/solaris/thread-st.h \ - sysdeps/generic/malloc-machine.h \ - sysdeps/generic/thread-st.h \ - sysdeps/generic/atomic.h \ - $(doc_DATA) + sysdeps/sproc/malloc-machine.h \ + sysdeps/sproc/thread-st.h \ + sysdeps/pthread/malloc-machine.h \ + sysdeps/pthread/thread-st.h \ + sysdeps/solaris/malloc-machine.h \ + sysdeps/solaris/thread-st.h \ + sysdeps/generic/malloc-machine.h \ + sysdeps/generic/thread-st.h \ + sysdeps/generic/atomic.h \ + $(doc_DATA) diff --git a/opal/mca/memory/ptmalloc2/README-open-mpi.txt b/opal/mca/memory/linux/README-open-mpi.txt similarity index 100% rename from opal/mca/memory/ptmalloc2/README-open-mpi.txt rename to opal/mca/memory/linux/README-open-mpi.txt diff --git a/opal/mca/memory/ptmalloc2/README b/opal/mca/memory/linux/README-ptmalloc2.txt similarity index 100% rename from opal/mca/memory/ptmalloc2/README rename to opal/mca/memory/linux/README-ptmalloc2.txt diff --git a/opal/mca/memory/ptmalloc2/arena.c b/opal/mca/memory/linux/arena.c similarity index 97% rename from opal/mca/memory/ptmalloc2/arena.c rename to opal/mca/memory/linux/arena.c index 8c6bc8ef7f..e3f7d69d14 100644 --- a/opal/mca/memory/ptmalloc2/arena.c +++ b/opal/mca/memory/linux/arena.c @@ -18,10 +18,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Copyright (c) 2009-2010 IBM Corporation. All rights reserved. - * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. - */ - /* $Id: arena.c,v 1.9 2004/11/05 14:42:23 wg Exp $ */ /* Compile-time constants. */ @@ -294,7 +290,6 @@ ptmalloc_unlock_all2 __MALLOC_P((void)) #endif /* !defined NO_THREADS */ - /* Initialization routine. */ #ifdef _LIBC #include @@ -520,10 +515,6 @@ dump_heap(heap) heap_info *heap; #endif /* MALLOC_DEBUG > 1 */ - -extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int run_hooks); - - /* Create a new heap. size is automatically rounded up to a multiple of the page size. */ @@ -558,9 +549,8 @@ new_heap(size, top_pad) size_t size, top_pad; if(p1 != MAP_FAILED) { p2 = (char *)(((unsigned long)p1 + (HEAP_MAX_SIZE-1)) & ~(HEAP_MAX_SIZE-1)); ul = p2 - p1; - opal_mem_free_ptmalloc2_munmap(p1, ul, 1, 0); - opal_mem_free_ptmalloc2_munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul, - 1, 0); + munmap(p1, ul); + munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); } else { /* Try to take the chance that an allocation of only HEAP_MAX_SIZE is already aligned. */ @@ -568,12 +558,12 @@ new_heap(size, top_pad) size_t size, top_pad; if(p2 == MAP_FAILED) return 0; if((unsigned long)p2 & (HEAP_MAX_SIZE-1)) { - opal_mem_free_ptmalloc2_munmap(p2, HEAP_MAX_SIZE, 1, 0); + munmap(p2, HEAP_MAX_SIZE); return 0; } } if(mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) { - opal_mem_free_ptmalloc2_munmap(p2, HEAP_MAX_SIZE, 1, 0); + munmap(p2, HEAP_MAX_SIZE); return 0; } h = (heap_info *)p2; diff --git a/opal/mca/memory/linux/configure.m4 b/opal/mca/memory/linux/configure.m4 new file mode 100644 index 0000000000..5adf394092 --- /dev/null +++ b/opal/mca/memory/linux/configure.m4 @@ -0,0 +1,196 @@ +# -*- shell-script -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2008-2010 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AC_DEFUN([MCA_memory_linux_COMPILE_MODE], [ + AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) + $4="static" + AC_MSG_RESULT([$$4]) +]) + + +# MCA_memory_linux_CONFIG(action-if-can-compile, +# [action-if-cant-compile]) +# ------------------------------------------------ +AC_DEFUN([MCA_memory_linux_CONFIG],[ + OMPI_VAR_SCOPE_PUSH([memory_linux_ptmalloc2_happy memory_linux_ummu_happy memory_linux_requested icc_major_ver icc_minor_ver memory_linux_mmap memory_linux_munmap memory_linux_LIBS_SAVE]) + + # Only allow this component to build on Linux-based systems + + AC_MSG_CHECKING([operating system]) + case $host in + *linux*) + AC_MSG_RESULT([$host -- supported]) + memory_linux_ptmalloc2_happy=yes + memory_linux_ummu_happy=yes + ;; + *) + AC_MSG_RESULT([$host -- unsupported]) + memory_linux_ptmalloc2_happy=no + memory_linux_ummu_happy=no + ;; + esac + + AS_IF([test "$with_memory_manager" = "linux"], + [memory_linux_ptmalloc2_happy=yes + memory_linux_ummu_happy=yes + memory_linux_requested=1], + [memory_linux_requested=0 + AS_IF([test "$with_memory_manager" = ""], + [memory_linux_ptmalloc2_happy=yes + memory_linux_ummu_happy=yes], + [memory_linux_ptmalloc2_happy=yes + memory_linux_ummu_happy=no])]) + + ###################################################################### + # ptmalloc2 + ###################################################################### + + # Per ticket #227, Intel 9.0 v20051201 on ia64 with optimization + # of -O2 or higher will bork linux in strange in mysterious ways. + # Doh! So if the compiler vendor is intel and we're on an ia64 + # box, run "icc --version" and snarf the version string. If it's + # 9.0 and the version is <= 20051201, then disable ptmalloc2. + # Executive decision: ignore optimization levels (even though -O1 + # and -O0 seem to work). The upgrade to 9.1 is free, so that's a + # better path than trying to make a much more complicated test + # here. + + AS_IF([test "$memory_linux_ptmalloc2_happy" = yes], + [case $host in + ia64-*) + AS_IF([test "$ompi_c_vendor" = "intel"], + [# check for v9.0 <= 20051201 + icc_major_ver="`$CC --version | head -n 1 | awk '{ print [$]3 }'`" + icc_minor_ver="`$CC --version | head -n 1 | awk '{ print [$]4 }'`" + AS_IF([test "$icc_major_ver" = "9.0" -a "`expr $icc_minor_ver \<= 20051201`" = "1"], + [memory_linux_ptmalloc2_happy=no + AC_MSG_WARN([*** Detected Intel C compiler v9.0 <= 20051201 on ia64]) + AC_MSG_WARN([*** This compiler/platform combination has known problems with ptmalloc2]) + AC_MSG_WARN([*** Disabling ptmalloc2])])]) + ;; + esac]) + + AS_IF([test "$memory_linux_ptmalloc2_happy" = yes], + [# check for malloc.h + AC_CHECK_HEADER([malloc.h], + [memory_linux_ptmalloc2_happy=yes], + [memory_linux_ptmalloc2_happy=no])]) + + AS_IF([test "$memory_linux_ptmalloc2_happy" = yes], + [# check for init hook symbol + AC_CHECK_DECL([__malloc_initialize_hook], + [memory_linux_ptmalloc2_happy=yes], + [memory_linux_ptmalloc2_happy=no], + [AC_INCLUDES_DEFAULT + #include ])]) + + # + # See if we have sbrk prototyped + # + AS_IF([test "$memory_linux_ptmalloc2_happy" = yes], + [AC_CHECK_DECLS([sbrk])]) + + # + # Figure out how we're going to call mmap/munmap for real + # + AS_IF([test "$memory_linux_ptmalloc2_happy" = yes], + [memory_linux_mmap=0 + memory_linux_munmap=1 + + # it's nearly impossible to call mmap from syscall(), so + # only go this route if we can't get at munmap any other + # way. + AC_CHECK_HEADER([syscall.h], + [AC_CHECK_FUNCS([syscall], [], [memory_linux_munmap=0])]) + + # Always look for __munmap and __mmap + AC_CHECK_FUNCS([__munmap], [memory_linux_mmap=1]) + AC_CHECK_FUNCS([__mmap]) + + # only allow dlsym (and therefore add -ldl) if we + # really need to + AS_IF([test "$memory_linux_mmap" = "0"], + [memory_linux_LIBS_SAVE="$LIBS" + AC_CHECK_LIB([dl], + [dlsym], + [LIBS="$LIBS -ldl" + memory_linux_LIBS="-ldl" + memory_linux_mmap=1]) + AC_CHECK_FUNCS([dlsym]) + LIBS="$memory_linux_LIBS_SAVE"]) + + AS_IF([test "$memory_linux_mmap" = "0" -a "$memory_linux_munmap" = "0"], + [memory_linux_ptmalloc2_happy=no])]) + + # If all is good, save the extra libs for the wrapper + AS_IF([test "$memory_linux_ptmalloc2_happy" = yes], + [memory_linux_WRAPPER_EXTRA_LIBS="$memory_linux_LIBS" + value=1], + [value=0]) + AC_DEFINE_UNQUOTED([MEMORY_LINUX_PTMALLOC2], [$value], + [Whether ptmalloc2 is supported on this system or not]) + AM_CONDITIONAL([MEMORY_LINUX_PTMALLOC2], + [test "$memory_linux_ptmalloc2_happy" = yes]) + + ###################################################################### + # ummunotify + ###################################################################### + + # Check for the relevant header + AS_IF([test "$memory_linux_ummu_happy" = yes], + [# check for linux/ummunotify.h + AC_CHECK_HEADER([linux/ummunotify.h], + [memory_linux_ummu_happy=yes], + [memory_linux_ummu_happy=no])]) + + # has the Linux declaration for ioctl + AC_CHECK_HEADERS([stropts.h]) + + # If all is good, set the header file that we want the rest of the + # code base to use + AS_IF([test "$memory_linux_ummu_happy" = yes], + [memory_base_include="linux/public.h" + value=1], + [value=0]) + AC_DEFINE_UNQUOTED([MEMORY_LINUX_UMMUNOTIFY], [$value], + [Whether ummunotify is supported on this system or not]) + AM_CONDITIONAL([MEMORY_LINUX_UMMUNOTIFY], + [test "$memory_linux_ummu_happy" = yes]) + + ###################################################################### + # post processing + ###################################################################### + + AS_IF([test "$memory_malloc_hooks_requested" = 1 -a \ + "$memory_linux_ptmalloc2_happy" = no -a \ + "$memory_linux_ummu_happy" = no], + [AC_MSG_ERROR([linux memory management requested but neither ptmalloc2 nor ummunotify are available. Aborting.])]) + AC_SUBST([memory_linux_LIBS]) + + AS_IF([test "$memory_linux_ptmalloc2_happy" = yes -o \ + "$memory_linux_ummu_happy" = yes], + [memory_base_found=1 + $1], + [memory_base_found=0 + memory_base_include= + $2]) + + OMPI_VAR_SCOPE_POP +]) diff --git a/opal/mca/memory/ptmalloc2/configure.params b/opal/mca/memory/linux/configure.params similarity index 96% rename from opal/mca/memory/ptmalloc2/configure.params rename to opal/mca/memory/linux/configure.params index 526024db36..ff14c5c34a 100644 --- a/opal/mca/memory/ptmalloc2/configure.params +++ b/opal/mca/memory/linux/configure.params @@ -19,5 +19,5 @@ # Specific to this module -PARAM_CONFIG_PRIORITY=20 +PARAM_CONFIG_PRIORITY=40 PARAM_CONFIG_FILES="Makefile" diff --git a/opal/mca/memory/linux/help-opal-memory-linux.txt b/opal/mca/memory/linux/help-opal-memory-linux.txt new file mode 100644 index 0000000000..0f9db1f4c8 --- /dev/null +++ b/opal/mca/memory/linux/help-opal-memory-linux.txt @@ -0,0 +1,42 @@ +# -*- text -*- +# +# Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# +# This is the US/English help file for Open MPI's memory/linux component. +# +[disable incorrectly set] +WARNING: The special MCA parameter "%s" was set in +an unexpected way, and is likely not working the way you want it to. + +Specifically, this MCA parameter is "special" in that it can *only* be +set in the environment. Setting this value in a file -- and sometimes +even on the command line -- will not work as intended. The *only* way +to set this value is to set "OMPI_MCA_%s" in the environment before +starting your job. + + Value: %d + Source: %s +# +[ummunotify eaccess] +Open MPI was unable to open the UMMU notification device. This is +likely a permissions problem on the device itself. UMMU notification +support is therefore disabled in this process; an alternate memory +hook manager *may* be used instead (if available). + + Local host: %s + UMMU device: %s +# +[ummunotify open error] +Open MPI was unable to open the UMMU notification device. UMMU +notification support is therefore disabled in this process; an +alternate memory hook manager *may* be used instead (if available). + + Local host: %s + UMMU device: %s + Error: %s (%d) diff --git a/opal/mca/memory/ptmalloc2/hooks.c b/opal/mca/memory/linux/hooks.c similarity index 92% rename from opal/mca/memory/ptmalloc2/hooks.c rename to opal/mca/memory/linux/hooks.c index f60e661003..eea0dfac1c 100644 --- a/opal/mca/memory/ptmalloc2/hooks.c +++ b/opal/mca/memory/linux/hooks.c @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. + * + * Additional copyrights may follow. + */ /* Malloc implementation for multiple threads without lock contention. Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -28,7 +33,7 @@ #include "opal/util/show_help.h" #include "opal/constants.h" -extern opal_memory_base_component_2_0_0_t mca_memory_ptmalloc2_component; +#include "opal/mca/memory/linux/memory_linux.h" #ifndef DEFAULT_CHECK_ACTION #define DEFAULT_CHECK_ACTION 1 @@ -671,26 +676,26 @@ public_sET_STATe(Void_t* msptr) So we can basically have some hard-coded tests for things to see if we want to setup to use our internal ptmalloc2 or not. */ -static void *opal_memory_ptmalloc2_malloc_hook(size_t sz, - const __malloc_ptr_t caller) +static void *opal_memory_linux_malloc_hook(size_t sz, + const __malloc_ptr_t caller) { return public_mALLOc(sz); } -static void *opal_memory_ptmalloc2_realloc_hook(Void_t* ptr, size_t sz, - const __malloc_ptr_t caller) +static void *opal_memory_linux_realloc_hook(Void_t* ptr, size_t sz, + const __malloc_ptr_t caller) { return public_rEALLOc(ptr, sz); } -static void *opal_memory_ptmalloc2_memalign_hook(size_t alignment, size_t sz, - const __malloc_ptr_t caller) +static void *opal_memory_linux_memalign_hook(size_t alignment, size_t sz, + const __malloc_ptr_t caller) { return public_mEMALIGn(alignment, sz); } -static void opal_memory_ptmalloc2_free_hook(__malloc_ptr_t __ptr, - const __malloc_ptr_t caller) +static void opal_memory_linux_free_hook(__malloc_ptr_t __ptr, + const __malloc_ptr_t caller) { public_fREe(__ptr); } @@ -722,7 +727,7 @@ static check_result_t check(const char *name) } /* OMPI's init function */ -static void opal_memory_ptmalloc2_malloc_init_hook(void) +static void opal_memory_linux_malloc_init_hook(void) { /* Yes, checking for an MPI MCA parameter here is an abstraction violation. Cope. Yes, even checking for *any* MCA parameter @@ -742,7 +747,7 @@ static void opal_memory_ptmalloc2_malloc_init_hook(void) causing Badness (see http://bugs.debian.org/531522). $FAKEROOTKEY is set by Debian's "fakeroot" build environment; check for that explicitly. */ - r1 = check("OMPI_MCA_memory_ptmalloc2_disable"); + r1 = check("OMPI_MCA_memory_linux_disable"); r2 = check("FAKEROOTKEY"); if ((RESULT_NOT_FOUND != r1 && RESULT_NO != r1) || (RESULT_NOT_FOUND != r2 && RESULT_NO != r2)) { @@ -798,10 +803,10 @@ static void opal_memory_ptmalloc2_malloc_init_hook(void) ptmalloc_init(); /* Now set the hooks to point to our functions */ - __free_hook = opal_memory_ptmalloc2_free_hook; - __malloc_hook = opal_memory_ptmalloc2_malloc_hook; - __memalign_hook = opal_memory_ptmalloc2_memalign_hook; - __realloc_hook = opal_memory_ptmalloc2_realloc_hook; + __free_hook = opal_memory_linux_free_hook; + __malloc_hook = opal_memory_linux_malloc_hook; + __memalign_hook = opal_memory_linux_memalign_hook; + __realloc_hook = opal_memory_linux_realloc_hook; } } @@ -814,10 +819,10 @@ static void opal_memory_ptmalloc2_malloc_init_hook(void) libopen-pal). This declaration is not in malloc.h because this function only exists as a horrid workaround to force linkers to pull in this .o file (see explanation below). */ -void *opal_memory_ptmalloc2_hook_pull(void); +void opal_memory_linux_hook_pull(bool *want_hooks); /* OMPI change: add a dummy function here that will be called by the - ptmalloc2 component open() function. This dummy function is + linux component open() function. This dummy function is necessary for when OMPI is built as --disable-shared --enable-static --disable-dlopen, because we won't use -Wl,--export-dynamic when building OMPI. So we need to ensure that @@ -825,8 +830,7 @@ void *opal_memory_ptmalloc2_hook_pull(void); but they also end up in the final exectuable (so that __malloc_initialize_hook is there, overrides the weak symbol in glibc, ....etc.). */ -static int bogus = 37; -void *opal_memory_ptmalloc2_hook_pull(void) +void opal_memory_linux_hook_pull(bool *want_hooks) { int val; @@ -840,24 +844,26 @@ void *opal_memory_ptmalloc2_hook_pull(void) _malloc_init_hook(). */ mca_base_param_source_t source; char *file; - int p = mca_base_param_reg_int(&mca_memory_ptmalloc2_component.memoryc_version, + int p = mca_base_param_reg_int(&mca_memory_linux_component.super.memoryc_version, "disable", - "If this MCA parameter is set to 1 **VIA ENVIRONMENT VARIABLE ONLY*** (this MCA parameter *CANNOT* be set in a file or on the mpirun command line!), the ptmalloc2 hooks will be disabled", + "If this MCA parameter is set to 1 **VIA ENVIRONMENT VARIABLE ONLY*** (this MCA parameter *CANNOT* be set in a file or on the mpirun command line!), this component will be disabled and will not attempt to use either ummunotify or memory hook support", false, false, 0, &val); - /* We can at least warn if someone tried to set this in a file */ - if (p >= 0 && - OPAL_SUCCESS == mca_base_param_lookup_source(p, &source, &file) && - (MCA_BASE_PARAM_SOURCE_DEFAULT != source && - MCA_BASE_PARAM_SOURCE_ENV != source)) { - opal_show_help("help-opal-memory-ptmalloc2.txt", - "disable incorrectly set", true, - "opal_ptmalloc2_disable", - "opal_ptmalloc2_disable", val, - MCA_BASE_PARAM_SOURCE_FILE == source ? - file : "override"); - } - return &bogus; + /* We can at least warn if someone tried to set this in a file */ + if (p >= 0) { + if (OPAL_SUCCESS == mca_base_param_lookup_source(p, &source, &file) && + (MCA_BASE_PARAM_SOURCE_DEFAULT != source && + MCA_BASE_PARAM_SOURCE_ENV != source)) { + opal_show_help("help-opal-memory-linux.txt", + "disable incorrectly set", true, + "opal_linux_disable", + "opal_linux_disable", val, + MCA_BASE_PARAM_SOURCE_FILE == source ? + file : "override"); + } else { + *want_hooks = OPAL_INT_TO_BOOL(!val); + } + } } @@ -865,7 +871,7 @@ void *opal_memory_ptmalloc2_hook_pull(void) /* OMPI change: This is the symbol to override to make the above function get fired during malloc initialization time. */ void (*__malloc_initialize_hook) (void) = - opal_memory_ptmalloc2_malloc_init_hook; + opal_memory_linux_malloc_init_hook; /* * Local variables: diff --git a/opal/mca/memory/ptmalloc2/lran2.h b/opal/mca/memory/linux/lran2.h similarity index 100% rename from opal/mca/memory/ptmalloc2/lran2.h rename to opal/mca/memory/linux/lran2.h diff --git a/opal/mca/memory/ptmalloc2/malloc-stats.c b/opal/mca/memory/linux/malloc-stats.c similarity index 97% rename from opal/mca/memory/ptmalloc2/malloc-stats.c rename to opal/mca/memory/linux/malloc-stats.c index 7be74e1b43..cfb9fb23df 100644 --- a/opal/mca/memory/ptmalloc2/malloc-stats.c +++ b/opal/mca/memory/linux/malloc-stats.c @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. + * + * Additional copyrights may follow. + */ /* Malloc implementation for multiple threads; statistics printing. Copyright (C) 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -21,7 +26,7 @@ /* $Id: $ */ /* OMPI change: Name-shift all the internal symbols */ -#include "opal/mca/memory/ptmalloc2/rename.h" +#include "opal/mca/memory/linux/rename.h" #include /* needed for malloc_stats */ diff --git a/opal/mca/memory/ptmalloc2/malloc.c b/opal/mca/memory/linux/malloc.c similarity index 98% rename from opal/mca/memory/ptmalloc2/malloc.c rename to opal/mca/memory/linux/malloc.c index ff327ecb45..3b77c7034d 100644 --- a/opal/mca/memory/ptmalloc2/malloc.c +++ b/opal/mca/memory/linux/malloc.c @@ -1,7 +1,9 @@ /********************** BEGIN OMPI CHANGES *****************************/ -/* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. +/* + * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. + * + * Additional copyrights may follow. */ - #define OPAL_DISABLE_ENABLE_MEM_DEBUG 1 #include "opal_config.h" @@ -10,8 +12,9 @@ #include "opal/sys/atomic.h" #include "opal/memoryhooks/memory_internal.h" +#include "opal/mca/memory/linux/memory_linux.h" /* Name-shift all the internal symbols */ -#include "opal/mca/memory/ptmalloc2/rename.h" +#include "opal/mca/memory/linux/rename.h" /* * Not all systems have sbrk() declared, since it's technically not a @@ -22,25 +25,22 @@ void *sbrk(); #endif -static void* -opal_mem_free_ptmalloc2_sbrk(int inc) +static void *opal_memory_linux_free_ptmalloc2_sbrk(int inc) { - if (inc < 0) { - long oldp = (long) sbrk(0); - opal_mem_hooks_release_hook((void*) (oldp + inc), -inc, 1); - } + if (inc < 0) { + long oldp = (long) sbrk(0); + opal_mem_hooks_release_hook((void*) (oldp + inc), -inc, 1); + } - return sbrk(inc); + return sbrk(inc); } -extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int run_hooks); - /* if we are trying to catch only allocations from and releases to the operating system, intercept sbrk, mmap, and munmap. If we want to intercept every call to malloc/realloc/free/etc., don't do this, as we need to add something into each of those calls anyway. */ -#define MORECORE opal_mem_free_ptmalloc2_sbrk -#define munmap(a,b) opal_mem_free_ptmalloc2_munmap(a,b,1,1) +#define MORECORE opal_memory_linux_free_ptmalloc2_sbrk +#define munmap(a,b) opal_memory_linux_free_ptmalloc2_munmap(a,b,1) /* make some non-GCC compilers happy */ #ifndef __GNUC__ @@ -3419,15 +3419,12 @@ public_mALLOc(size_t bytes) #endif /* OMPI change: put in a flag so that we can know that this function - was invoked. This flag is checked in the memory/ptmalloc2 - component init to ensure that this ptmalloc is actually being - used. Used a simple "extern" here to get the flag symbol rather - than putting it in a new .h file that would only contain a small - number of symbols. */ - { - extern bool opal_memory_ptmalloc2_malloc_invoked; - opal_memory_ptmalloc2_malloc_invoked = true; - } + was invoked. This flag is checked in the memory/linux component + init to ensure that this ptmalloc is actually being used. Used a + simple "extern" here to get the flag symbol rather than putting + it in a new .h file that would only contain a small number of + symbols. */ + mca_memory_linux_component.malloc_invoked = true; arena_get(ar_ptr, bytes); if(!ar_ptr) @@ -3479,15 +3476,12 @@ public_fREe(Void_t* mem) #endif /* OMPI change: put in a flag so that we can know that this function - was invoked. This flag is checked in the memory/ptmalloc2 - component init to ensure that this ptmalloc is actually being - used. Used a simple "extern" here to get the flag symbol rather - than putting it in a new .h file that would only contain a small - number of symbols. */ - { - extern bool opal_memory_ptmalloc2_free_invoked; - opal_memory_ptmalloc2_free_invoked = true; - } + was invoked. This flag is checked in the memory/linux component + init to ensure that this ptmalloc is actually being used. Used a + simple "extern" here to get the flag symbol rather than putting + it in a new .h file that would only contain a small number of + symbols. */ + mca_memory_linux_component.free_invoked = true; if (mem == 0) /* free(0) has no effect */ return; @@ -3541,15 +3535,12 @@ public_rEALLOc(Void_t* oldmem, size_t bytes) #endif /* OMPI change: put in a flag so that we can know that this function - was invoked. This flag is checked in the memory/ptmalloc2 - component init to ensure that this ptmalloc is actually being - used. Used a simple "extern" here to get the flag symbol rather - than putting it in a new .h file that would only contain a small - number of symbols. */ - { - extern bool opal_memory_ptmalloc2_realloc_invoked; - opal_memory_ptmalloc2_realloc_invoked = true; - } + was invoked. This flag is checked in the memory/linux component + init to ensure that this ptmalloc is actually being used. Used a + simple "extern" here to get the flag symbol rather than putting + it in a new .h file that would only contain a small number of + symbols. */ + mca_memory_linux_component.realloc_invoked = true; #if REALLOC_ZERO_BYTES_FREES if (bytes == 0 && oldmem != NULL) { public_fREe(oldmem); return 0; } @@ -3631,15 +3622,12 @@ public_mEMALIGn(size_t alignment, size_t bytes) #endif /* OMPI change: put in a flag so that we can know that this function - was invoked. This flag is checked in the memory/ptmalloc2 - component init to ensure that this ptmalloc is actually being - used. Used a simple "extern" here to get the flag symbol rather - than putting it in a new .h file that would only contain a small - number of symbols. */ - { - extern bool opal_memory_ptmalloc2_memalign_invoked; - opal_memory_ptmalloc2_memalign_invoked = true; - } + was invoked. This flag is checked in the memory/linux component + init to ensure that this ptmalloc is actually being used. Used a + simple "extern" here to get the flag symbol rather than putting + it in a new .h file that would only contain a small number of + symbols. */ + mca_memory_linux_component.memalign_invoked = true; /* If need less alignment than we give anyway, just relay to malloc */ if (alignment <= MALLOC_ALIGNMENT) return public_mALLOc(bytes); diff --git a/opal/mca/memory/ptmalloc2/malloc.h b/opal/mca/memory/linux/malloc.h similarity index 100% rename from opal/mca/memory/ptmalloc2/malloc.h rename to opal/mca/memory/linux/malloc.h diff --git a/opal/mca/memory/linux/memory_linux.h b/opal/mca/memory/linux/memory_linux.h new file mode 100644 index 0000000000..8860d7e270 --- /dev/null +++ b/opal/mca/memory/linux/memory_linux.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MEMORY_LINUX_H +#define OPAL_MEMORY_LINUX_H + +#include "opal_config.h" + +#include "opal/mca/memory/memory.h" + +BEGIN_C_DECLS + +/* Component structure */ + +typedef struct opal_memory_linux_component_t { + opal_memory_base_component_2_0_0_t super; + + /* Component data */ + int verbose_level; + int enable_ummunotify; + int enable_ptmalloc2; + +#if MEMORY_LINUX_UMMUNOTIFY + /* Ummunotify-specific data */ + int ummunotify_fd; +#endif + +#if MEMORY_LINUX_PTMALLOC2 + /* Ptmalloc2-specific data */ + bool free_invoked; + bool malloc_invoked; + bool realloc_invoked; + bool memalign_invoked; + bool munmap_invoked; +#endif +} opal_memory_linux_component_t; + +/* memory_linux_component.c */ + +extern opal_memory_linux_component_t mca_memory_linux_component; + + +#if MEMORY_LINUX_UMMUNOTIFY +/* memory_linux_ummunotify.c */ +int opal_memory_linux_ummunotify_open(void); +int opal_memory_linux_ummunotify_close(void); +#endif /* MEMORY_LINUX_UMMUNOTIFY */ + +#if MEMORY_LINUX_PTMALLOC2 +/* memory_linux_ptmalloc2.c */ +int opal_memory_linux_ptmalloc2_open(void); +int opal_memory_linux_ptmalloc2_close(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 */ + +END_C_DECLS + +#endif diff --git a/opal/mca/memory/linux/memory_linux_component.c b/opal/mca/memory/linux/memory_linux_component.c new file mode 100644 index 0000000000..1bbbcaba47 --- /dev/null +++ b/opal/mca/memory/linux/memory_linux_component.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* This component basically fronts two different memory management + schemes: the Linux "ummunotify" kernel module and hooking in a + substitute ptmalloc2 allocator. Both of these mechanisms are + unified under a single component because the "memory" framework + both only allows one component to be selected, and that one + component must be compile-time linked into libopen-pal. Hence, if + we want to try to use either one of these mechanisms, we have to + have them both in a single component. + + When using ptmalloc2, the goal of this component is to wholly + replace the underlying allocator with our internal ptmalloc2 + allocator. See the file README-open-mpi.txt for details of how it + works. + + When using ummunotify, we can probe to find out when the MMU map + has been changed (i.e., memory has been released back to the OS). */ + +#include "opal_config.h" + +#include "opal/constants.h" +#include "opal/mca/base/mca_base_param.h" +#include "opal/mca/memory/memory.h" +#include "opal/mca/memory/base/empty.h" +#include "opal/memoryhooks/memory.h" + +#include "opal/mca/memory/linux/memory_linux.h" +#undef opal_memory_changed +#include "opal/mca/memory/linux/public.h" + +static int linux_open(void); +static int linux_close(void); +static int linux_register(void); + +#if MEMORY_LINUX_UMMUNOTIFY +static bool ummunotify_opened = false; +#endif +#if MEMORY_LINUX_PTMALLOC2 +static bool ptmalloc2_opened = false; +#endif + + +opal_memory_linux_component_t mca_memory_linux_component = { + /* First, the opal_memory_base_component_2_0_0_t */ + { + /* First, the mca_component_t struct containing meta + information about the component itself */ + { + OPAL_MEMORY_BASE_VERSION_2_0_0, + + /* Component name and version */ + "linux", + OPAL_MAJOR_VERSION, + OPAL_MINOR_VERSION, + OPAL_RELEASE_VERSION, + + /* Component open and close functions */ + linux_open, + linux_close, + NULL, + linux_register, + }, + { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + }, + + /* Memory framework functions. These function pointer values + are replaced by memory_linux_ummunotify.c at run time if we + end up using ummunotify support. */ + NULL, + opal_memory_base_component_register_empty, + opal_memory_base_component_deregister_empty + }, + + /* Component-specific data, filled in later (compiler will 0/NULL + it out) */ +}; + + +/* + * Register MCA params + */ +static int linux_register(void) +{ + /* Information only */ + mca_base_param_reg_int(&mca_memory_linux_component.super.memoryc_version, + "ptmalloc2_available", + "Whether ptmalloc2 support is included in Open MPI or not (1 = yes, 0 = no)", + false, true, MEMORY_LINUX_PTMALLOC2, NULL); + mca_base_param_reg_int(&mca_memory_linux_component.super.memoryc_version, + "ummunotify_available", + "Whether ummunotify support is included in Open MPI or not (1 = yes, 0 = no)", + false, true, MEMORY_LINUX_UMMUNOTIFY, NULL); + + /* Allow user to manually enable/disable */ + mca_base_param_reg_int(&mca_memory_linux_component.super.memoryc_version, + "ptmalloc2_enable", + "Whether to enable ptmalloc2 support or not (negative = try to enable, but continue even if support is not available, 0 = do not enable support, positive = try to enable and fail if support is not available)", + false, false, -1, + &mca_memory_linux_component.enable_ptmalloc2); + mca_base_param_reg_int(&mca_memory_linux_component.super.memoryc_version, + "ummunotify_enable", + "Whether to enable ummunotify support or not (negative = try to enable, but continue even if support is not available, 0 = do not enable support, positive = try to enable and fail if support is not available)", + false, false, -1, + &mca_memory_linux_component.enable_ummunotify); + + return OPAL_SUCCESS; +} + + +static int linux_open(void) +{ + int i, v; + + i = mca_base_param_find("memory", NULL, "base_verbose"); + mca_base_param_lookup_int(i, &v); + mca_memory_linux_component.verbose_level = v; + + /* Try initializing ummunotify first; if that fails, try + ptmalloc2. */ +#if MEMORY_LINUX_UMMUNOTIFY + if (mca_memory_linux_component.enable_ummunotify) { + if (v >= 10) { + opal_output(0, "memory:linux: attempting to initialize ummunotify support"); + } + if (OPAL_SUCCESS == opal_memory_linux_ummunotify_open()) { + ummunotify_opened = true; + if (v >= 10) { + opal_output(0, "memory:linux: ummunotify successfully initialized; we'll use that"); + } + return OPAL_SUCCESS; + } + if (v >= 10) { + opal_output(0, "memory:linux: ummunotify failed to initialize"); + } + } +#endif + +#if MEMORY_LINUX_PTMALLOC2 + if (mca_memory_linux_component.enable_ptmalloc2) { + if (v >= 10) { + opal_output(0, "memory:linux: attempting to initialize ptmalloc2 support"); + } + if (OPAL_SUCCESS == opal_memory_linux_ptmalloc2_open()) { + ptmalloc2_opened = true; + if (v >= 10) { + opal_output(0, "memory:linux: ptmalloc2 successfully initialized; we'll use that"); + } + return OPAL_SUCCESS; + } + if (v >= 10) { + opal_output(0, "memory:linux: ummunotify failed to initialize"); + } + } +#endif + + /* We can return OPAL_ERR_NOT_AVAILABLE if nothing is + available; that will make the MCA base silently disregard this + component. */ + + if (v >= 10) { + opal_output(0, "memory:linux: no memory hooks available in this process"); + } + return OPAL_ERR_NOT_AVAILABLE; +} + +static int linux_close(void) +{ + int v = mca_memory_linux_component.verbose_level; + +#if MEMORY_LINUX_UMMUNOTIFY + if (ummunotify_opened) { + if (v >= 10) { + opal_output(0, "memory:linux: shutting down ummunotify support"); + } + opal_memory_linux_ummunotify_close(); + ummunotify_opened = false; + } +#endif +#if MEMORY_LINUX_PTMALLOC2 + if (ptmalloc2_opened) { + if (v >= 10) { + opal_output(0, "memory:linux: shutting down ptmalloc2 support"); + } + opal_memory_linux_ptmalloc2_close(); + ptmalloc2_opened = false; + } +#endif + + return OPAL_SUCCESS; +} diff --git a/opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.c b/opal/mca/memory/linux/memory_linux_munmap.c similarity index 63% rename from opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.c rename to opal/mca/memory/linux/memory_linux_munmap.c index 67f46b3c38..118cce6010 100644 --- a/opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.c +++ b/opal/mca/memory/linux/memory_linux_munmap.c @@ -37,7 +37,7 @@ #include "opal/memoryhooks/memory_internal.h" -#include "opal_ptmalloc2_munmap.h" +#include "memory_linux.h" /* * munmap is always intercepted @@ -48,10 +48,9 @@ int __munmap(void* addr, size_t len); /* intercept munmap, as the user can give back memory that way as well. */ -OPAL_DECLSPEC int -munmap(void* addr, size_t len) +OPAL_DECLSPEC int munmap(void* addr, size_t len) { - return opal_mem_free_ptmalloc2_munmap(addr, len, 0, 1); + return opal_memory_linux_free_ptmalloc2_munmap(addr, len, 0); } @@ -59,44 +58,34 @@ munmap(void* addr, size_t len) that we can intercept both munmap and __munmap. If that isn't possible, try calling __munmap from munmap and let __munmap go. If that doesn't work, try dlsym */ -int -opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, - int call_hooks) +int opal_memory_linux_free_ptmalloc2_munmap(void *start, size_t length, + int from_alloc) { - { - extern bool opal_memory_ptmalloc2_munmap_invoked; - opal_memory_ptmalloc2_munmap_invoked = true; - } +#if !defined(HAVE___MUNMAP) && \ + !(defined(HAVE_SYSCALL) && defined(__NR_munmap)) && defined(HAVE_DLSYM) + static int (*realmunmap)(void*, size_t); +#endif - if (call_hooks) { - opal_mem_hooks_release_hook(start, length, from_alloc); - } + mca_memory_linux_component.munmap_invoked = true; + + opal_mem_hooks_release_hook(start, length, from_alloc); #if defined(HAVE___MUNMAP) return __munmap(start, length); #elif defined(HAVE_SYSCALL) && defined(__NR_munmap) return syscall(__NR_munmap, start, length); #elif defined(HAVE_DLSYM) - { - /* Must use a typedef here because we need volatile to be an - attribute of the variable, not the function (which would be - meaningless, anyway). */ - typedef int (*munmap_fn_t)(void*, size_t); - static volatile munmap_fn_t realmunmap = NULL; + if (NULL == realmunmap) { + union { + int (*munmap_fp)(void*, size_t); + void *munmap_p; + } tmp; - if (NULL == realmunmap) { - union { - int (*munmap_fp)(void*, size_t); - void *munmap_p; - } tmp; - - tmp.munmap_p = dlsym(RTLD_NEXT, "munmap"); - realmunmap = tmp.munmap_fp; - ++count; - } - - return realmunmap(start, length); + tmp.munmap_p = dlsym(RTLD_NEXT, "munmap"); + realmunmap = tmp.munmap_fp; } + + return realmunmap(start, length); #else #error "Can not determine how to call munmap" #endif diff --git a/opal/mca/memory/linux/memory_linux_ptmalloc2.c b/opal/mca/memory/linux/memory_linux_ptmalloc2.c new file mode 100644 index 0000000000..3350e056f6 --- /dev/null +++ b/opal/mca/memory/linux/memory_linux_ptmalloc2.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include +#include +#include + +#include "opal/constants.h" +#include "opal/util/output.h" +#include "opal/memoryhooks/memory.h" +#include "opal/memoryhooks/memory_internal.h" + +#include "opal/mca/memory/linux/memory_linux.h" + + +/* Need to call a function in hooks.c to ensure that all those symbols + get pulled in at link time (e.g., when building libmpi.a, so that + those symbols end up in the final executable -- especially if we + use --disable-dlopen and therefore -Wl,--export-dynamic isn't used + when we build OMPI). */ +extern void opal_memory_linux_hook_pull(bool *want_hooks); + + +/* + * Try to initialize ptmalloc2 + */ +int opal_memory_linux_ptmalloc2_open(void) +{ + int val = 0; + void *p; + bool want_hooks = true; + + /* Call a [somewhat] dummy function in hooks.c. ***Do not remove + this call!*** See comment at the beginning of this file + explaining why it is here. It will also check to see if an + environment variable has been set to disable this component + (note that OPAL_ERR_NOT_AVAILABLE is a special return value + that will silently fail the open component call; all others + will issue an error). */ + opal_memory_linux_hook_pull(&want_hooks); + if (!want_hooks) { + return OPAL_ERR_NOT_AVAILABLE; + } + + /* We will also provide malloc/free support if we've been + activated. We don't exclusively rely on the + __malloc_initialize_hook() previously being called because it's + possible that our hook was called, but then someone else reset + the hooks to point to something else (i.e., before MPI_INIT). + So explicitly test here if our hooks are still in place. If + they are, then enable FREE|CHUNK_SUPPORT. If not, then don't + enable that support -- just leave it at MUNMAP_SUPPORT. + + (Look in hooks.c for the __malloc_initialize_hook setup) */ + + /* Do a simple set of tests to see if our hooks are still the ones + installed. Explicitly reset the flags indicating that our + functions were invoked */ + p = malloc(1024 * 1024 * 4); + if (NULL == p) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + p = realloc(p, 1024 * 1024 * 4 + 32); + if (NULL == p) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + free(p); + p = memalign(4, 1024 * 1024); + if (NULL == p) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + free(p); + +#if HAVE_POSIX_MEMALIGN + /* Double check for posix_memalign, too */ + if (mca_memory_linux_component.memalign_invoked) { + mca_memory_linux_component.memalign_invoked = false; + if (0 != posix_memalign(&p, sizeof(void*), 1024 * 1024)) { + return OPAL_ERR_IN_ERRNO; + } + free(p); + } +#endif + + if (mca_memory_linux_component.malloc_invoked && + mca_memory_linux_component.realloc_invoked && + mca_memory_linux_component.memalign_invoked && + mca_memory_linux_component.free_invoked) { + /* Happiness; our functions were invoked */ + val |= OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_CHUNK_SUPPORT; + } + + /* Check if our mmap layering is working */ + p = mmap(NULL, 4096, PROT_READ, (MAP_ANONYMOUS | MAP_PRIVATE), -1, 0); + if (MAP_FAILED == p) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + munmap(p, 4096); + if (mca_memory_linux_component.munmap_invoked) { + val |= OPAL_MEMORY_MUNMAP_SUPPORT; + } + + /* All done */ + if (val > 0) { + opal_mem_hooks_set_support(val); + return OPAL_SUCCESS; + } + return OPAL_ERR_NOT_AVAILABLE; +} + + +int opal_memory_linux_ptmalloc2_close(void) +{ + /* Nothing to do, really. This function exists just for + symmetry. */ + + return OPAL_SUCCESS; +} diff --git a/opal/mca/memory/linux/memory_linux_ummunotify.c b/opal/mca/memory/linux/memory_linux_ummunotify.c new file mode 100644 index 0000000000..9f391222ec --- /dev/null +++ b/opal/mca/memory/linux/memory_linux_ummunotify.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_STROPTS_H +#include +#endif +#include +#include + +#include + +#include "opal_stdint.h" +#include "opal/constants.h" +#include "opal/util/output.h" +#include "opal/util/show_help.h" +#include "opal/mca/memory/memory.h" +#include "opal/memoryhooks/memory.h" +#include "opal/memoryhooks/memory_internal.h" + +#include "opal/mca/memory/linux/memory_linux.h" +#include "opal/mca/memory/linux/public.h" + +#define DEV_UMMUNOTIFY "/dev/ummunotify" + + +/* + * Local functions + */ +static int ummunotify_process(void); +static int ummunotify_register(void *start, size_t len, uint64_t cookie); +static int ummunotify_deregister(void *start, size_t len, uint64_t cookie); + + +/* + * Local variables + */ +static bool initialized = false; + + +/* + * Global variables (these need to be global variables rather than in + * the component struct because they are accessed in the + * opal_memory_changed() macro defined in public.h, and we don't want + * to have to include the component structure definition in public.h). + */ +uint64_t opal_memory_linux_ummunotify_counter_last_value = 0; +volatile uint64_t *opal_memory_linux_ummunotify_counter = + &opal_memory_linux_ummunotify_counter_last_value; + + +int opal_memory_linux_ummunotify_open(void) +{ + uint64_t *p; + + /* Just to be safe... */ + opal_memory_linux_ummunotify_counter_last_value = 0; + opal_memory_linux_ummunotify_counter = + &opal_memory_linux_ummunotify_counter_last_value; + + /* Open the device. Try to give a meaningful error message if + we're unable to open it. */ + mca_memory_linux_component.ummunotify_fd = + open(DEV_UMMUNOTIFY, O_RDONLY | O_NONBLOCK); + if (mca_memory_linux_component.ummunotify_fd < 0) { + char hostname[HOST_NAME_MAX]; + gethostname(hostname, sizeof(hostname)); + + if (EACCES == errno) { + /* This will get a proper show_help when merged into the + linux component */ + opal_show_help("help-opal-memory-linux.txt", + "ummunotify eaccess", true, + hostname, DEV_UMMUNOTIFY); + } else if (ENOENT != errno) { + /* Don't print an error if DEV_UMMUNOTIFY simply doesn't exist */ + opal_show_help("help-opal-memory-linux.txt", + "ummunotify open error", true, + hostname, DEV_UMMUNOTIFY, + strerror(errno), errno); + } + return OPAL_ERR_NOT_SUPPORTED; + } + + p = mmap(NULL, sizeof(*opal_memory_linux_ummunotify_counter), + PROT_READ, MAP_SHARED, + mca_memory_linux_component.ummunotify_fd, 0); + if (MAP_FAILED == opal_memory_linux_ummunotify_counter) { + close(mca_memory_linux_component.ummunotify_fd); + mca_memory_linux_component.ummunotify_fd = -1; + return OPAL_ERR_NOT_SUPPORTED; + } + opal_memory_linux_ummunotify_counter = p; + + /* If everything went well, tell OMPI that we have full support + for the memory hooks and fill in the component function + pointers */ + opal_mem_hooks_set_support(OPAL_MEMORY_FREE_SUPPORT | + OPAL_MEMORY_CHUNK_SUPPORT | + OPAL_MEMORY_MUNMAP_SUPPORT); + mca_memory_linux_component.super.memoryc_process = ummunotify_process; + mca_memory_linux_component.super.memoryc_register = ummunotify_register; + mca_memory_linux_component.super.memoryc_deregister = ummunotify_deregister; + initialized = true; + + return OPAL_SUCCESS; +} + + +/* + * Called during opal_finalize (usually during MPI_FINALIZE) to tear + * down anything that can/should be torn down to disable this + * component. The application may continue for a while after + * MPI_FINALIZE, so we should do as much as possible to disable + * anything we enabled during ummunotify_open(). + */ +int opal_memory_linux_ummunotify_close(void) +{ + if (initialized && mca_memory_linux_component.ummunotify_fd >= 0) { + munmap((void*) opal_memory_linux_ummunotify_counter, + sizeof(*opal_memory_linux_ummunotify_counter)); + close(mca_memory_linux_component.ummunotify_fd); + mca_memory_linux_component.ummunotify_fd = -1; + opal_memory_linux_ummunotify_counter = + &opal_memory_linux_ummunotify_counter_last_value; + initialized = false; + } + + return OPAL_SUCCESS; +} + +/* + * Called when opal_memory_changed() returns 1 + */ +static int ummunotify_process(void) +{ + int n; + unsigned int i; + struct ummunotify_event events[128]; + + /* Loop reading from the ummunot fd until there's nothing left to + read. If we get a LAST event, re-record the counter. */ + while (initialized) { + n = read(mca_memory_linux_component.ummunotify_fd, + &events, sizeof(events)); + if (n <= 0) { + return (EAGAIN == errno) ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; + } + + for (i = 0; i < n / sizeof(events[0]); ++i) { + switch (events[i].type) { + case UMMUNOTIFY_EVENT_TYPE_INVAL: + /* 0 => this callback did not come from malloc */ + OPAL_OUTPUT((-1, "ummunot: invalidate start %p, end %p", + (void*) events[i].hint_start, + (void*) events[i].hint_end)); + opal_mem_hooks_release_hook((void *) (uintptr_t) events[i].hint_start, + events[i].hint_end - events[i].hint_start, + 0); + break; + + case UMMUNOTIFY_EVENT_TYPE_LAST: + opal_memory_linux_ummunotify_counter_last_value = + events[i].user_cookie_counter; + /* Are there more events to read? */ + if (opal_memory_linux_ummunotify_counter_last_value == + *opal_memory_linux_ummunotify_counter) { + OPAL_OUTPUT((-1, "ummunot: LAST; done")); + return OPAL_SUCCESS; + } + OPAL_OUTPUT((-1, "ummunot: LAST; but looping around")); + break; + } + } + } + + /* Will only get here if this component has not been + initialized */ + return OPAL_SUCCESS; +} + +static int ummunotify_register(void *start, size_t len, uint64_t cookie) +{ + struct ummunotify_register_ioctl r; + r.reserved = 0; + r.start = (unsigned long) start; + r.end = (unsigned long) start + len; + r.user_cookie = cookie; + + OPAL_OUTPUT((-1, "ummunot: register %p - %p", + start, ((char*) start) + len)); + if (initialized && ioctl(mca_memory_linux_component.ummunotify_fd, + UMMUNOTIFY_REGISTER_REGION, &r)) { + OPAL_OUTPUT((-1, "Error in ioctl register!")); + return OPAL_ERR_IN_ERRNO; + } + + return OPAL_SUCCESS; +} + +static int ummunotify_deregister(void *start, size_t len, uint64_t cookie) +{ + OPAL_OUTPUT((-1, "ummunot: deregister %p - %p", + start, ((char*) start) + len)); + if (initialized && ioctl(mca_memory_linux_component.ummunotify_fd, + UMMUNOTIFY_UNREGISTER_REGION, &cookie)) { + OPAL_OUTPUT((-1, "Error in ioctl unregister!")); + return OPAL_ERR_IN_ERRNO; + } + + return OPAL_SUCCESS; +} diff --git a/opal/mca/memory/linux/public.h b/opal/mca/memory/linux/public.h new file mode 100644 index 0000000000..4248a853b6 --- /dev/null +++ b/opal/mca/memory/linux/public.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MEMORY_LINUX_PUBLIC_H +#define OPAL_MEMORY_LINUX_PUBLIC_H + +#include "opal_config.h" + +#include + +OPAL_DECLSPEC extern volatile uint64_t *opal_memory_linux_ummunotify_counter; +OPAL_DECLSPEC extern uint64_t opal_memory_linux_ummunotify_counter_last_value; + +#define opal_memory_changed() \ + (opal_memory_linux_ummunotify_counter_last_value != \ + *opal_memory_linux_ummunotify_counter) + +#endif diff --git a/opal/mca/memory/ptmalloc2/rename.h b/opal/mca/memory/linux/rename.h similarity index 100% rename from opal/mca/memory/ptmalloc2/rename.h rename to opal/mca/memory/linux/rename.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/generic/atomic.h b/opal/mca/memory/linux/sysdeps/generic/atomic.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/generic/atomic.h rename to opal/mca/memory/linux/sysdeps/generic/atomic.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/generic/malloc-machine.h b/opal/mca/memory/linux/sysdeps/generic/malloc-machine.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/generic/malloc-machine.h rename to opal/mca/memory/linux/sysdeps/generic/malloc-machine.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/generic/thread-st.h b/opal/mca/memory/linux/sysdeps/generic/thread-st.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/generic/thread-st.h rename to opal/mca/memory/linux/sysdeps/generic/thread-st.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/pthread/malloc-machine.h b/opal/mca/memory/linux/sysdeps/pthread/malloc-machine.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/pthread/malloc-machine.h rename to opal/mca/memory/linux/sysdeps/pthread/malloc-machine.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/pthread/thread-st.h b/opal/mca/memory/linux/sysdeps/pthread/thread-st.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/pthread/thread-st.h rename to opal/mca/memory/linux/sysdeps/pthread/thread-st.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/solaris/malloc-machine.h b/opal/mca/memory/linux/sysdeps/solaris/malloc-machine.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/solaris/malloc-machine.h rename to opal/mca/memory/linux/sysdeps/solaris/malloc-machine.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/solaris/thread-st.h b/opal/mca/memory/linux/sysdeps/solaris/thread-st.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/solaris/thread-st.h rename to opal/mca/memory/linux/sysdeps/solaris/thread-st.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/sproc/malloc-machine.h b/opal/mca/memory/linux/sysdeps/sproc/malloc-machine.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/sproc/malloc-machine.h rename to opal/mca/memory/linux/sysdeps/sproc/malloc-machine.h diff --git a/opal/mca/memory/ptmalloc2/sysdeps/sproc/thread-st.h b/opal/mca/memory/linux/sysdeps/sproc/thread-st.h similarity index 100% rename from opal/mca/memory/ptmalloc2/sysdeps/sproc/thread-st.h rename to opal/mca/memory/linux/sysdeps/sproc/thread-st.h diff --git a/opal/mca/memory/ptmalloc2/t-test.h b/opal/mca/memory/linux/t-test.h similarity index 100% rename from opal/mca/memory/ptmalloc2/t-test.h rename to opal/mca/memory/linux/t-test.h diff --git a/opal/mca/memory/ptmalloc2/t-test1.c b/opal/mca/memory/linux/t-test1.c similarity index 100% rename from opal/mca/memory/ptmalloc2/t-test1.c rename to opal/mca/memory/linux/t-test1.c diff --git a/opal/mca/memory/ptmalloc2/t-test2.c b/opal/mca/memory/linux/t-test2.c similarity index 100% rename from opal/mca/memory/ptmalloc2/t-test2.c rename to opal/mca/memory/linux/t-test2.c diff --git a/opal/mca/memory/ptmalloc2/tst-mallocstate.c b/opal/mca/memory/linux/tst-mallocstate.c similarity index 100% rename from opal/mca/memory/ptmalloc2/tst-mallocstate.c rename to opal/mca/memory/linux/tst-mallocstate.c diff --git a/opal/mca/memory/ptmalloc2/tst-mstats.c b/opal/mca/memory/linux/tst-mstats.c similarity index 100% rename from opal/mca/memory/ptmalloc2/tst-mstats.c rename to opal/mca/memory/linux/tst-mstats.c 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 7e9f547f7b..092d67eb48 100644 --- a/opal/mca/memory/malloc_solaris/memory_malloc_solaris_component.c +++ b/opal/mca/memory/malloc_solaris/memory_malloc_solaris_component.c @@ -10,6 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007-2008 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -19,6 +20,7 @@ #include "opal_config.h" #include "opal/mca/memory/memory.h" +#include "opal/mca/memory/base/empty.h" #include "opal/memoryhooks/memory_internal.h" #include "opal/constants.h" @@ -60,6 +62,12 @@ const opal_memory_base_component_2_0_0_t mca_memory_malloc_solaris_component = { /* The component is checkpoint ready */ MCA_BASE_METADATA_PARAM_CHECKPOINT }, + + /* This component doesn't need these functions, but need to + provide safe/empty register/deregister functions to call */ + NULL, + opal_memory_base_component_register_empty, + opal_memory_base_component_deregister_empty, }; /* diff --git a/opal/mca/memory/memory.h b/opal/mca/memory/memory.h index e43abc6292..89989506d1 100644 --- a/opal/mca/memory/memory.h +++ b/opal/mca/memory/memory.h @@ -9,6 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -16,16 +17,40 @@ * $HEADER$ */ -/* NOTE: This framework is really for build system only. There is no - set of function pointers that must be called or set interface or - any of that. The only two functions that a component must call - (note: call, not implement) are defined in - opal/memoryhooks/memory_internal.h. Other than that, to each his - own.. +/* NOTE: This framework accomodates two kinds of memory hooks systems: - Components should make some attempt to provide a component struct - via the usual means, just so ompi_info has something rational to - display. + 1. Those that only require being setup once and then will + automatically call back to internal component/module functions + as required (e.g., the ptmalloc2 component). It is expected + that such components will have a NULL value for memoryc_process + and empty (base) implementations of memoryc_register and + memoryc_deregister. + + 2. Those that must be queried periodically to find out if something + has happened to the registered memory mappings (e.g., the + ummunot component). It is expected that such components will + have complete implementations for memoryc_process, + memoryc_register, and memoryc_deregister. + + There will only be one of these components compiled in to Open MPI + (it will be compiled in libopen-pal; it will never be a DSO). so + the componente will rule "yes, I can run" or "no, I cannot run". + If it elects not to run, then there is no memory manager support in + this process. + + Because there will only be one memory manager component in the + process, there is no need for a separate module structure -- + everything is in the component for simplicity. + + Note that there is an interface relevant to this framework that is + not described in this file: the opal_memory_changed() macro. This + macro should return 1 if an asynchronous agent has noticed that + memory mappings have changed. The macro should be as cheap/fast as + possible (which is why it's a macro). If it returns 1, the + memoryc_process() function pointer (below), will be invoked. If + the component does not provide this macro, then a default macro is + used that always returns 0 and therefore memoryc_process() will + never be invoked (and can legally be NULL). */ #ifndef OPAL_MCA_MEMORY_MEMORY_H @@ -36,21 +61,79 @@ #include "opal/mca/mca.h" #include "opal/mca/base/base.h" +BEGIN_C_DECLS + +/** + * Prototype for doing something once memory changes have been + * detected. This function is assumed to do whatever is necessary to + * a) figured out what has changed, and b) adjust OMPI as relevant + * (e.g., call opal_mem_hooks_release_hook). It only needs to be + * supplied for components that provide opal_memory_changed() macros + * that can return non-zero. + */ +typedef int (*opal_memory_base_component_process_fn_t)(void); + +/** + * Prototype for a function that is invoked when Open MPI starts to + * "care" about a specific memory region. That is, Open MPI declares + * that it wants to be notified if the memory mapping for this region + * changes. + * + * If a component does not want/need to provide this functionality, it + * can use the value opal_memory_base_register_empty (an empty + * implementation of this function). + */ +typedef int (*opal_memory_base_component_register_fn_t)(void *base, + size_t len, + uint64_t cookie); + + +/** + * 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 + * if the memory mapping for this region changes. + * + * The parameters of this function will exactly match parameters that + * were previously passed to the call to + * opal_memory_base_component_register_fn_t. + * + * If a component does not want/need to provide this functionality, it + * can use the value opal_memory_base_deregister_empty (an empty + * implementation of this function). + */ +typedef int (*opal_memory_base_component_deregister_fn_t)(void *base, + size_t len, + uint64_t cookie); + + /** * Structure for memory components. */ -struct opal_memory_base_component_2_0_0_t { +typedef struct opal_memory_base_component_2_0_0_t { /** MCA base component */ mca_base_component_t memoryc_version; /** MCA base data */ mca_base_component_data_t memoryc_data; -}; -/** - * Convenience typedef - */ -typedef struct opal_memory_base_component_2_0_0_t opal_memory_base_component_2_0_0_t; -extern opal_memory_base_component_2_0_0_t *opal_memory_active_component; + /** Function to call when something has changed, as indicated by + opal_memory_changed(). Will be ignored if the component does + not provide an opal_memory_changed() macro that returns + nonzero. */ + opal_memory_base_component_process_fn_t memoryc_process; + + /** Function invoked when Open MPI starts "caring" about a + specific memory region */ + opal_memory_base_component_register_fn_t memoryc_register; + /** Function invoked when Open MPI stops "caring" about a + specific memory region */ + opal_memory_base_component_deregister_fn_t memoryc_deregister; +} opal_memory_base_component_2_0_0_t; + +OPAL_DECLSPEC extern opal_memory_base_component_2_0_0_t *opal_memory; + +END_C_DECLS /* * Macro for use in components that are of type memory diff --git a/opal/mca/memory/ptmalloc2/configure.m4 b/opal/mca/memory/ptmalloc2/configure.m4 deleted file mode 100644 index dd8f4ed21e..0000000000 --- a/opal/mca/memory/ptmalloc2/configure.m4 +++ /dev/null @@ -1,133 +0,0 @@ -# -*- shell-script -*- -# -# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana -# University Research and Technology -# Corporation. All rights reserved. -# Copyright (c) 2004-2005 The University of Tennessee and The University -# of Tennessee Research Foundation. All rights -# reserved. -# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, -# University of Stuttgart. All rights reserved. -# Copyright (c) 2004-2005 The Regents of the University of California. -# All rights reserved. -# Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -AC_DEFUN([MCA_memory_ptmalloc2_COMPILE_MODE], [ - AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) - $4="static" - AC_MSG_RESULT([$$4]) -]) - - -# MCA_memory_ptmalloc2_CONFIG(action-if-can-compile, -# [action-if-cant-compile]) -# ------------------------------------------------ -AC_DEFUN([MCA_memory_ptmalloc2_CONFIG],[ - AS_IF([test "$with_memory_manager" = "ptmalloc2"], - [if test "`echo $host | grep apple-darwin`" != "" ; then - AC_MSG_WARN([*** Using ptmalloc with OS X will result in failure.]) - AC_MSG_ERROR([*** Aborting to save you the effort]) - fi - memory_ptmalloc2_happy="yes" - memory_ptmalloc2_should_use=1], - [memory_ptmalloc2_should_use=0 - AS_IF([test "$with_memory_manager" = ""], - [memory_ptmalloc2_happy="yes"], - [memory_ptmalloc2_happy="no"])]) - - - # Per ticket #227, Intel 9.0 v20051201 on ia64 with optimization - # of -O2 or higher will bork ptmalloc2 in strange in mysterious - # ways. Doh! So if the compiler vendor is intel and we're on an - # ia64 box, run "icc --version" and snarf the version string. If - # it's 9.0 and the version is <= 20051201, then disable ptmalloc2. - # Executive decision: ignore optimization levels (even though -O1 - # and -O0 seem to work). The upgrade to 9.1 is free, so that's a - # better path than trying to make a much more complicated test - # here. - - case $host in - ia64-*) - AS_IF([test "$ompi_c_vendor" = "intel"], - [# check for v9.0 <= 20051201 - icc_major_ver="`$CC --version | head -n 1 | awk '{ print [$]3 }'`" - icc_minor_ver="`$CC --version | head -n 1 | awk '{ print [$]4 }'`" - AS_IF([test "$icc_major_ver" = "9.0" -a "`expr $icc_minor_ver \<= 20051201`" = "1"], - [memory_ptmalloc2_happy="no" - AC_MSG_WARN([*** Detected Intel C compiler v9.0 <= 20051201 on ia64]) - AC_MSG_WARN([*** This compiler/platform combination has known problems with ptmalloc2]) - AC_MSG_WARN([*** Automatically disabling ptmalloc2])]) - unset icc_major_ver icc_minor_ver]) - ;; - esac - - AS_IF([test "$memory_ptmalloc2_happy" = "yes"], - [# check for malloc.h - AC_CHECK_HEADER([malloc.h], - [memory_ptmalloc2_happy="yes"], - [memory_ptmalloc2_happy="no"])]) - - AS_IF([test "$memory_ptmalloc2_happy" = "yes"], - [# check for init hook symbol - AC_CHECK_DECL([__malloc_initialize_hook], - [memory_ptmalloc2_happy="yes"], - [memory_ptmalloc2_happy="no"], - [AC_INCLUDES_DEFAULT - #include ])]) - - # - # See if we have sbrk prototyped - # - AS_IF([test "$memory_ptmalloc2_happy" = "yes"], [AC_CHECK_DECLS([sbrk])]) - - # - # Figure out how we're going to call mmap/munmap for real - # - AS_IF([test "$memory_ptmalloc2_happy" = "yes"], - [memory_ptmalloc2_mmap=0 - memory_ptmalloc2_munmap=1 - - # it's nearly impossible to call mmap from syscall(), so - # only go this route if we can't get at munmap any other - # way. - AC_CHECK_HEADER([syscall.h], - [AC_CHECK_FUNCS([syscall], [], [memory_ptmalloc2_munmap=0])]) - - # Always look for __munmap and __mmap - AC_CHECK_FUNCS([__munmap], [memory_ptmalloc2_mmap=1]) - AC_CHECK_FUNCS([__mmap]) - - # only allow dlsym (and therefore add -ldl) if we - # really need to - AS_IF([test "$memory_ptmalloc2_mmap" = "0"], - [memory_ptmalloc2_LIBS_SAVE="$LIBS" - AC_CHECK_LIB([dl], - [dlsym], - [LIBS="$LIBS -ldl" - memory_ptmalloc2_LIBS="-ldl" - memory_ptmalloc2_mmap=1]) - AC_CHECK_FUNCS([dlsym]) - LIBS="$memory_ptmalloc2_LIBS_SAVE"]) - - AS_IF([test "$memory_ptmalloc2_mmap" = "0" -a "$memory_ptmalloc2_munmap" = "0"], - [memory_ptmalloc2_happy="no"])]) - - AS_IF([test "$memory_ptmalloc2_happy" = "yes"], - [memory_ptmalloc2_WRAPPER_EXTRA_LIBS="$memory_ptmalloc2_LIBS"]) - - AS_IF([test "$memory_ptmalloc2_happy" = "no" -a \ - "$memory_malloc_hoooks_should_use" = "1"], - [AC_MSG_ERROR([ptmalloc2 memory management requested but not available. Aborting.])]) - - AC_SUBST([memory_ptmalloc2_LIBS]) - - AS_IF([test "$memory_ptmalloc2_happy" = "yes"], - [memory_base_found=1 - $1], [$2]) -]) diff --git a/opal/mca/memory/ptmalloc2/help-opal-memory-ptmalloc2.txt b/opal/mca/memory/ptmalloc2/help-opal-memory-ptmalloc2.txt deleted file mode 100644 index e7690abc76..0000000000 --- a/opal/mca/memory/ptmalloc2/help-opal-memory-ptmalloc2.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -*- text -*- -# -# Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# -# This is the US/English help file for Open MPI's ptmalloc2 component. -# -[disable incorrectly set] -WARNING: The special MCA parameter "%s" was set in -an unexpected way, and is likely not working the way you want it to. - -Specifically, this MCA parameter is "special" in that it can *only* be -set in the environment. Setting this value in a file -- and sometimes -even on the command line -- will not work as intended. The *only* way -to set this value is to set "OMPI_MCA_%s" in the environment before -starting your job. - - Value: %d - Source: %s diff --git a/opal/mca/memory/ptmalloc2/opal_ptmalloc2_component.c b/opal/mca/memory/ptmalloc2/opal_ptmalloc2_component.c deleted file mode 100644 index 07c5338cb8..0000000000 --- a/opal/mca/memory/ptmalloc2/opal_ptmalloc2_component.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2005 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -/* The goal of this component is to wholly replace the underlying - allocator with our internal ptmalloc2 allocator. - - See the file README-open-mpi.txt for details of how it works. */ - -#include "opal_config.h" - -#include -#include - -#include "opal/constants.h" -#include "opal/mca/memory/memory.h" -#include "opal/memoryhooks/memory.h" - -/* Need to call a function in hooks.c to ensure that all those symbols - get pulled in at link time (e.g., when building libmpi.a, so that - those symbols end up in the final executable -- especially if we - use --disable-dlopen and therefore -Wl,--export-dynamic isn't used - when we build OMPI). */ -extern void *opal_memory_ptmalloc2_hook_pull(void); - -static int ptmalloc2_open(void); - -const opal_memory_base_component_2_0_0_t mca_memory_ptmalloc2_component = { - /* First, the mca_component_t struct containing meta information - about the component itself */ - { - OPAL_MEMORY_BASE_VERSION_2_0_0, - - /* Component name and version */ - "ptmalloc2", - OPAL_MAJOR_VERSION, - OPAL_MINOR_VERSION, - OPAL_RELEASE_VERSION, - - /* Component open and close functions */ - ptmalloc2_open, - NULL - }, - { - /* The component is checkpoint ready */ - MCA_BASE_METADATA_PARAM_CHECKPOINT - }, -}; - -/* Public symbols */ -bool opal_memory_ptmalloc2_free_invoked = false; -bool opal_memory_ptmalloc2_malloc_invoked = false; -bool opal_memory_ptmalloc2_realloc_invoked = false; -bool opal_memory_ptmalloc2_memalign_invoked = false; -bool opal_memory_ptmalloc2_munmap_invoked = false; - -static int ptmalloc2_open(void) -{ - void *p; - int val = 0; - - /* Call a dummy function in hooks.c. ***Do not remove this - call!*** See comment at the beginning of this file explaining - why it is here. */ - p = opal_memory_ptmalloc2_hook_pull(); - - /* We will also provide malloc/free support if we've been - activated. We don't rely on the __malloc_initialize_hook() - previously being called because it's possible that our hook was - called, but then someone else reset the hooks to point to - something else (i.e., before MPI_INIT). So explicitly test - here if our hooks are still in place. If they are, then enable - FREE|CUNK_SUPPORT. If not, then don't enable that support -- - just leave it at MUNMAP_SUPPORT. - - (Look in hooks.c for the __malloc_initialize_hook setup) */ - - /* Do a simple set of tests to see if our hooks are still the ones - installed. Explicitly reset the flags indicating that our - functions were invoked */ - opal_memory_ptmalloc2_malloc_invoked = false; - opal_memory_ptmalloc2_realloc_invoked = false; - opal_memory_ptmalloc2_memalign_invoked = false; - opal_memory_ptmalloc2_free_invoked = false; - opal_memory_ptmalloc2_munmap_invoked = false; - - p = malloc(1024 * 1024 * 4); - if (NULL == p) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - p = realloc(p, 1024 * 1024 * 4 + 32); - if (NULL == p) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - free(p); - p = memalign(4, 1024 * 1024); - if (NULL == p) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - free(p); - -#if HAVE_POSIX_MEMALIGN - /* Double check for posix_memalign, too */ - if (opal_memory_ptmalloc2_memalign_invoked) { - opal_memory_ptmalloc2_memalign_invoked = false; - if (0 != posix_memalign(&p, sizeof(void*), 1024 * 1024)) { - return OPAL_ERR_IN_ERRNO; - } - free(p); - } -#endif - - if (opal_memory_ptmalloc2_malloc_invoked && - opal_memory_ptmalloc2_realloc_invoked && - opal_memory_ptmalloc2_memalign_invoked && - opal_memory_ptmalloc2_free_invoked) { - /* Happiness; our functions were invoked */ - val |= OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_CHUNK_SUPPORT; - } - - p = mmap(NULL, 4096, PROT_READ, (MAP_ANONYMOUS | MAP_PRIVATE), -1, 0); - if (MAP_FAILED == p) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - munmap(p, 4096); - - if (opal_memory_ptmalloc2_munmap_invoked) { - val |= OPAL_MEMORY_MUNMAP_SUPPORT; - } - - /* Set the support level */ - opal_mem_hooks_set_support(val); - - return OPAL_SUCCESS; -}