/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2007 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) 2006 Voltaire. All rights reserved. * Copyright (c) 2009-2013 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2009 IBM Corporation. All rights reserved. * Copyright (c) 2013 NVIDIA Corporation. All rights reserved. * Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights * reserved. * * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "opal_config.h" #include MCA_memory_IMPLEMENTATION_HEADER #include "opal/mca/memory/memory.h" #include "opal/mca/rcache/rcache.h" #include "rcache_base_vma.h" #include "rcache_base_vma_tree.h" /** * Initialize the rcache */ static void mca_rcache_base_vma_module_construct (mca_rcache_base_vma_module_t *vma_module) { OBJ_CONSTRUCT(&vma_module->vma_lock, opal_recursive_mutex_t); (void) mca_rcache_base_vma_tree_init (vma_module); } static void mca_rcache_base_vma_module_destruct (mca_rcache_base_vma_module_t *vma_module) { OBJ_DESTRUCT(&vma_module->vma_lock); mca_rcache_base_vma_tree_finalize (vma_module); } OBJ_CLASS_INSTANCE(mca_rcache_base_vma_module_t, opal_object_t, mca_rcache_base_vma_module_construct, mca_rcache_base_vma_module_destruct); mca_rcache_base_vma_module_t *mca_rcache_base_vma_module_alloc (void) { return OBJ_NEW(mca_rcache_base_vma_module_t); } int mca_rcache_base_vma_find (mca_rcache_base_vma_module_t *vma_module, void *addr, size_t size, mca_rcache_base_registration_t **reg) { int rc; unsigned char *bound_addr; if (size == 0) { return OPAL_ERROR; } bound_addr = (unsigned char *) ((intptr_t) addr + size - 1); /* 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_base_vma_tree_find (vma_module, (unsigned char *) addr, bound_addr); return OPAL_SUCCESS; } int mca_rcache_base_vma_find_all (mca_rcache_base_vma_module_t *vma_module, void *addr, size_t size, mca_rcache_base_registration_t **regs, int reg_cnt) { int rc; unsigned char *bound_addr; if(size == 0) { return OPAL_ERROR; } bound_addr = (unsigned char *) ((intptr_t) addr + size - 1); /* 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_base_vma_tree_find_all (vma_module, (unsigned char *) addr, bound_addr, regs, reg_cnt); } int mca_rcache_base_vma_insert (mca_rcache_base_vma_module_t *vma_module, mca_rcache_base_registration_t *reg, size_t limit) { size_t reg_size = reg->bound - reg->base + 1; int rc; if (limit != 0 && reg_size > limit) { /* return out of resources if request is bigger than cache size * return temp out of resources otherwise */ return OPAL_ERR_OUT_OF_RESOURCE; } /* 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_base_vma_tree_insert (vma_module, reg, limit); if (OPAL_LIKELY(OPAL_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) (uintptr_t) reg); } return rc; } int mca_rcache_base_vma_delete (mca_rcache_base_vma_module_t *vma_module, mca_rcache_base_registration_t *reg) { /* 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) (uintptr_t) reg); return mca_rcache_base_vma_tree_delete (vma_module, reg); } int mca_rcache_base_vma_iterate (mca_rcache_base_vma_module_t *vma_module, unsigned char *base, size_t size, int (*callback_fn) (struct mca_rcache_base_registration_t *, void *), void *ctx) { return mca_rcache_base_vma_tree_iterate (vma_module, base, size, callback_fn, ctx); } void mca_rcache_base_vma_dump_range (mca_rcache_base_vma_module_t *vma_module, unsigned char *base, size_t size, char *msg) { mca_rcache_base_vma_tree_dump_range (vma_module, base, size, msg); }