[ofa-general] [PATCH] uDAPL v2: move implementation of direct CQ objects down to provider level

Arlin Davis arlin.r.davis at intel.com
Wed Jul 29 10:03:49 PDT 2009


DAPL introduced the concept of directly waiting on the CQ for
events by adding a compile time flag and special handling in the common
code.  Rather than using the compile time flag and modifying the
common code, let the provider implement the best way to wait for
CQ events.

This simplifies the code and allows the common openib providers to
optimize for Linux and Windows platforms independently, rather than
assuming a specific implementation for signaling events.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
 dapl/common/dapl_adapter_util.h      |   19 +--
 dapl/common/dapl_evd_dto_callb.c     |    8 +-
 dapl/common/dapl_evd_util.c          |   36 +---
 dapl/ibal/dapl_ibal_cq.c             |   61 +------
 dapl/ibal/dapl_ibal_util.c           |   76 +-------
 dapl/ibal/dapl_ibal_util.h           |    1 -
 dapl/include/dapl.h                  |   10 +-
 dapl/openib_common/cq.c              |  353 +++++++++++++++++++---------------
 dapl/openib_common/dapl_ib_common.h  |    3 -
 dapl/openib_common/qp.c              |   11 +-
 dapl/udapl/dapl_evd_set_unwaitable.c |    7 +-
 dapl/udapl/dapl_evd_wait.c           |   19 +--
 12 files changed, 238 insertions(+), 366 deletions(-)

diff --git a/dapl/common/dapl_adapter_util.h b/dapl/common/dapl_adapter_util.h
index 1a8b7cc..97ab42e 100755
--- a/dapl/common/dapl_adapter_util.h
+++ b/dapl/common/dapl_adapter_util.h
@@ -249,25 +249,14 @@ dapls_query_provider_specific_attr(
    	IN DAPL_IA			*ia_ptr,
 	IN DAT_PROVIDER_ATTR		*attr_ptr );
 
-#ifdef CQ_WAIT_OBJECT
 DAT_RETURN
-dapls_ib_wait_object_create (
-	IN DAPL_EVD			*evd_ptr,
-	IN ib_wait_obj_handle_t		*p_cq_wait_obj_handle);
-
-DAT_RETURN
-dapls_ib_wait_object_destroy (
-	IN ib_wait_obj_handle_t		cq_wait_obj_handle);
+dapls_evd_dto_wakeup (
+	IN DAPL_EVD			*evd_ptr);
 
 DAT_RETURN
-dapls_ib_wait_object_wakeup (
-	IN ib_wait_obj_handle_t		cq_wait_obj_handle);
-
-DAT_RETURN
-dapls_ib_wait_object_wait (
-	IN ib_wait_obj_handle_t		cq_wait_obj_handle,
+dapls_evd_dto_wait (
+	IN DAPL_EVD			*evd_ptr,
 	IN uint32_t 			timeout);
-#endif
 
 #ifdef DAT_EXTENSIONS
 void
diff --git a/dapl/common/dapl_evd_dto_callb.c b/dapl/common/dapl_evd_dto_callb.c
index 2f0d106..2e8d70e 100755
--- a/dapl/common/dapl_evd_dto_callb.c
+++ b/dapl/common/dapl_evd_dto_callb.c
@@ -118,13 +118,7 @@ dapl_evd_dto_callback(IN ib_hca_handle_t hca_handle,
 		 * We don't need to worry about taking the lock for the
 		 * wakeup because wakeups are sticky.
 		 */
-#ifdef CQ_WAIT_OBJECT
-		if (evd_ptr->cq_wait_obj_handle)
-			dapls_ib_wait_object_wakeup(evd_ptr->
-						    cq_wait_obj_handle);
-		else
-#endif
-			dapl_os_wait_object_wakeup(&evd_ptr->wait_object);
+		dapls_evd_dto_wakeup(evd_ptr);
 
 	} else if (state == DAPL_EVD_STATE_OPEN) {
 		DAPL_CNO *cno = evd_ptr->cno_ptr;
diff --git a/dapl/common/dapl_evd_util.c b/dapl/common/dapl_evd_util.c
index 2cfd693..88c3f8f 100644
--- a/dapl/common/dapl_evd_util.c
+++ b/dapl/common/dapl_evd_util.c
@@ -161,7 +161,7 @@ dapls_evd_internal_create(DAPL_IA * ia_ptr,
 	 * be conservative and set producer side locking.  Otherwise, no.
 	 */
 	evd_ptr->evd_producer_locking_needed =
-	    ((evd_flags & ~(DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) != 0);
+	    !(evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG));
 
 	/* Before we setup any callbacks, transition state to OPEN.  */
 	evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;
@@ -301,20 +301,6 @@ DAPL_EVD *dapls_evd_alloc(IN DAPL_IA * ia_ptr,
 	evd_ptr->completion_type = DAPL_EVD_STATE_THRESHOLD;	/* FIXME: should be DAPL_EVD_STATE_INIT */
 	dapl_os_wait_object_init(&evd_ptr->wait_object);
 
-#ifdef CQ_WAIT_OBJECT
-	/* Create CQ wait object; no CNO and data stream type */
-	if ((cno_ptr == NULL) &&
-	    ((evd_flags & ~(DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) == 0)) {
-		dapls_ib_wait_object_create(evd_ptr,
-					    &evd_ptr->cq_wait_obj_handle);
-		if (evd_ptr->cq_wait_obj_handle == NULL) {
-			dapl_os_free(evd_ptr, sizeof(DAPL_EVD));
-			evd_ptr = NULL;
-			goto bail;
-		}
-	}
-#endif
-
 	evd_ptr->cno_active_count = 0;
 	if (cno_ptr != NULL) {
 		/* Take a reference count on the CNO */
@@ -517,12 +503,6 @@ DAT_RETURN dapls_evd_dealloc(IN DAPL_EVD * evd_ptr)
 
 	dapl_os_wait_object_destroy(&evd_ptr->wait_object);
 
-#ifdef CQ_WAIT_OBJECT
-	if (evd_ptr->cq_wait_obj_handle) {
-		dapls_ib_wait_object_destroy(evd_ptr->cq_wait_obj_handle);
-	}
-#endif
-
 #ifdef DAPL_COUNTERS
 	dapl_os_free(evd_ptr->cntrs,
 		     sizeof(DAT_UINT64) * DCNT_EVD_ALL_COUNTERS);
@@ -698,14 +678,12 @@ dapli_evd_post_event(IN DAPL_EVD * evd_ptr, IN const DAT_EVENT * event_ptr)
 			>= evd_ptr->threshold)) {
 			dapl_os_unlock(&evd_ptr->header.lock);
 
-#ifdef CQ_WAIT_OBJECT
-			if (evd_ptr->cq_wait_obj_handle)
-				dapls_ib_wait_object_wakeup(evd_ptr->
-							    cq_wait_obj_handle);
-			else
-#endif
-				dapl_os_wait_object_wakeup(&evd_ptr->
-							   wait_object);
+			if (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) {
+				dapls_evd_dto_wakeup(evd_ptr);
+			} else {
+				dapl_os_wait_object_wakeup(&evd_ptr->wait_object);
+			}
+
 		} else {
 			dapl_os_unlock(&evd_ptr->header.lock);
 		}
diff --git a/dapl/ibal/dapl_ibal_cq.c b/dapl/ibal/dapl_ibal_cq.c
index 28de045..5bc51af 100644
--- a/dapl/ibal/dapl_ibal_cq.c
+++ b/dapl/ibal/dapl_ibal_cq.c
@@ -159,18 +159,8 @@ dapls_ib_cq_late_alloc (
     
     ibal_ca = (dapl_ibal_ca_t*)evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle;
 	
-#ifdef CQ_WAIT_OBJECT
-    if (evd_ptr->cq_wait_obj_handle)
-    {
-        cq_create.h_wait_obj  = evd_ptr->cq_wait_obj_handle;
-        cq_create.pfn_comp_cb = NULL;
-    }
-    else 
-#endif
-    {
-        cq_create.h_wait_obj  = NULL;
-        cq_create.pfn_comp_cb = dapli_ib_cq_completion_cb;
-    }
+    cq_create.h_wait_obj  = NULL;
+    cq_create.pfn_comp_cb = dapli_ib_cq_completion_cb;
 
     ib_status = ib_create_cq (
                         (ib_ca_handle_t)ibal_ca->h_ca,
@@ -227,53 +217,6 @@ bail:
  *
  */
 
-#if 0
-
-/* windows delays CQ creation as a PD (Protection Domain) is required
- * and we do not have one at this juncture. The follow code is for future 
- * reference only.
- */
-
-DAT_RETURN
-dapls_ib_cq_alloc (
-	IN  DAPL_IA		*ia_ptr,
-	IN  DAPL_EVD		*evd_ptr,
-	IN  DAT_COUNT		*cqlen )
-{
-     dapl_dbg_log ( DAPL_DBG_TYPE_UTIL, 
-		"dapls_ib_cq_alloc: evd %lx cqlen=%d \n", evd_ptr, *cqlen );
-
-     struct ibv_comp_channel *channel = ia_ptr->hca_ptr->ib_trans.ib_cq;
-
-#ifdef CQ_WAIT_OBJECT
-     if (evd_ptr->cq_wait_obj_handle)
-     	channel = evd_ptr->cq_wait_obj_handle;
-#endif
-
-     /* Call IB verbs to create CQ */
-     evd_ptr->ib_cq_handle = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,
-                                           *cqlen,
-                                           evd_ptr,
-                                           channel,
-                                           0);
-	
-     if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE) 
-         return	DAT_INSUFFICIENT_RESOURCES;
-
-     /* arm cq for events */
-     dapls_set_cq_notify(ia_ptr, evd_ptr);
-	
-        /* update with returned cq entry size */
-     *cqlen = evd_ptr->ib_cq_handle->cqe;
-
-     dapl_dbg_log ( DAPL_DBG_TYPE_UTIL,
-                    "dapls_ib_cq_alloc: new_cq %lx cqlen=%d \n", 
-                    evd_ptr->ib_cq_handle, *cqlen );
-
-     return DAT_SUCCESS;
-}
-#endif
-
 
 /*
  * dapl_ib_cq_free
diff --git a/dapl/ibal/dapl_ibal_util.c b/dapl/ibal/dapl_ibal_util.c
index ad4acf0..513d7c9 100644
--- a/dapl/ibal/dapl_ibal_util.c
+++ b/dapl/ibal/dapl_ibal_util.c
@@ -1850,83 +1850,21 @@ dapls_ib_completion_notify ( IN ib_hca_handle_t         hca_handle,
     return dapl_ib_status_convert (ib_status);
 }
 
-
-
-DAT_RETURN
-dapls_ib_wait_object_create (
-        IN cl_waitobj_handle_t* p_cq_wait_obj_handle)
-{
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_create (FALSE /* auto_reset */, p_cq_wait_obj_handle);
-
-    if (cl_status == CL_SUCCESS)
-        return DAT_SUCCESS;
-
-    return DAT_INTERNAL_ERROR;
-}
-
-
-DAT_RETURN
-dapls_ib_wait_object_destroy (
-        IN cl_waitobj_handle_t    cq_wait_obj_handle)
-{
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_destroy (cq_wait_obj_handle);
-
-    if (cl_status == CL_SUCCESS)
-        return DAT_SUCCESS;
-
-    return DAT_INTERNAL_ERROR;
-}
-
-
 DAT_RETURN
-dapls_ib_wait_object_wakeup (
-        IN cl_waitobj_handle_t    cq_wait_obj_handle)
+dapls_evd_dto_wakeup (
+	IN DAPL_EVD			*evd_ptr)
 {
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_signal (cq_wait_obj_handle);
-
-    if (cl_status == CL_SUCCESS)
-        return DAT_SUCCESS;
-
-    return DAT_INTERNAL_ERROR;
+	return dapl_os_wait_object_wakeup(&evd_ptr->wait_object);
 }
 
-
 DAT_RETURN
-dapls_ib_wait_object_wait (
-        IN cl_waitobj_handle_t cq_wait_obj_handle,
-        IN uint32_t timeout)
+dapls_evd_dto_wait (
+	IN DAPL_EVD			*evd_ptr,
+	IN uint32_t 			timeout)
 {
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_wait_on (cq_wait_obj_handle, timeout, TRUE ); 
-
-    switch (cl_status)
-    {
-        case CL_SUCCESS: 
-            return DAT_SUCCESS;
-
-        case CL_TIMEOUT: 
-            dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                         "--> wait_object_wait: cl_timeout: %d\n", timeout);
-            return DAT_TIMEOUT_EXPIRED;
-
-        case CL_NOT_DONE: 
-            return DAT_SUCCESS;
-
-        default: 
-            dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                         "--> wait_object_wait: cl_error: %d\n", cl_status);
-            return DAT_INTERNAL_ERROR;
-    }
+	return dapl_os_wait_object_wait(&evd_ptr->wait_object, timeout);
 }
 
-
 /*
  * dapls_ib_get_async_event
  *
diff --git a/dapl/ibal/dapl_ibal_util.h b/dapl/ibal/dapl_ibal_util.h
index 52dd879..a73d6c1 100644
--- a/dapl/ibal/dapl_ibal_util.h
+++ b/dapl/ibal/dapl_ibal_util.h
@@ -51,7 +51,6 @@ typedef  ib_wr_type_t                  ib_send_op_type_t;
 typedef  ib_wc_t                       ib_work_completion_t;
 typedef  uint32_t                      ib_hca_port_t;
 typedef  uint32_t                      ib_uint32_t;
-typedef  uint32_t                      ib_comp_handle_t;
 typedef  ib_local_ds_t                 ib_data_segment_t;
 
 typedef  unsigned __int3264            cl_dev_handle_t;
diff --git a/dapl/include/dapl.h b/dapl/include/dapl.h
index b13c963..a36b110 100755
--- a/dapl/include/dapl.h
+++ b/dapl/include/dapl.h
@@ -355,9 +355,6 @@ struct dapl_evd
     /* Every EVD has a CQ unless it is a SOFTWARE_EVENT only EVD */
     ib_cq_handle_t	ib_cq_handle;
 
-    /* Mellanox Specific completion handle for registration/de-registration */
-    ib_comp_handle_t    ib_comp_handle;
-
     /* An Event Dispatcher cannot be freed while
      * it is referenced elsewhere.
      */
@@ -382,12 +379,7 @@ struct dapl_evd
     DAT_COUNT		cno_active_count;
     DAPL_CNO		*cno_ptr;
 
-    DAPL_OS_WAIT_OBJECT wait_object;
-
-#ifdef CQ_WAIT_OBJECT
-    /* Some providers support a direct CQ wait object */
-    ib_wait_obj_handle_t	cq_wait_obj_handle;
-#endif
+    DAPL_OS_WAIT_OBJECT	wait_object;
 
     DAT_COUNT		threshold;
     DAPL_EVD_COMPLETION	completion_type;
diff --git a/dapl/openib_common/cq.c b/dapl/openib_common/cq.c
index 74a5940..096167c 100644
--- a/dapl/openib_common/cq.c
+++ b/dapl/openib_common/cq.c
@@ -171,22 +171,36 @@ DAT_RETURN dapls_ib_get_async_event(IN ib_error_record_t * err_record,
  *	DAT_INSUFFICIENT_RESOURCES
  *
  */
+#if defined(_WIN32)
+
 DAT_RETURN
 dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,
 		  IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)
 {
-	struct ibv_comp_channel *channel = evd_ptr->cq_wait_obj_handle;
+	OVERLAPPED *overlap;
+	DAT_RETURN ret;
 
 	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
 		     "dapls_ib_cq_alloc: evd %p cqlen=%d \n", evd_ptr, *cqlen);
 
-	/* Call IB verbs to create CQ */
 	evd_ptr->ib_cq_handle = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,
-					      *cqlen, evd_ptr, channel, 0);
+					      *cqlen, evd_ptr, NULL, 0);
 
 	if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE)
 		return DAT_INSUFFICIENT_RESOURCES;
 
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     " cq_object_create: (%p)\n", evd_ptr);
+
+	overlap = &evd_ptr->ib_cq_handle->comp_entry.Overlap;
+	overlap->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+	if (!overlap->hEvent) {
+		ret = DAT_INSUFFICIENT_RESOURCES;
+		goto err;
+	}
+
+	overlap->hEvent = (HANDLE) ((ULONG_PTR) overlap->hEvent | 1);
+
 	/* arm cq for events */
 	dapls_set_cq_notify(ia_ptr, evd_ptr);
 
@@ -198,17 +212,20 @@ dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,
 		     evd_ptr->ib_cq_handle, *cqlen);
 
 	return DAT_SUCCESS;
+
+err:
+	ibv_destroy_cq(evd_ptr->ib_cq_handle);
+	return ret;
 }
 
 /*
- * dapl_ib_cq_resize
+ * dapls_ib_cq_free
  *
- * Alloc a CQ
+ * destroy a CQ
  *
  * Input:
  *	ia_handle		IA handle
  *	evd_ptr			pointer to EVD struct
- *	cqlen			minimum QLen
  *
  * Output:
  * 	none
@@ -218,50 +235,186 @@ dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,
  *	DAT_INVALID_PARAMETER
  *
  */
+DAT_RETURN dapls_ib_cq_free(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)
+{
+	DAT_EVENT event;
+	ib_work_completion_t wc;
+	HANDLE hevent;
+
+	if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {
+		/* pull off CQ and EVD entries and toss */
+		while (ibv_poll_cq(evd_ptr->ib_cq_handle, 1, &wc) == 1) ;
+		while (dapl_evd_dequeue(evd_ptr, &event) == DAT_SUCCESS) ;
+
+		hevent = evd_ptr->ib_cq_handle->comp_entry.Overlap.hEvent;
+		if (ibv_destroy_cq(evd_ptr->ib_cq_handle))
+			return (dapl_convert_errno(errno, "ibv_destroy_cq"));
+
+		CloseHandle(hevent);
+		evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
+	}
+	return DAT_SUCCESS;
+}
+
 DAT_RETURN
-dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,
-		   IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)
+dapls_evd_dto_wakeup(IN DAPL_EVD * evd_ptr)
 {
-	ib_cq_handle_t new_cq;
-	struct ibv_comp_channel *channel = evd_ptr->cq_wait_obj_handle;
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     " cq_object_wakeup: evd=%p\n", evd_ptr);
 
-	/* IB verbs DOES support resize. REDO THIS.
-	 * Try to re-create CQ
-	 * with new size. Can only be done if QP is not attached. 
-	 * destroy EBUSY == QP still attached.
-	 */
+	if (!SetEvent(evd_ptr->ib_cq_handle->comp_entry.Overlap.hEvent))
+		return DAT_INTERNAL_ERROR;
 
-	/* Call IB verbs to create CQ */
-	new_cq = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle, *cqlen,
-			       evd_ptr, channel, 0);
+	return DAT_SUCCESS;
+}
+
+DAT_RETURN
+dapls_evd_dto_wait(IN DAPL_EVD * evd_ptr, IN uint32_t timeout)
+{
+	int status;
+
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     " cq_object_wait: EVD %p time %d\n",
+		     evd_ptr, timeout);
+
+	status = WaitForSingleObject(evd_ptr->ib_cq_handle->
+				     comp_entry.Overlap.hEvent,
+				     timeout / 1000);
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     " cq_object_wait: EVD %p status 0x%x\n",
+		     evd_ptr, status);
+	if (status)
+		return DAT_TIMEOUT_EXPIRED;
 
-	if (new_cq == IB_INVALID_HANDLE)
+	InterlockedExchange(&evd_ptr->ib_cq_handle->comp_entry.Busy, 0);
+	return DAT_SUCCESS;
+}
+
+#else // WIN32
+
+DAT_RETURN
+dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,
+		  IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)
+{
+	struct ibv_comp_channel *channel;
+	DAT_RETURN ret;
+
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     "dapls_ib_cq_alloc: evd %p cqlen=%d \n", evd_ptr, *cqlen);
+
+	channel = ibv_create_comp_channel(ia_ptr->hca_ptr->ib_hca_handle);
+	if (!channel)
 		return DAT_INSUFFICIENT_RESOURCES;
 
-	/* destroy the original and replace if successful */
-	if (ibv_destroy_cq(evd_ptr->ib_cq_handle)) {
-		ibv_destroy_cq(new_cq);
-		return (dapl_convert_errno(errno, "resize_cq"));
-	}
+	evd_ptr->ib_cq_handle = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,
+					      *cqlen, evd_ptr, channel, 0);
 
-	/* update EVD with new cq handle and size */
-	evd_ptr->ib_cq_handle = new_cq;
-	*cqlen = new_cq->cqe;
+	if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE) {
+		ret = DAT_INSUFFICIENT_RESOURCES;
+		goto err;
+	}
 
 	/* arm cq for events */
 	dapls_set_cq_notify(ia_ptr, evd_ptr);
 
+	/* update with returned cq entry size */
+	*cqlen = evd_ptr->ib_cq_handle->cqe;
+
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     "dapls_ib_cq_alloc: new_cq %p cqlen=%d \n",
+		     evd_ptr->ib_cq_handle, *cqlen);
+
+	return DAT_SUCCESS;
+
+err:
+	ibv_destroy_comp_channel(channel);
+	return ret;
+}
+
+DAT_RETURN dapls_ib_cq_free(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)
+{
+	DAT_EVENT event;
+	ib_work_completion_t wc;
+	struct ibv_comp_channel *channel;
+
+	if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {
+		/* pull off CQ and EVD entries and toss */
+		while (ibv_poll_cq(evd_ptr->ib_cq_handle, 1, &wc) == 1) ;
+		while (dapl_evd_dequeue(evd_ptr, &event) == DAT_SUCCESS) ;
+
+		channel = evd_ptr->ib_cq_handle->channel;
+		if (ibv_destroy_cq(evd_ptr->ib_cq_handle))
+			return (dapl_convert_errno(errno, "ibv_destroy_cq"));
+
+		ibv_destroy_comp_channel(channel);
+		evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
+	}
+	return DAT_SUCCESS;
+}
+
+DAT_RETURN
+dapls_evd_dto_wakeup(IN DAPL_EVD * evd_ptr)
+{
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     " cq_object_wakeup: evd=%p\n", evd_ptr);
+
+	/* no wake up mechanism */
 	return DAT_SUCCESS;
 }
 
+DAT_RETURN
+dapls_evd_dto_wait(IN DAPL_EVD * evd_ptr, IN uint32_t timeout)
+{
+	struct ibv_comp_channel *channel = evd_ptr->ib_cq_handle->channel;
+	struct ibv_cq *ibv_cq = NULL;
+	void *context;
+	int status = 0;
+	int timeout_ms = -1;
+	struct pollfd cq_fd = {
+		.fd = channel->fd,
+		.events = POLLIN,
+		.revents = 0
+	};
+
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     " cq_object_wait: EVD %p time %d\n",
+		     evd_ptr, timeout);
+
+	/* uDAPL timeout values in usecs */
+	if (timeout != DAT_TIMEOUT_INFINITE)
+		timeout_ms = timeout / 1000;
+
+	status = poll(&cq_fd, 1, timeout_ms);
+
+	/* returned event */
+	if (status > 0) {
+		if (!ibv_get_cq_event(channel, &ibv_cq, &context)) {
+			ibv_ack_cq_events(ibv_cq, 1);
+		}
+		status = 0;
+
+		/* timeout */
+	} else if (status == 0)
+		status = ETIMEDOUT;
+
+	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
+		     " cq_object_wait: RET evd %p ibv_cq %p %s\n",
+		     evd_ptr, ibv_cq, strerror(errno));
+
+	return (dapl_convert_errno(status, "cq_wait_object_wait"));
+
+}
+#endif
+
 /*
- * dapls_ib_cq_free
+ * dapl_ib_cq_resize
  *
- * destroy a CQ
+ * Alloc a CQ
  *
  * Input:
  *	ia_handle		IA handle
  *	evd_ptr			pointer to EVD struct
+ *	cqlen			minimum QLen
  *
  * Output:
  * 	none
@@ -271,20 +424,27 @@ dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,
  *	DAT_INVALID_PARAMETER
  *
  */
-DAT_RETURN dapls_ib_cq_free(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)
+DAT_RETURN
+dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,
+		   IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)
 {
-	DAT_EVENT event;
-	ib_work_completion_t wc;
+	ib_cq_handle_t old_cq, new_cq;
+	DAT_RETURN ret;
 
-	if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {
-		/* pull off CQ and EVD entries and toss */
-		while (ibv_poll_cq(evd_ptr->ib_cq_handle, 1, &wc) == 1) ;
-		while (dapl_evd_dequeue(evd_ptr, &event) == DAT_SUCCESS) ;
-		if (ibv_destroy_cq(evd_ptr->ib_cq_handle))
-			return (dapl_convert_errno(errno, "ibv_destroy_cq"));
-		evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
-	}
+	old_cq = evd_ptr->ib_cq_handle;
+	ret = dapls_ib_cq_alloc(ia_ptr, evd_ptr, cqlen);
+	if (ret)
+		goto err;
+
+	new_cq = evd_ptr->ib_cq_handle;
+	evd_ptr->ib_cq_handle = old_cq;
+	dapls_ib_cq_free(ia_ptr, evd_ptr);
+	evd_ptr->ib_cq_handle = new_cq;
 	return DAT_SUCCESS;
+
+err:
+	evd_ptr->ib_cq_handle = old_cq;
+	return ret;
 }
 
 /*
@@ -369,119 +529,6 @@ DAT_RETURN dapls_ib_completion_poll(IN DAPL_HCA * hca_ptr,
 	return DAT_QUEUE_EMPTY;
 }
 
-/* NEW common wait objects for providers with direct CQ wait objects */
-DAT_RETURN
-dapls_ib_wait_object_create(IN DAPL_EVD * evd_ptr,
-			    IN ib_wait_obj_handle_t * p_cq_wait_obj_handle)
-{
-	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-		     " cq_object_create: (%p,%p)\n",
-		     evd_ptr, p_cq_wait_obj_handle);
-
-	/* set cq_wait object to evd_ptr */
-	*p_cq_wait_obj_handle =
-	    ibv_create_comp_channel(evd_ptr->header.owner_ia->hca_ptr->
-				    ib_hca_handle);
-
-	return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_ib_wait_object_destroy(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)
-{
-	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-		     " cq_object_destroy: wait_obj=%p\n", p_cq_wait_obj_handle);
-
-	ibv_destroy_comp_channel(p_cq_wait_obj_handle);
-
-	return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_ib_wait_object_wakeup(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)
-{
-	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-		     " cq_object_wakeup: wait_obj=%p\n", p_cq_wait_obj_handle);
-
-	/* no wake up mechanism */
-	return DAT_SUCCESS;
-}
-
-#if defined(_WIN32) || defined(_WIN64)
-DAT_RETURN
-dapls_ib_wait_object_wait(IN ib_wait_obj_handle_t p_cq_wait_obj_handle,
-			  IN uint32_t timeout)
-{
-	struct dapl_evd *evd_ptr;
-	struct ibv_cq *ibv_cq = NULL;
-	int status = 0;
-
-	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-		     " cq_object_wait: CQ channel %p time %d\n",
-		     p_cq_wait_obj_handle, timeout);
-
-	/* uDAPL timeout values in usecs */
-	p_cq_wait_obj_handle->comp_channel.Milliseconds = timeout / 1000;
-
-	/* returned event */
-	status = ibv_get_cq_event(p_cq_wait_obj_handle, &ibv_cq,
-				  (void *)&evd_ptr);
-	if (status == 0) {
-		ibv_ack_cq_events(ibv_cq, 1);
-	}
-
-	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-		     " cq_object_wait: RET evd %p ibv_cq %p %s\n",
-		     evd_ptr, ibv_cq, strerror(errno));
-
-	return (dapl_convert_errno(status, "cq_wait_object_wait"));
-}
-#else			//_WIN32 || _WIN64
-DAT_RETURN
-dapls_ib_wait_object_wait(IN ib_wait_obj_handle_t p_cq_wait_obj_handle,
-			  IN uint32_t timeout)
-{
-	struct dapl_evd *evd_ptr;
-	struct ibv_cq *ibv_cq = NULL;
-	int status = 0;
-	int timeout_ms = -1;
-	struct pollfd cq_fd = {
-		.fd = p_cq_wait_obj_handle->fd,
-		.events = POLLIN,
-		.revents = 0
-	};
-
-	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-		     " cq_object_wait: CQ channel %p time %d\n",
-		     p_cq_wait_obj_handle, timeout);
-
-	/* uDAPL timeout values in usecs */
-	if (timeout != DAT_TIMEOUT_INFINITE)
-		timeout_ms = timeout / 1000;
-
-	status = poll(&cq_fd, 1, timeout_ms);
-
-	/* returned event */
-	if (status > 0) {
-		if (!ibv_get_cq_event(p_cq_wait_obj_handle,
-				      &ibv_cq, (void *)&evd_ptr)) {
-			ibv_ack_cq_events(ibv_cq, 1);
-		}
-		status = 0;
-
-		/* timeout */
-	} else if (status == 0)
-		status = ETIMEDOUT;
-
-	dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-		     " cq_object_wait: RET evd %p ibv_cq %p %s\n",
-		     evd_ptr, ibv_cq, strerror(errno));
-
-	return (dapl_convert_errno(status, "cq_wait_object_wait"));
-
-}
-#endif				//_WIN32 || _WIN64
-
 /*
  * Local variables:
  *  c-indent-level: 4
diff --git a/dapl/openib_common/dapl_ib_common.h b/dapl/openib_common/dapl_ib_common.h
index b61e50e..0b417b8 100644
--- a/dapl/openib_common/dapl_ib_common.h
+++ b/dapl/openib_common/dapl_ib_common.h
@@ -107,9 +107,6 @@ typedef int			ib_bool_t;
 typedef union ibv_gid		GID;
 typedef char			*IB_HCA_NAME;
 typedef uint16_t		ib_hca_port_t;
-typedef uint32_t		ib_comp_handle_t;
-
-typedef struct ibv_comp_channel *ib_wait_obj_handle_t;
 
 /* Definitions */
 #define IB_INVALID_HANDLE	NULL
diff --git a/dapl/openib_common/qp.c b/dapl/openib_common/qp.c
index 9fb7c96..9aa0594 100644
--- a/dapl/openib_common/qp.c
+++ b/dapl/openib_common/qp.c
@@ -77,15 +77,20 @@ dapls_ib_qp_alloc(IN DAPL_IA * ia_ptr,
 	else if (!ia_ptr->hca_ptr->ib_trans.ib_cq_empty)
 		rcv_cq = ia_ptr->hca_ptr->ib_trans.ib_cq_empty;
 	else {
-		struct ibv_comp_channel *channel = 
-				rcv_evd->cq_wait_obj_handle;
+		struct ibv_comp_channel *channel;
+
+		channel = ibv_create_comp_channel(ia_ptr->hca_ptr->ib_hca_handle);
+		if (!channel)
+			return (dapl_convert_errno(ENOMEM, "create_cq"));
 		  
 		/* Call IB verbs to create CQ */
 		rcv_cq = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,
 				       0, NULL, channel, 0);
 
-		if (rcv_cq == IB_INVALID_HANDLE)
+		if (rcv_cq == IB_INVALID_HANDLE) {
+			ibv_destroy_comp_channel(channel);
 			return (dapl_convert_errno(ENOMEM, "create_cq"));
+		}
 
 		ia_ptr->hca_ptr->ib_trans.ib_cq_empty = rcv_cq;
 	}
diff --git a/dapl/udapl/dapl_evd_set_unwaitable.c b/dapl/udapl/dapl_evd_set_unwaitable.c
index bf41662..718e433 100644
--- a/dapl/udapl/dapl_evd_set_unwaitable.c
+++ b/dapl/udapl/dapl_evd_set_unwaitable.c
@@ -80,12 +80,9 @@ DAT_RETURN DAT_API dapl_evd_set_unwaitable(IN DAT_EVD_HANDLE evd_handle)
 	 * thing.
 	 */
 	if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED) {
-#ifdef CQ_WAIT_OBJECT
-		if (evd_ptr->cq_wait_obj_handle)
-			dapls_ib_wait_object_wakeup(evd_ptr->
-						    cq_wait_obj_handle);
+		if (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG))
+			dapls_evd_dto_wakeup(evd_ptr);
 		else
-#endif
 			dapl_os_wait_object_wakeup(&evd_ptr->wait_object);
 	}
       bail:
diff --git a/dapl/udapl/dapl_evd_wait.c b/dapl/udapl/dapl_evd_wait.c
index 8d82d63..2e501ae 100644
--- a/dapl/udapl/dapl_evd_wait.c
+++ b/dapl/udapl/dapl_evd_wait.c
@@ -182,8 +182,7 @@ DAT_RETURN DAT_API dapl_evd_wait(IN DAT_EVD_HANDLE evd_handle,
 		 * a DTO_EVD or RMR_BIND_EVD
 		 */
 		if ((!notify_requested) &&
-		    ((evd_ptr->evd_flags & DAT_EVD_DTO_FLAG) ||
-		     (evd_ptr->evd_flags & DAT_EVD_RMR_BIND_FLAG))) {
+		    (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG))) {
 			dat_status =
 			    dapls_ib_completion_notify(evd_ptr->header.
 						       owner_ia->hca_ptr->
@@ -216,17 +215,11 @@ DAT_RETURN DAT_API dapl_evd_wait(IN DAT_EVD_HANDLE evd_handle,
 		DAPL_CNTR(evd_ptr, DCNT_EVD_WAIT_BLOCKED);
 		dapl_os_unlock(&evd_ptr->header.lock);
 
-#ifdef CQ_WAIT_OBJECT
-		if (evd_ptr->cq_wait_obj_handle)
-			dat_status =
-			    dapls_ib_wait_object_wait(evd_ptr->
-						      cq_wait_obj_handle,
-						      time_out);
-		else
-#endif
-			dat_status =
-			    dapl_os_wait_object_wait(&evd_ptr->wait_object,
-						     time_out);
+		if (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) {
+			dat_status = dapls_evd_dto_wait(evd_ptr, time_out);
+		} else {
+			dat_status = dapl_os_wait_object_wait(&evd_ptr->wait_object, time_out);
+		}
 
 		dapl_os_lock(&evd_ptr->header.lock);
 
-- 
1.5.2.5





More information about the general mailing list