1
1

Merge pull request #2054 from ggouaillardet/topic/mca_btl_tcp_proc_insert

btl/tcp: make mca_btl_tcp_proc_insert re-entrant
Этот коммит содержится в:
Gilles Gouaillardet 2016-09-06 08:54:38 +09:00 коммит произвёл GitHub
родитель 91e1200c14 4b208e4463
Коммит 7b39d9065c

Просмотреть файл

@ -12,7 +12,7 @@
* All rights reserved. * All rights reserved.
* Copyright (c) 2008-2010 Oracle and/or its affiliates. All rights reserved * Copyright (c) 2008-2010 Oracle and/or its affiliates. All rights reserved
* Copyright (c) 2013-2015 Intel, Inc. All rights reserved * Copyright (c) 2013-2015 Intel, Inc. All rights reserved
* Copyright (c) 2014-2015 Research Organization for Information Science * Copyright (c) 2014-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved. * and Technology (RIST). All rights reserved.
* Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights * Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
* reserved. * reserved.
@ -48,17 +48,20 @@
static void mca_btl_tcp_proc_construct(mca_btl_tcp_proc_t* proc); static void mca_btl_tcp_proc_construct(mca_btl_tcp_proc_t* proc);
static void mca_btl_tcp_proc_destruct(mca_btl_tcp_proc_t* proc); static void mca_btl_tcp_proc_destruct(mca_btl_tcp_proc_t* proc);
static mca_btl_tcp_interface_t** local_interfaces = NULL; struct mca_btl_tcp_proc_data_t {
static int local_kindex_to_index[MAX_KERNEL_INTERFACE_INDEX]; mca_btl_tcp_interface_t** local_interfaces;
static size_t num_local_interfaces, max_local_interfaces; int local_kindex_to_index[MAX_KERNEL_INTERFACE_INDEX];
static mca_btl_tcp_interface_t** peer_interfaces = NULL; size_t num_local_interfaces, max_local_interfaces;
static size_t num_peer_interfaces, max_peer_interfaces; size_t num_peer_interfaces;
static int peer_kindex_to_index[MAX_KERNEL_INTERFACE_INDEX]; int peer_kindex_to_index[MAX_KERNEL_INTERFACE_INDEX];
static unsigned int *best_assignment; unsigned int *best_assignment;
static int max_assignment_weight; int max_assignment_weight;
static int max_assignment_cardinality; int max_assignment_cardinality;
static enum mca_btl_tcp_connection_quality **weights; enum mca_btl_tcp_connection_quality **weights;
static struct mca_btl_tcp_addr_t ***best_addr; struct mca_btl_tcp_addr_t ***best_addr;
};
typedef struct mca_btl_tcp_proc_data_t mca_btl_tcp_proc_data_t;
OBJ_CLASS_INSTANCE( mca_btl_tcp_proc_t, OBJ_CLASS_INSTANCE( mca_btl_tcp_proc_t,
opal_list_item_t, opal_list_item_t,
@ -198,49 +201,49 @@ mca_btl_tcp_proc_t* mca_btl_tcp_proc_create(opal_proc_t* proc)
static void evaluate_assignment(int *a) { static void evaluate_assignment(mca_btl_tcp_proc_data_t *proc_data, int *a) {
size_t i; size_t i;
unsigned int max_interfaces = num_local_interfaces; unsigned int max_interfaces = proc_data->num_local_interfaces;
int assignment_weight = 0; int assignment_weight = 0;
int assignment_cardinality = 0; int assignment_cardinality = 0;
if(max_interfaces < num_peer_interfaces) { if(max_interfaces < proc_data->num_peer_interfaces) {
max_interfaces = num_peer_interfaces; max_interfaces = proc_data->num_peer_interfaces;
} }
for(i = 0; i < max_interfaces; ++i) { for(i = 0; i < max_interfaces; ++i) {
if(0 < weights[i][a[i]-1]) { if(0 < proc_data->weights[i][a[i]-1]) {
++assignment_cardinality; ++assignment_cardinality;
assignment_weight += weights[i][a[i]-1]; assignment_weight += proc_data->weights[i][a[i]-1];
} }
} }
/* /*
* check wether current solution beats all previous solutions * check wether current solution beats all previous solutions
*/ */
if(assignment_cardinality > max_assignment_cardinality if(assignment_cardinality > proc_data->max_assignment_cardinality
|| (assignment_cardinality == max_assignment_cardinality || (assignment_cardinality == proc_data->max_assignment_cardinality
&& assignment_weight > max_assignment_weight)) { && assignment_weight > proc_data->max_assignment_weight)) {
for(i = 0; i < max_interfaces; ++i) { for(i = 0; i < max_interfaces; ++i) {
best_assignment[i] = a[i]-1; proc_data->best_assignment[i] = a[i]-1;
} }
max_assignment_weight = assignment_weight; proc_data->max_assignment_weight = assignment_weight;
max_assignment_cardinality = assignment_cardinality; proc_data->max_assignment_cardinality = assignment_cardinality;
} }
} }
static void visit(int k, int level, int siz, int *a) static void visit(mca_btl_tcp_proc_data_t *proc_data, int k, int level, int siz, int *a)
{ {
level = level+1; a[k] = level; level = level+1; a[k] = level;
if (level == siz) { if (level == siz) {
evaluate_assignment(a); evaluate_assignment(proc_data, a);
} else { } else {
int i; int i;
for ( i = 0; i < siz; i++) for ( i = 0; i < siz; i++)
if (a[i] == 0) if (a[i] == 0)
visit(i, level, siz, a); visit(proc_data, i, level, siz, a);
} }
level = level-1; a[k] = 0; level = level-1; a[k] = 0;
@ -258,23 +261,25 @@ static void mca_btl_tcp_initialise_interface(mca_btl_tcp_interface_t* tcp_interf
tcp_interface->inuse = 0; tcp_interface->inuse = 0;
} }
static mca_btl_tcp_interface_t** mca_btl_tcp_retrieve_local_interfaces(void) static mca_btl_tcp_interface_t** mca_btl_tcp_retrieve_local_interfaces(mca_btl_tcp_proc_data_t *proc_data)
{ {
struct sockaddr_storage local_addr; struct sockaddr_storage local_addr;
char local_if_name[IF_NAMESIZE]; char local_if_name[IF_NAMESIZE];
char **include, **exclude, **argv; char **include, **exclude, **argv;
int idx; int idx;
mca_btl_tcp_interface_t * local_interface;
if( NULL != local_interfaces ) assert (NULL == proc_data->local_interfaces);
return local_interfaces; if( NULL != proc_data->local_interfaces )
return proc_data->local_interfaces;
max_local_interfaces = MAX_KERNEL_INTERFACES; proc_data->max_local_interfaces = MAX_KERNEL_INTERFACES;
num_local_interfaces = 0; proc_data->num_local_interfaces = 0;
local_interfaces = (mca_btl_tcp_interface_t**)calloc( max_local_interfaces, sizeof(mca_btl_tcp_interface_t*) ); proc_data->local_interfaces = (mca_btl_tcp_interface_t**)calloc( proc_data->max_local_interfaces, sizeof(mca_btl_tcp_interface_t*) );
if( NULL == local_interfaces ) if( NULL == proc_data->local_interfaces )
return NULL; return NULL;
memset(local_kindex_to_index, -1, sizeof(int)*MAX_KERNEL_INTERFACE_INDEX); memset(proc_data->local_kindex_to_index, -1, sizeof(int)*MAX_KERNEL_INTERFACE_INDEX);
/* Collect up the list of included and excluded interfaces, if any */ /* Collect up the list of included and excluded interfaces, if any */
include = opal_argv_split(mca_btl_tcp_component.tcp_if_include,','); include = opal_argv_split(mca_btl_tcp_component.tcp_if_include,',');
@ -334,25 +339,26 @@ static mca_btl_tcp_interface_t** mca_btl_tcp_retrieve_local_interfaces(void)
} }
kindex = opal_ifindextokindex(idx); kindex = opal_ifindextokindex(idx);
index = local_kindex_to_index[kindex]; index = proc_data->local_kindex_to_index[kindex];
/* create entry for this kernel index previously not seen */ /* create entry for this kernel index previously not seen */
if(-1 == index) { if(-1 == index) {
index = num_local_interfaces++; index = proc_data->num_local_interfaces++;
local_kindex_to_index[kindex] = index; proc_data->local_kindex_to_index[kindex] = index;
if( num_local_interfaces == max_local_interfaces ) { if( proc_data->num_local_interfaces == proc_data->max_local_interfaces ) {
max_local_interfaces <<= 1; proc_data->max_local_interfaces <<= 1;
local_interfaces = (mca_btl_tcp_interface_t**)realloc( local_interfaces, proc_data->local_interfaces = (mca_btl_tcp_interface_t**)realloc( proc_data->local_interfaces,
max_local_interfaces * sizeof(mca_btl_tcp_interface_t*) ); proc_data->max_local_interfaces * sizeof(mca_btl_tcp_interface_t*) );
if( NULL == local_interfaces ) if( NULL == proc_data->local_interfaces )
goto cleanup; goto cleanup;
} }
local_interfaces[index] = (mca_btl_tcp_interface_t *) malloc(sizeof(mca_btl_tcp_interface_t)); proc_data->local_interfaces[index] = (mca_btl_tcp_interface_t *) malloc(sizeof(mca_btl_tcp_interface_t));
assert(NULL != local_interfaces[index]); assert(NULL != proc_data->local_interfaces[index]);
mca_btl_tcp_initialise_interface(local_interfaces[index], kindex, index); mca_btl_tcp_initialise_interface(proc_data->local_interfaces[index], kindex, index);
} }
local_interface = proc_data->local_interfaces[proc_data->local_kindex_to_index[kindex]];
switch(local_addr.ss_family) { switch(local_addr.ss_family) {
case AF_INET: case AF_INET:
/* if AF is disabled, skip it completely */ /* if AF is disabled, skip it completely */
@ -360,12 +366,12 @@ static mca_btl_tcp_interface_t** mca_btl_tcp_retrieve_local_interfaces(void)
continue; continue;
} }
local_interfaces[local_kindex_to_index[kindex]]->ipv4_address = local_interface->ipv4_address =
(struct sockaddr_storage*) malloc(sizeof(local_addr)); (struct sockaddr_storage*) malloc(sizeof(local_addr));
memcpy(local_interfaces[local_kindex_to_index[kindex]]->ipv4_address, memcpy(local_interface->ipv4_address,
&local_addr, sizeof(local_addr)); &local_addr, sizeof(local_addr));
opal_ifindextomask(idx, opal_ifindextomask(idx,
&local_interfaces[local_kindex_to_index[kindex]]->ipv4_netmask, &local_interface->ipv4_netmask,
sizeof(int)); sizeof(int));
break; break;
case AF_INET6: case AF_INET6:
@ -374,12 +380,12 @@ static mca_btl_tcp_interface_t** mca_btl_tcp_retrieve_local_interfaces(void)
continue; continue;
} }
local_interfaces[local_kindex_to_index[kindex]]->ipv6_address local_interface->ipv6_address
= (struct sockaddr_storage*) malloc(sizeof(local_addr)); = (struct sockaddr_storage*) malloc(sizeof(local_addr));
memcpy(local_interfaces[local_kindex_to_index[kindex]]->ipv6_address, memcpy(local_interface->ipv6_address,
&local_addr, sizeof(local_addr)); &local_addr, sizeof(local_addr));
opal_ifindextomask(idx, opal_ifindextomask(idx,
&local_interfaces[local_kindex_to_index[kindex]]->ipv6_netmask, &local_interface->ipv6_netmask,
sizeof(int)); sizeof(int));
break; break;
default: default:
@ -395,7 +401,7 @@ cleanup:
opal_argv_free(exclude); opal_argv_free(exclude);
} }
return local_interfaces; return proc_data->local_interfaces;
} }
/* /*
* Note that this routine must be called with the lock on the process * Note that this routine must be called with the lock on the process
@ -410,6 +416,10 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
unsigned int perm_size; unsigned int perm_size;
int rc, *a = NULL; int rc, *a = NULL;
size_t i, j; size_t i, j;
mca_btl_tcp_interface_t** peer_interfaces;
mca_btl_tcp_proc_data_t _proc_data, *proc_data=&_proc_data;
size_t max_peer_interfaces;
memset(proc_data, 0, sizeof(mca_btl_tcp_proc_data_t));
if (NULL == (proc_hostname = opal_get_proc_hostname(btl_proc->proc_opal))) { if (NULL == (proc_hostname = opal_get_proc_hostname(btl_proc->proc_opal))) {
return OPAL_ERR_UNREACH; return OPAL_ERR_UNREACH;
@ -431,21 +441,17 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
btl_proc->proc_endpoints[btl_proc->proc_endpoint_count++] = btl_endpoint; btl_proc->proc_endpoints[btl_proc->proc_endpoint_count++] = btl_endpoint;
/* sanity checks */ /* sanity checks */
if( NULL == local_interfaces ) { if( NULL == mca_btl_tcp_retrieve_local_interfaces(proc_data) )
if( NULL == mca_btl_tcp_retrieve_local_interfaces() ) return OPAL_ERR_OUT_OF_RESOURCE;
return OPAL_ERR_OUT_OF_RESOURCE; if( 0 == proc_data->num_local_interfaces ) {
}
if( 0 == num_local_interfaces ) {
return OPAL_ERR_UNREACH; return OPAL_ERR_UNREACH;
} }
if( NULL == peer_interfaces ) { max_peer_interfaces = proc_data->max_local_interfaces;
max_peer_interfaces = max_local_interfaces; peer_interfaces = (mca_btl_tcp_interface_t**)calloc( max_peer_interfaces, sizeof(mca_btl_tcp_interface_t*) );
peer_interfaces = (mca_btl_tcp_interface_t**)malloc( max_peer_interfaces * sizeof(mca_btl_tcp_interface_t*) ); assert(NULL != peer_interfaces);
} proc_data->num_peer_interfaces = 0;
num_peer_interfaces = 0; memset(proc_data->peer_kindex_to_index, -1, sizeof(int)*MAX_KERNEL_INTERFACE_INDEX);
memset(peer_kindex_to_index, -1, sizeof(int)*MAX_KERNEL_INTERFACE_INDEX);
memset(peer_interfaces, 0, max_peer_interfaces * sizeof(mca_btl_tcp_interface_t*));
/* /*
* identify all kernel interfaces and the associated addresses of * identify all kernel interfaces and the associated addresses of
@ -460,12 +466,12 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
mca_btl_tcp_proc_tosocks (endpoint_addr, &endpoint_addr_ss); mca_btl_tcp_proc_tosocks (endpoint_addr, &endpoint_addr_ss);
index = peer_kindex_to_index[endpoint_addr->addr_ifkindex]; index = proc_data->peer_kindex_to_index[endpoint_addr->addr_ifkindex];
if(-1 == index) { if(-1 == index) {
index = num_peer_interfaces++; index = proc_data->num_peer_interfaces++;
peer_kindex_to_index[endpoint_addr->addr_ifkindex] = index; proc_data->peer_kindex_to_index[endpoint_addr->addr_ifkindex] = index;
if( num_peer_interfaces == max_peer_interfaces ) { if( proc_data->num_peer_interfaces == max_peer_interfaces ) {
max_peer_interfaces <<= 1; max_peer_interfaces <<= 1;
peer_interfaces = (mca_btl_tcp_interface_t**)realloc( peer_interfaces, peer_interfaces = (mca_btl_tcp_interface_t**)realloc( peer_interfaces,
max_peer_interfaces * sizeof(mca_btl_tcp_interface_t*) ); max_peer_interfaces * sizeof(mca_btl_tcp_interface_t*) );
@ -512,68 +518,71 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
* assign weights to each possible pair of interfaces * assign weights to each possible pair of interfaces
*/ */
perm_size = num_local_interfaces; perm_size = proc_data->num_local_interfaces;
if(num_peer_interfaces > perm_size) { if(proc_data->num_peer_interfaces > perm_size) {
perm_size = num_peer_interfaces; perm_size = proc_data->num_peer_interfaces;
} }
weights = (enum mca_btl_tcp_connection_quality**) malloc(perm_size proc_data->weights = (enum mca_btl_tcp_connection_quality**) malloc(perm_size
* sizeof(enum mca_btl_tcp_connection_quality*)); * sizeof(enum mca_btl_tcp_connection_quality*));
assert(NULL != proc_data->weights);
best_addr = (mca_btl_tcp_addr_t ***) malloc(perm_size proc_data->best_addr = (mca_btl_tcp_addr_t ***) malloc(perm_size
* sizeof(mca_btl_tcp_addr_t **)); * sizeof(mca_btl_tcp_addr_t **));
assert(NULL != proc_data->best_addr);
for(i = 0; i < perm_size; ++i) { for(i = 0; i < perm_size; ++i) {
weights[i] = (enum mca_btl_tcp_connection_quality*) malloc(perm_size * proc_data->weights[i] = (enum mca_btl_tcp_connection_quality*) calloc(perm_size,
sizeof(enum mca_btl_tcp_connection_quality)); sizeof(enum mca_btl_tcp_connection_quality));
memset(weights[i], 0, perm_size * sizeof(enum mca_btl_tcp_connection_quality)); assert(NULL != proc_data->weights[i]);
best_addr[i] = (mca_btl_tcp_addr_t **) malloc(perm_size * proc_data->best_addr[i] = (mca_btl_tcp_addr_t **) calloc(perm_size,
sizeof(mca_btl_tcp_addr_t *)); sizeof(mca_btl_tcp_addr_t *));
memset(best_addr[i], 0, perm_size * sizeof(mca_btl_tcp_addr_t *)); assert(NULL != proc_data->best_addr[i]);
} }
for(i=0; i<num_local_interfaces; ++i) { for(i=0; i<proc_data->num_local_interfaces; ++i) {
for(j=0; j<num_peer_interfaces; ++j) { mca_btl_tcp_interface_t* local_interface = proc_data->local_interfaces[i];
for(j=0; j<proc_data->num_peer_interfaces; ++j) {
/* initially, assume no connection is possible */ /* initially, assume no connection is possible */
weights[i][j] = CQ_NO_CONNECTION; proc_data->weights[i][j] = CQ_NO_CONNECTION;
/* check state of ipv4 address pair */ /* check state of ipv4 address pair */
if(NULL != local_interfaces[i]->ipv4_address && if(NULL != proc_data->local_interfaces[i]->ipv4_address &&
NULL != peer_interfaces[j]->ipv4_address) { NULL != peer_interfaces[j]->ipv4_address) {
/* check for loopback */ /* check for loopback */
if ((opal_net_islocalhost((struct sockaddr *)local_interfaces[i]->ipv4_address) && if ((opal_net_islocalhost((struct sockaddr *)local_interface->ipv4_address) &&
!opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv4_address)) || !opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv4_address)) ||
(opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv4_address) && (opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv4_address) &&
!opal_net_islocalhost((struct sockaddr *)local_interfaces[i]->ipv4_address)) || !opal_net_islocalhost((struct sockaddr *)local_interface->ipv4_address)) ||
(opal_net_islocalhost((struct sockaddr *)local_interfaces[i]->ipv4_address) && (opal_net_islocalhost((struct sockaddr *)local_interface->ipv4_address) &&
!opal_ifislocal(proc_hostname))) { !opal_ifislocal(proc_hostname))) {
/* No connection is possible on these interfaces */ /* No connection is possible on these interfaces */
/* check for RFC1918 */ /* check for RFC1918 */
} else if(opal_net_addr_isipv4public((struct sockaddr*) local_interfaces[i]->ipv4_address) && } else if(opal_net_addr_isipv4public((struct sockaddr*) local_interface->ipv4_address) &&
opal_net_addr_isipv4public((struct sockaddr*) peer_interfaces[j]->ipv4_address)) { opal_net_addr_isipv4public((struct sockaddr*) peer_interfaces[j]->ipv4_address)) {
if(opal_net_samenetwork((struct sockaddr*) local_interfaces[i]->ipv4_address, if(opal_net_samenetwork((struct sockaddr*) local_interface->ipv4_address,
(struct sockaddr*) peer_interfaces[j]->ipv4_address, (struct sockaddr*) peer_interfaces[j]->ipv4_address,
local_interfaces[i]->ipv4_netmask)) { local_interface->ipv4_netmask)) {
weights[i][j] = CQ_PUBLIC_SAME_NETWORK; proc_data->weights[i][j] = CQ_PUBLIC_SAME_NETWORK;
} else { } else {
weights[i][j] = CQ_PUBLIC_DIFFERENT_NETWORK; proc_data->weights[i][j] = CQ_PUBLIC_DIFFERENT_NETWORK;
} }
best_addr[i][j] = peer_interfaces[j]->ipv4_endpoint_addr; proc_data->best_addr[i][j] = peer_interfaces[j]->ipv4_endpoint_addr;
continue; continue;
} else { } else {
if(opal_net_samenetwork((struct sockaddr*) local_interfaces[i]->ipv4_address, if(opal_net_samenetwork((struct sockaddr*) local_interface->ipv4_address,
(struct sockaddr*) peer_interfaces[j]->ipv4_address, (struct sockaddr*) peer_interfaces[j]->ipv4_address,
local_interfaces[i]->ipv4_netmask)) { local_interface->ipv4_netmask)) {
weights[i][j] = CQ_PRIVATE_SAME_NETWORK; proc_data->weights[i][j] = CQ_PRIVATE_SAME_NETWORK;
} else { } else {
weights[i][j] = CQ_PRIVATE_DIFFERENT_NETWORK; proc_data->weights[i][j] = CQ_PRIVATE_DIFFERENT_NETWORK;
} }
best_addr[i][j] = peer_interfaces[j]->ipv4_endpoint_addr; proc_data->best_addr[i][j] = peer_interfaces[j]->ipv4_endpoint_addr;
continue; continue;
} }
} }
@ -581,27 +590,27 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
/* check state of ipv6 address pair - ipv6 is always public, /* check state of ipv6 address pair - ipv6 is always public,
* since link-local addresses are skipped in opal_ifinit() * since link-local addresses are skipped in opal_ifinit()
*/ */
if(NULL != local_interfaces[i]->ipv6_address && if(NULL != local_interface->ipv6_address &&
NULL != peer_interfaces[j]->ipv6_address) { NULL != peer_interfaces[j]->ipv6_address) {
/* check for loopback */ /* check for loopback */
if ((opal_net_islocalhost((struct sockaddr *)local_interfaces[i]->ipv6_address) && if ((opal_net_islocalhost((struct sockaddr *)local_interface->ipv6_address) &&
!opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv6_address)) || !opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv6_address)) ||
(opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv6_address) && (opal_net_islocalhost((struct sockaddr *)peer_interfaces[j]->ipv6_address) &&
!opal_net_islocalhost((struct sockaddr *)local_interfaces[i]->ipv6_address)) || !opal_net_islocalhost((struct sockaddr *)local_interface->ipv6_address)) ||
(opal_net_islocalhost((struct sockaddr *)local_interfaces[i]->ipv6_address) && (opal_net_islocalhost((struct sockaddr *)local_interface->ipv6_address) &&
!opal_ifislocal(proc_hostname))) { !opal_ifislocal(proc_hostname))) {
/* No connection is possible on these interfaces */ /* No connection is possible on these interfaces */
} else if(opal_net_samenetwork((struct sockaddr*) local_interfaces[i]->ipv6_address, } else if(opal_net_samenetwork((struct sockaddr*) local_interface->ipv6_address,
(struct sockaddr*) peer_interfaces[j]->ipv6_address, (struct sockaddr*) peer_interfaces[j]->ipv6_address,
local_interfaces[i]->ipv6_netmask)) { local_interface->ipv6_netmask)) {
weights[i][j] = CQ_PUBLIC_SAME_NETWORK; proc_data->weights[i][j] = CQ_PUBLIC_SAME_NETWORK;
} else { } else {
weights[i][j] = CQ_PUBLIC_DIFFERENT_NETWORK; proc_data->weights[i][j] = CQ_PUBLIC_DIFFERENT_NETWORK;
} }
best_addr[i][j] = peer_interfaces[j]->ipv6_endpoint_addr; proc_data->best_addr[i][j] = peer_interfaces[j]->ipv6_endpoint_addr;
continue; continue;
} }
@ -613,7 +622,7 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
* interfaces * interfaces
*/ */
best_assignment = (unsigned int *) malloc (perm_size * sizeof(int)); proc_data->best_assignment = (unsigned int *) malloc (perm_size * sizeof(int));
a = (int *) malloc(perm_size * sizeof(int)); a = (int *) malloc(perm_size * sizeof(int));
if (NULL == a) { if (NULL == a) {
@ -627,20 +636,21 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
* for more details about this issue. */ * for more details about this issue. */
if (perm_size <= MAX_PERMUTATION_INTERFACES) { if (perm_size <= MAX_PERMUTATION_INTERFACES) {
memset(a, 0, perm_size * sizeof(int)); memset(a, 0, perm_size * sizeof(int));
max_assignment_cardinality = -1; proc_data->max_assignment_cardinality = -1;
max_assignment_weight = -1; proc_data->max_assignment_weight = -1;
visit(0, -1, perm_size, a); visit(proc_data, 0, -1, perm_size, a);
rc = OPAL_ERR_UNREACH; rc = OPAL_ERR_UNREACH;
for(i = 0; i < perm_size; ++i) { for(i = 0; i < perm_size; ++i) {
if(best_assignment[i] > num_peer_interfaces unsigned int best = proc_data->best_assignment[i];
|| weights[i][best_assignment[i]] == CQ_NO_CONNECTION if(best > proc_data->num_peer_interfaces
|| peer_interfaces[best_assignment[i]]->inuse || proc_data->weights[i][best] == CQ_NO_CONNECTION
|| NULL == peer_interfaces[best_assignment[i]]) { || peer_interfaces[best]->inuse
|| NULL == peer_interfaces[best]) {
continue; continue;
} }
peer_interfaces[best_assignment[i]]->inuse++; peer_interfaces[best]->inuse++;
btl_endpoint->endpoint_addr = best_addr[i][best_assignment[i]]; btl_endpoint->endpoint_addr = proc_data->best_addr[i][best];
btl_endpoint->endpoint_addr->addr_inuse++; btl_endpoint->endpoint_addr->addr_inuse++;
rc = OPAL_SUCCESS; rc = OPAL_SUCCESS;
break; break;
@ -651,11 +661,11 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
/* Find the best connection that is not in use. Save away /* Find the best connection that is not in use. Save away
* the indices of the best location. */ * the indices of the best location. */
max = CQ_NO_CONNECTION; max = CQ_NO_CONNECTION;
for(i=0; i<num_local_interfaces; ++i) { for(i=0; i<proc_data->num_local_interfaces; ++i) {
for(j=0; j<num_peer_interfaces; ++j) { for(j=0; j<proc_data->num_peer_interfaces; ++j) {
if (!peer_interfaces[j]->inuse) { if (!peer_interfaces[j]->inuse) {
if (weights[i][j] > max) { if (proc_data->weights[i][j] > max) {
max = weights[i][j]; max = proc_data->weights[i][j];
i_max = i; i_max = i;
j_max = j; j_max = j;
} }
@ -666,18 +676,18 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
rc = OPAL_ERR_UNREACH; rc = OPAL_ERR_UNREACH;
if (CQ_NO_CONNECTION != max) { if (CQ_NO_CONNECTION != max) {
peer_interfaces[j_max]->inuse++; peer_interfaces[j_max]->inuse++;
btl_endpoint->endpoint_addr = best_addr[i_max][j_max]; btl_endpoint->endpoint_addr = proc_data->best_addr[i_max][j_max];
btl_endpoint->endpoint_addr->addr_inuse++; btl_endpoint->endpoint_addr->addr_inuse++;
rc = OPAL_SUCCESS; rc = OPAL_SUCCESS;
} }
} }
for(i = 0; i < perm_size; ++i) { for(i = 0; i < perm_size; ++i) {
free(weights[i]); free(proc_data->weights[i]);
free(best_addr[i]); free(proc_data->best_addr[i]);
} }
for(i = 0; i < num_peer_interfaces; ++i) { for(i = 0; i < proc_data->num_peer_interfaces; ++i) {
if(NULL != peer_interfaces[i]->ipv4_address) { if(NULL != peer_interfaces[i]->ipv4_address) {
free(peer_interfaces[i]->ipv4_address); free(peer_interfaces[i]->ipv4_address);
} }
@ -687,25 +697,22 @@ int mca_btl_tcp_proc_insert( mca_btl_tcp_proc_t* btl_proc,
free(peer_interfaces[i]); free(peer_interfaces[i]);
} }
free(peer_interfaces); free(peer_interfaces);
peer_interfaces = NULL;
max_peer_interfaces = 0;
for(i = 0; i < num_local_interfaces; ++i) { for(i = 0; i < proc_data->num_local_interfaces; ++i) {
if(NULL != local_interfaces[i]->ipv4_address) { if(NULL != proc_data->local_interfaces[i]->ipv4_address) {
free(local_interfaces[i]->ipv4_address); free(proc_data->local_interfaces[i]->ipv4_address);
} }
if(NULL != local_interfaces[i]->ipv6_address) { if(NULL != proc_data->local_interfaces[i]->ipv6_address) {
free(local_interfaces[i]->ipv6_address); free(proc_data->local_interfaces[i]->ipv6_address);
} }
free(local_interfaces[i]); free(proc_data->local_interfaces[i]);
} }
free(local_interfaces); free(proc_data->local_interfaces);
local_interfaces = NULL; proc_data->max_local_interfaces = 0;
max_local_interfaces = 0;
free(weights); free(proc_data->weights);
free(best_addr); free(proc_data->best_addr);
free(best_assignment); free(proc_data->best_assignment);
free(a); free(a);
return rc; return rc;