2005-09-12 22:28:23 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
|
|
|
* All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
|
|
|
* 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$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
|
|
|
|
|
|
|
#include "ompi_config.h"
|
|
|
|
#include <sched.h>
|
|
|
|
#include "ompi/include/constants.h"
|
|
|
|
#include "mca/pml/pml.h"
|
|
|
|
#include "mca/btl/btl.h"
|
|
|
|
#include "mca/bml/bml.h"
|
|
|
|
#include "mca/mpool/mpool.h"
|
|
|
|
#include "pml_ob1.h"
|
|
|
|
#include "pml_ob1_rdma.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to see if memory is registered or can be registered. Build a
|
|
|
|
* set of registrations on the request.
|
|
|
|
*/
|
|
|
|
|
|
|
|
size_t mca_pml_ob1_rdma_btls(
|
|
|
|
mca_bml_base_endpoint_t* bml_endpoint,
|
|
|
|
unsigned char* base,
|
|
|
|
size_t size,
|
|
|
|
mca_pml_ob1_rdma_btl_t* rdma_btls)
|
|
|
|
{
|
|
|
|
size_t num_btls = mca_bml_base_btl_array_get_size(&bml_endpoint->btl_rdma);
|
|
|
|
size_t num_btls_used = 0;
|
|
|
|
ompi_pointer_array_t regs;
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
/* shortcut when there are no rdma capable btls */
|
|
|
|
if(num_btls == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check to see if memory is registered */
|
|
|
|
OBJ_CONSTRUCT(®s, ompi_pointer_array_t);
|
|
|
|
for(n = 0; n < num_btls && num_btls_used < MCA_PML_OB1_MAX_RDMA_PER_REQUEST; n++) {
|
|
|
|
|
|
|
|
mca_bml_base_btl_t* bml_btl = mca_bml_base_btl_array_get_index(&bml_endpoint->btl_rdma, n);
|
|
|
|
mca_mpool_base_registration_t* fit = NULL;
|
|
|
|
mca_mpool_base_registration_t* largest = NULL;
|
|
|
|
mca_mpool_base_module_t* btl_mpool = bml_btl->btl_mpool;
|
|
|
|
uint32_t reg_cnt;
|
|
|
|
size_t r;
|
|
|
|
|
|
|
|
/* btl is rdma capable and registration is not required */
|
|
|
|
if(NULL == btl_mpool) {
|
|
|
|
rdma_btls[num_btls_used].bml_btl = bml_btl;
|
|
|
|
rdma_btls[num_btls_used].btl_reg = NULL;
|
|
|
|
num_btls_used++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* look through existing registrations */
|
|
|
|
btl_mpool->mpool_find(btl_mpool,
|
|
|
|
base,
|
|
|
|
size,
|
|
|
|
®s,
|
|
|
|
®_cnt);
|
|
|
|
|
|
|
|
/* shortcut for one entry - the typical case */
|
|
|
|
if(reg_cnt == 1) {
|
|
|
|
mca_mpool_base_registration_t* reg = ompi_pointer_array_get_item(®s, 0);
|
|
|
|
size_t reg_len = reg->bound - base + 1;
|
|
|
|
|
|
|
|
/* is the existing registration the required size */
|
|
|
|
if(reg->base <= base && reg_len >= size) {
|
|
|
|
|
|
|
|
rdma_btls[num_btls_used].bml_btl = bml_btl;
|
|
|
|
rdma_btls[num_btls_used].btl_reg = reg;
|
|
|
|
num_btls_used++;
|
|
|
|
|
|
|
|
/* otherwise if leave_pinned re-register */
|
|
|
|
} else if(mca_pml_ob1.leave_pinned) {
|
|
|
|
unsigned char* new_base = reg->base;
|
|
|
|
size_t new_len = (base - reg->base) + size;
|
|
|
|
btl_mpool->mpool_deregister(btl_mpool, reg);
|
|
|
|
btl_mpool->mpool_register(btl_mpool,
|
|
|
|
new_base,
|
|
|
|
new_len,
|
|
|
|
MCA_MPOOL_FLAGS_CACHE,
|
|
|
|
®);
|
|
|
|
|
|
|
|
rdma_btls[num_btls_used].bml_btl = bml_btl;
|
|
|
|
rdma_btls[num_btls_used].btl_reg = reg;
|
|
|
|
num_btls_used++;
|
|
|
|
|
|
|
|
/* existing registration cannot be used */
|
|
|
|
} else {
|
|
|
|
btl_mpool->mpool_release(btl_mpool, reg);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* find the best fit when there are multiple registrations
|
|
|
|
*/
|
|
|
|
for(r = 0; r < reg_cnt; r++) {
|
|
|
|
mca_mpool_base_registration_t* reg = ompi_pointer_array_get_item(®s, r);
|
|
|
|
size_t reg_len = reg->bound - base + 1;
|
|
|
|
if(reg->base <= base && reg_len >= size) {
|
|
|
|
fit = reg;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if(NULL == largest)
|
|
|
|
largest = reg;
|
|
|
|
else if(reg->base <= base && (reg->bound - base) > (largest->bound - base)) {
|
|
|
|
largest = reg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if the leave pinned option is set - and there is not an existing
|
|
|
|
* registration that satisfies this request, create one.
|
|
|
|
*/
|
|
|
|
if(NULL == fit && mca_pml_ob1.leave_pinned) {
|
|
|
|
if (NULL == largest) {
|
|
|
|
/* register the memory */
|
|
|
|
btl_mpool->mpool_register(
|
|
|
|
btl_mpool,
|
|
|
|
base,
|
|
|
|
size,
|
|
|
|
MCA_MPOOL_FLAGS_CACHE,
|
|
|
|
&fit);
|
|
|
|
if(NULL == fit) {
|
|
|
|
opal_output(0, "[%s:%d] unable to register memory\n", __FILE__, __LINE__);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* a registration exists but is not large enough */
|
|
|
|
} else {
|
|
|
|
unsigned char* new_base = largest->base;
|
|
|
|
size_t new_len = (base - largest->base) + size;
|
|
|
|
|
2005-09-21 15:34:45 +00:00
|
|
|
/* simplify cleanup - bump reference count as we decrement again below */
|
|
|
|
btl_mpool->mpool_retain(btl_mpool,largest);
|
|
|
|
btl_mpool->mpool_deregister(btl_mpool, largest);
|
2005-09-12 22:28:23 +00:00
|
|
|
btl_mpool->mpool_register(btl_mpool,
|
|
|
|
new_base,
|
|
|
|
new_len,
|
|
|
|
MCA_MPOOL_FLAGS_CACHE,
|
|
|
|
&fit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* decrement reference count on all unused entries */
|
|
|
|
for(r = 0; r < reg_cnt; r++) {
|
|
|
|
mca_mpool_base_registration_t* reg = ompi_pointer_array_get_item(®s, r);
|
|
|
|
if(reg != fit) {
|
|
|
|
btl_mpool->mpool_release(btl_mpool, reg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(NULL != fit) {
|
|
|
|
rdma_btls[num_btls_used].bml_btl = bml_btl;
|
|
|
|
rdma_btls[num_btls_used].btl_reg = fit;
|
|
|
|
num_btls_used++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(®s);
|
|
|
|
return num_btls_used;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For a given btl - find the best fit registration or
|
|
|
|
* optionally create one for leave pinned.
|
|
|
|
*/
|
|
|
|
|
|
|
|
mca_mpool_base_registration_t* mca_pml_ob1_rdma_registration(
|
|
|
|
mca_bml_base_btl_t* bml_btl,
|
|
|
|
unsigned char* base,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
ompi_pointer_array_t regs;
|
|
|
|
mca_mpool_base_registration_t* fit = NULL;
|
|
|
|
mca_mpool_base_registration_t* largest = NULL;
|
|
|
|
mca_mpool_base_module_t* btl_mpool = bml_btl->btl_mpool;
|
|
|
|
uint32_t reg_cnt;
|
|
|
|
size_t r;
|
|
|
|
|
|
|
|
/* btl is rdma capable and registration is not required */
|
|
|
|
if(NULL == btl_mpool) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check to see if memory is registered */
|
|
|
|
OBJ_CONSTRUCT(®s, ompi_pointer_array_t);
|
|
|
|
|
|
|
|
/* look through existing registrations */
|
|
|
|
btl_mpool->mpool_find(btl_mpool,
|
|
|
|
base,
|
|
|
|
size,
|
|
|
|
®s,
|
|
|
|
®_cnt);
|
|
|
|
|
|
|
|
for(r = 0; r < reg_cnt; r++) {
|
|
|
|
mca_mpool_base_registration_t* reg = ompi_pointer_array_get_item(®s, r);
|
|
|
|
size_t reg_len = reg->bound - base + 1;
|
|
|
|
if(reg->base <= base && reg_len >= size) {
|
|
|
|
fit = reg;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if(NULL == largest)
|
|
|
|
largest = reg;
|
|
|
|
else if(reg->base <= base && (reg->bound - base) > (largest->bound - base)) {
|
|
|
|
largest = reg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if the leave pinned option is set - and there is not an existing
|
|
|
|
* registration that satisfies this request, create one.
|
|
|
|
*/
|
|
|
|
if(NULL == fit && mca_pml_ob1.leave_pinned) {
|
|
|
|
if (NULL == largest) {
|
|
|
|
/* register the memory */
|
|
|
|
btl_mpool->mpool_register(
|
|
|
|
btl_mpool,
|
|
|
|
base,
|
|
|
|
size,
|
|
|
|
MCA_MPOOL_FLAGS_CACHE,
|
|
|
|
&fit);
|
|
|
|
|
|
|
|
/* a registration exists but is not large enough */
|
|
|
|
} else {
|
|
|
|
unsigned char* new_base = largest->base;
|
|
|
|
size_t new_len = (base - largest->base) + size;
|
|
|
|
btl_mpool->mpool_deregister(btl_mpool, largest);
|
|
|
|
btl_mpool->mpool_register(btl_mpool,
|
|
|
|
new_base,
|
|
|
|
new_len,
|
|
|
|
MCA_MPOOL_FLAGS_CACHE,
|
|
|
|
&fit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* release reference count */
|
|
|
|
for(r = 0; r < reg_cnt; r++) {
|
|
|
|
mca_mpool_base_registration_t *reg = ompi_pointer_array_get_item(®s, r);
|
|
|
|
if(reg != fit) {
|
|
|
|
btl_mpool->mpool_release(btl_mpool, reg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(®s);
|
|
|
|
return fit;
|
|
|
|
}
|
|
|
|
|