/* local prototypes */
static struct dapl_cm_id * dapli_req_recv(struct dapl_cm_id *conn,
struct rdma_cm_event *event);
-static int dapli_cm_active_cb(struct dapl_cm_id *conn,
+static void dapli_cm_active_cb(struct dapl_cm_id *conn,
struct rdma_cm_event *event);
-static int dapli_cm_passive_cb(struct dapl_cm_id *conn,
+static void dapli_cm_passive_cb(struct dapl_cm_id *conn,
struct rdma_cm_event *event);
static void dapli_addr_resolve(struct dapl_cm_id *conn);
static void dapli_route_resolve(struct dapl_cm_id *conn);
static void dapli_addr_resolve(struct dapl_cm_id *conn)
{
int ret;
-
+#ifdef DAPL_DBG
+ struct rdma_addr *ipaddr = &conn->cm_id->route.addr;
+#endif
dapl_dbg_log(DAPL_DBG_TYPE_CM,
" addr_resolve: cm_id %p SRC %x DST %x\n",
conn->cm_id,
static void dapli_route_resolve(struct dapl_cm_id *conn)
{
int ret;
- struct rdma_cm_id *cm_id = conn->cm_id;
-
+#ifdef DAPL_DBG
+ struct rdma_addr *ipaddr = &conn->cm_id->route.addr;
+ struct ib_addr *ibaddr = &conn->cm_id->route.addr.addr.ibaddr;
+#endif
dapl_dbg_log(DAPL_DBG_TYPE_CM,
" route_resolve: cm_id %p SRC %x DST %x PORT %d\n",
conn->cm_id,
NULL, conn->ep);
}
+/*
+ * Called from consumer thread via dat_ep_free().
+ * CANNOT be called from the async event processing thread
+ * dapli_cma_event_cb() since a cm_id reference is held and
+ * a deadlock will occur.
+ */
void dapli_destroy_conn(struct dapl_cm_id *conn)
{
- int in_callback;
+ struct rdma_cm_id *cm_id;
dapl_dbg_log(DAPL_DBG_TYPE_CM,
" destroy_conn: conn %p id %d\n",
conn,conn->cm_id);
-
+
dapl_os_lock(&conn->lock);
conn->destroy = 1;
- in_callback = conn->in_callback;
+
+ if (conn->ep)
+ conn->ep->cm_handle = IB_INVALID_HANDLE;
+
+ cm_id = conn->cm_id;
+ conn->cm_id = NULL;
dapl_os_unlock(&conn->lock);
- if (!in_callback) {
- if (conn->ep)
- conn->ep->cm_handle = IB_INVALID_HANDLE;
- if (conn->cm_id) {
- if (conn->cm_id->qp)
- rdma_destroy_qp(conn->cm_id);
- rdma_destroy_id(conn->cm_id);
- }
-
- conn->cm_id = NULL;
- dapl_os_free(conn, sizeof(*conn));
+ /*
+ * rdma_destroy_id will force synchronization with async CM event
+ * thread since it blocks until the in-process event reference
+ * is cleared during our event processing call exit.
+ */
+ if (cm_id) {
+ if (cm_id->qp)
+ rdma_destroy_qp(cm_id);
+
+ rdma_destroy_id(cm_id);
}
+ dapl_os_free(conn, sizeof(*conn));
}
static struct dapl_cm_id * dapli_req_recv(struct dapl_cm_id *conn,
struct rdma_cm_event *event)
{
struct dapl_cm_id *new_conn;
+#ifdef DAPL_DBG
+ struct rdma_addr *ipaddr = &event->id->route.addr;
+#endif
if (conn->sp == NULL) {
dapl_dbg_log(DAPL_DBG_TYPE_ERR,
return new_conn;
}
-static int dapli_cm_active_cb(struct dapl_cm_id *conn,
+static void dapli_cm_active_cb(struct dapl_cm_id *conn,
struct rdma_cm_event *event)
{
- int destroy;
-
dapl_dbg_log(DAPL_DBG_TYPE_CM,
" active_cb: conn %p id %d event %d\n",
conn, conn->cm_id, event->event );
dapl_os_lock(&conn->lock);
if (conn->destroy) {
dapl_os_unlock(&conn->lock);
- return 0;
+ return;
}
- conn->in_callback = 1;
dapl_os_unlock(&conn->lock);
switch (event->event) {
break;
}
- dapl_os_lock(&conn->lock);
- destroy = conn->destroy;
- conn->in_callback = conn->destroy;
- dapl_os_unlock(&conn->lock);
- return(destroy);
+ return;
}
-static int dapli_cm_passive_cb(struct dapl_cm_id *conn,
+static void dapli_cm_passive_cb(struct dapl_cm_id *conn,
struct rdma_cm_event *event)
{
- int destroy;
struct dapl_cm_id *new_conn;
dapl_dbg_log(DAPL_DBG_TYPE_CM,
dapl_os_lock(&conn->lock);
if (conn->destroy) {
dapl_os_unlock(&conn->lock);
- return 0;
+ return;
}
- conn->in_callback = 1;
dapl_os_unlock(&conn->lock);
switch (event->event) {
break;
}
- dapl_os_lock(&conn->lock);
- destroy = conn->destroy;
- conn->in_callback = conn->destroy;
- dapl_os_unlock(&conn->lock);
- return(destroy);
+ return;
}
void dapli_cma_event_cb(void)
{
struct rdma_cm_event *event;
- int ret;
-
- dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " cm_event()\n");
- ret = rdma_get_cm_event(&event);
+ dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " cm_event()\n");
/* process one CM event, fairness */
- if(!ret) {
+ if(!rdma_get_cm_event(&event)) {
struct dapl_cm_id *conn;
- int ret;
/* set proper conn from cm_id context*/
if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST)
case RDMA_CM_EVENT_DISCONNECTED:
/* passive or active */
if (conn->sp)
- ret = dapli_cm_passive_cb(conn,event);
+ dapli_cm_passive_cb(conn,event);
else
- ret = dapli_cm_active_cb(conn,event);
-
- /* destroy both qp and cm_id */
- if (ret) {
- dapl_dbg_log(DAPL_DBG_TYPE_CM,
- " cma_cb: DESTROY conn %p"
- " cm_id %p qp %p\n",
- conn, conn->cm_id,
- conn->cm_id->qp);
-
- if (conn->cm_id->qp)
- rdma_destroy_qp(conn->cm_id);
-
- rdma_ack_cm_event(event);
- rdma_destroy_id(conn->cm_id);
- dapl_os_free(conn, sizeof(*conn));
- return;
- }
+ dapli_cm_active_cb(conn,event);
break;
case RDMA_CM_EVENT_CONNECT_RESPONSE:
default:
event->id->context);
break;
}
+ /* ack event, unblocks destroy_cm_id in consumer threads */
rdma_ack_cm_event(event);
- } else {
- dapl_dbg_log(DAPL_DBG_TYPE_CM,
- " cm_event: ERROR: rdma_get_cm_event() %d %d %s\n",
- ret, errno, strerror(errno));
- }
+ }
}
/*