14b36d4503
This commit fixes two issues that can occur during a connection: - Re-entry to connection progress from modex lookup. Added an additional endpoint state that will keep the code from re-entering the common endpoint create. - Fixed a race between a process posting a directed datagram through a send and a connection being progressed through opal_progress(). The progress code was not obtaining the endpoint lock before attempting to update the endpoint. To limit the amount of code changed for 2.0.1 this commit makes the endpoint lock recursive. In a future update this may be changed. Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
201 строка
5.7 KiB
C
201 строка
5.7 KiB
C
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
|
/*
|
|
* Copyright (c) 2011-2016 Los Alamos National Security, LLC. All rights
|
|
* reserved.
|
|
* Copyright (c) 2011 UT-Battelle, LLC. All rights reserved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#ifndef MCA_BTL_UGNI_ENDPOINT_H
|
|
#define MCA_BTL_UGNI_ENDPOINT_H
|
|
|
|
#include "btl_ugni.h"
|
|
|
|
enum mca_btl_ugni_endpoint_state_t {
|
|
MCA_BTL_UGNI_EP_STATE_INIT = 0,
|
|
MCA_BTL_UGNI_EP_STATE_START,
|
|
MCA_BTL_UGNI_EP_STATE_RDMA,
|
|
MCA_BTL_UGNI_EP_STATE_CONNECTING,
|
|
MCA_BTL_UGNI_EP_STATE_CONNECTED
|
|
};
|
|
typedef enum mca_btl_ugni_endpoint_state_t mca_btl_ugni_endpoint_state_t;
|
|
|
|
struct mca_btl_ugni_smsg_mbox_t;
|
|
|
|
typedef struct mca_btl_base_endpoint_t {
|
|
opal_list_item_t super;
|
|
|
|
opal_proc_t *peer_proc;
|
|
|
|
/** may need to lock recursively as the modex lookup could call opal_progress
|
|
* and hence our progress function. if this changes modify this mutex to not
|
|
* be recursive. also need to update the constructor function. */
|
|
opal_recursive_mutex_t lock;
|
|
mca_btl_ugni_endpoint_state_t state;
|
|
|
|
opal_common_ugni_endpoint_t *common;
|
|
|
|
mca_btl_ugni_module_t *btl;
|
|
|
|
gni_ep_handle_t smsg_ep_handle;
|
|
gni_ep_handle_t rdma_ep_handle;
|
|
|
|
mca_btl_ugni_endpoint_attr_t remote_attr; /* TODO: UGH, remove this */
|
|
|
|
struct mca_btl_ugni_smsg_mbox_t *mailbox;
|
|
gni_mem_handle_t rmt_irq_mem_hndl;
|
|
|
|
|
|
opal_list_t frag_wait_list;
|
|
bool wait_listed;
|
|
/** protect against race on connection */
|
|
bool dg_posted;
|
|
|
|
int32_t smsg_progressing;
|
|
|
|
int index;
|
|
} mca_btl_base_endpoint_t;
|
|
|
|
typedef mca_btl_base_endpoint_t mca_btl_ugni_endpoint_t;
|
|
OBJ_CLASS_DECLARATION(mca_btl_ugni_endpoint_t);
|
|
|
|
int mca_btl_ugni_ep_connect_progress (mca_btl_ugni_endpoint_t *ep);
|
|
int mca_btl_ugni_ep_disconnect (mca_btl_ugni_endpoint_t *ep, bool send_disconnect);
|
|
|
|
static inline int mca_btl_ugni_init_ep (mca_btl_ugni_module_t *ugni_module,
|
|
mca_btl_ugni_endpoint_t **ep,
|
|
mca_btl_ugni_module_t *btl,
|
|
opal_proc_t *peer_proc) {
|
|
mca_btl_ugni_endpoint_t *endpoint;
|
|
|
|
endpoint = OBJ_NEW(mca_btl_ugni_endpoint_t);
|
|
assert (endpoint != NULL);
|
|
|
|
endpoint->smsg_progressing = 0;
|
|
endpoint->state = MCA_BTL_UGNI_EP_STATE_INIT;
|
|
|
|
endpoint->btl = btl;
|
|
endpoint->peer_proc = peer_proc;
|
|
endpoint->index = opal_pointer_array_add (&ugni_module->endpoints, endpoint);
|
|
|
|
*ep = endpoint;
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
static inline void mca_btl_ugni_release_ep (mca_btl_ugni_endpoint_t *ep) {
|
|
int rc;
|
|
|
|
if (ep->common) {
|
|
opal_mutex_lock (&ep->lock);
|
|
|
|
rc = mca_btl_ugni_ep_disconnect (ep, false);
|
|
if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) {
|
|
BTL_VERBOSE(("btl/ugni error disconnecting endpoint"));
|
|
}
|
|
|
|
/* TODO -- Clear space at the end of the endpoint array */
|
|
opal_pointer_array_set_item (&ep->btl->endpoints, ep->index, NULL);
|
|
|
|
opal_mutex_unlock (&ep->lock);
|
|
|
|
opal_common_ugni_endpoint_return (ep->common);
|
|
}
|
|
|
|
OBJ_RELEASE(ep);
|
|
}
|
|
|
|
static inline int mca_btl_ugni_check_endpoint_state (mca_btl_ugni_endpoint_t *ep) {
|
|
int rc;
|
|
|
|
if (OPAL_LIKELY(MCA_BTL_UGNI_EP_STATE_CONNECTED == ep->state)) {
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
opal_mutex_lock (&ep->lock);
|
|
|
|
switch (ep->state) {
|
|
case MCA_BTL_UGNI_EP_STATE_INIT:
|
|
case MCA_BTL_UGNI_EP_STATE_RDMA:
|
|
case MCA_BTL_UGNI_EP_STATE_START:
|
|
rc = mca_btl_ugni_ep_connect_progress (ep);
|
|
if (OPAL_SUCCESS != rc) {
|
|
break;
|
|
}
|
|
case MCA_BTL_UGNI_EP_STATE_CONNECTING:
|
|
rc = OPAL_ERR_RESOURCE_BUSY;
|
|
break;
|
|
default:
|
|
rc = OPAL_SUCCESS;
|
|
}
|
|
|
|
opal_mutex_unlock (&ep->lock);
|
|
|
|
return rc;
|
|
}
|
|
|
|
static inline int mca_btl_ugni_ep_connect_rdma (mca_btl_base_endpoint_t *ep) {
|
|
int rc;
|
|
|
|
if (ep->state >= MCA_BTL_UGNI_EP_STATE_RDMA) {
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
/* protect against re-entry from opal_progress */
|
|
if (OPAL_UNLIKELY(MCA_BTL_UGNI_EP_STATE_START == ep->state)) {
|
|
return OPAL_ERR_RESOURCE_BUSY;
|
|
}
|
|
|
|
ep->state = MCA_BTL_UGNI_EP_STATE_START;
|
|
|
|
/* get the modex info for this endpoint and setup a ugni endpoint. this call may lead
|
|
* to re-entry through opal_progress(). */
|
|
rc = opal_common_ugni_endpoint_for_proc (ep->btl->device, ep->peer_proc, &ep->common);
|
|
if (OPAL_SUCCESS != rc) {
|
|
assert (0);
|
|
return rc;
|
|
}
|
|
|
|
/* bind endpoint to remote address */
|
|
rc = opal_common_ugni_ep_create (ep->common, ep->btl->rdma_local_cq, &ep->rdma_ep_handle);
|
|
if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) {
|
|
return rc;
|
|
}
|
|
|
|
ep->state = MCA_BTL_UGNI_EP_STATE_RDMA;
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
static inline int mca_btl_ugni_check_endpoint_state_rdma (mca_btl_base_endpoint_t *ep) {
|
|
int rc;
|
|
if (OPAL_LIKELY(MCA_BTL_UGNI_EP_STATE_INIT < ep->state)) {
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
opal_mutex_lock (&ep->lock);
|
|
rc = mca_btl_ugni_ep_connect_rdma (ep);
|
|
opal_mutex_unlock (&ep->lock);
|
|
return rc;
|
|
}
|
|
|
|
static inline int mca_btl_ugni_wildcard_ep_post (mca_btl_ugni_module_t *ugni_module) {
|
|
gni_return_t rc;
|
|
|
|
BTL_VERBOSE(("posting wildcard datagram"));
|
|
|
|
memset (&ugni_module->wc_local_attr, 0, sizeof (ugni_module->wc_local_attr));
|
|
memset (&ugni_module->wc_remote_attr, 0, sizeof (ugni_module->wc_remote_attr));
|
|
rc = GNI_EpPostDataWId (ugni_module->wildcard_ep, &ugni_module->wc_local_attr,
|
|
sizeof (ugni_module->wc_local_attr), &ugni_module->wc_remote_attr,
|
|
sizeof (ugni_module->wc_remote_attr), MCA_BTL_UGNI_CONNECT_WILDCARD_ID);
|
|
|
|
return opal_common_rc_ugni_to_opal (rc);
|
|
}
|
|
|
|
#endif /* MCA_BTL_UGNI_ENDPOINT_H */
|