[ofw] [PATCH 5/12] cq: allow polling with an array of wc's

Sean Hefty sean.hefty at intel.com
Mon Jul 21 09:14:45 PDT 2008


Allow polling for a list of work completions using an array of
completion structures, rather than a linked list.  This avoids needing
to walk the list to link the structures together before calling poll,
which is a fast path operation.

A new completion structure is added that provides the qp_context
associated with a completion.  This avoids changes to the existing
ULPs, while taking advantage of the underlying UVP capabilities.
Providing the qp_context is useful when dealing with SRQ.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/hw/mlx4/user/hca/cq.c branches\winverbs/hw/mlx4/user/hca/cq.c
--- trunk/hw/mlx4/user/hca/cq.c	2008-06-03 20:27:49.916625000 -0700
+++ branches\winverbs/hw/mlx4/user/hca/cq.c	2008-06-03 20:33:53.916625000 -0700
@@ -343,8 +343,31 @@ static int mlx4_poll_one(struct mlx4_cq 
 	return CQ_OK;
 }
 
+int mlx4_poll_cq_array(const void* h_cq,
+			const int num_entries, uvp_wc_t* const wc)
+{
+	struct mlx4_cq *cq = to_mcq((struct ibv_cq *)/*Ptr64ToPtr(*/ h_cq /*)*/);
+	struct mlx4_qp *qp;
+	int ne;
+	int err = CQ_EMPTY;
+
+	pthread_spin_lock(&cq->lock);
+ 	for (ne = 0; ne < num_entries; ne++) {
+		err = mlx4_poll_one(cq, &qp, (ib_wc_t *) &wc[ne]);
+		if (err != CQ_OK)
+			break;
+		wc[ne].qp_context = qp->ibv_qp.qp_context;
+	}
+
+	if (ne)
+		update_cons_index(cq);
+	pthread_spin_unlock(&cq->lock);
+
+	return (err == CQ_OK || err == CQ_EMPTY) ? ne : err;
+}
+
 ib_api_status_t
-mlx4_poll_cq(
+mlx4_poll_cq_list(
	IN		const	void*						h_cq,
	IN	OUT			ib_wc_t**	const			pp_free_wclist,
		OUT			ib_wc_t**	const			pp_done_wclist)
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/hw/mlx4/user/hca/mlx4.c branches\winverbs/hw/mlx4/user/hca/mlx4.c
--- trunk/hw/mlx4/user/hca/mlx4.c	2008-06-03 20:33:17.791625000 -0700
+++ branches\winverbs/hw/mlx4/user/hca/mlx4.c	2008-06-03 20:33:53.932250000 -0700
@@ -289,14 +289,15 @@ uvp_get_interface (
 	/*
 	 * OS bypass (send, receive, poll/notify cq)
 	 */
-	p_uvp->post_send	= mlx4_post_send;
-	p_uvp->post_recv	= mlx4_post_recv;
+	p_uvp->post_send		= mlx4_post_send;
+	p_uvp->post_recv		= mlx4_post_recv;
 	p_uvp->post_srq_recv	= mlx4_post_srq_recv;
-	p_uvp->poll_cq		= mlx4_poll_cq;
-	p_uvp->rearm_cq		= mlx4_arm_cq;
-	p_uvp->rearm_n_cq	= NULL; /* __enable_ncomp_cq_notify: Not implemented */;
-	p_uvp->peek_cq		= NULL; /* __peek_cq: Not implemented */
-	p_uvp->bind_mw		= NULL; /* __bind_mw: Not implemented */
+	p_uvp->poll_cq			= mlx4_poll_cq_list;
+	p_uvp->poll_cq_array	= mlx4_poll_cq_array;
+	p_uvp->rearm_cq			= mlx4_arm_cq;
+	p_uvp->rearm_n_cq		= NULL;
+	p_uvp->peek_cq			= NULL;
+	p_uvp->bind_mw			= NULL;
 
 #ifdef XRC_SUPPORT
 	/*
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/hw/mlx4/user/hca/mlx4.h branches\winverbs/hw/mlx4/user/hca/mlx4.h
--- trunk/hw/mlx4/user/hca/mlx4.h	2008-06-03 20:27:49.994750000 -0700
+++ branches\winverbs/hw/mlx4/user/hca/mlx4.h	2008-06-03 20:33:53.947875000 -0700
@@ -305,7 +305,9 @@ void mlx4_free_buf(struct mlx4_buf *buf)
 uint32_t *mlx4_alloc_db(struct mlx4_context *context, enum mlx4_db_type type);
 void mlx4_free_db(struct mlx4_context *context, enum mlx4_db_type type, uint32_t *db);
 
-ib_api_status_t mlx4_poll_cq(const void* h_cq,
+int mlx4_poll_cq_array(const void* h_cq,
+			const int num_entries, uvp_wc_t* const wc);
+ib_api_status_t mlx4_poll_cq_list(const void* h_cq,
 			ib_wc_t** const pp_free_wclist,
 			ib_wc_t** const pp_done_wclist);
 ib_api_status_t mlx4_arm_cq(const	void* h_cq, const	boolean_t solicited);
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/hw/mthca/user/mlnx_ual_osbypass.c
branches\winverbs/hw/mthca/user/mlnx_ual_osbypass.c
--- trunk/hw/mthca/user/mlnx_ual_osbypass.c	2008-06-03 20:27:50.026000000 -0700
+++ branches\winverbs/hw/mthca/user/mlnx_ual_osbypass.c	2008-06-03 20:33:53.963500000 -0700
@@ -176,6 +176,25 @@ err_invalid_params:
 }
 
 
+static int
+__poll_cq_array (
+	IN		const	void*						h_cq,
+	IN		const	int							num_entries,
+	IN	OUT			uvp_wc_t*	const			wc )
+{
+	int ne;
+	struct mthca_cq *cq = (struct mthca_cq *) h_cq;
+
+	UVP_ENTER(UVP_DBG_CQ);
+	CL_ASSERT (cq);
+
+	ne = cq->ibv_cq.context->ops.poll_cq(&cq->ibv_cq, num_entries, wc);
+
+	UVP_EXIT(UVP_DBG_CQ);
+	return ne;
+}
+
+
 static ib_api_status_t
 __enable_cq_notify (
 	IN		const	void*		FUNC_PTR64			h_cq,
@@ -219,28 +238,16 @@ void
 mlnx_get_osbypass_interface (
     IN OUT	uvp_interface_t		*p_uvp )
 {
-
     CL_ASSERT(p_uvp);
 
-    /*
-     * Work Request Processing Verbs
-     * Should the types be same as Verbs?
-     */
     p_uvp->post_send = __post_send;
     p_uvp->post_recv = __post_recv;
     p_uvp->post_srq_recv = __post_srq_recv;
-
-    /*
-     * Completion Processing and 
-     * Completion Notification Request Verbs.
-     * Should the types be same as Verbs?
-     */
     p_uvp->poll_cq  = __poll_cq;
     p_uvp->rearm_cq = __enable_cq_notify;
-    p_uvp->rearm_n_cq = NULL; /* __enable_ncomp_cq_notify: Not implemented */;
-    p_uvp->peek_cq  = NULL; /* __peek_cq: Not implemented */
-
-    /* Memory window bind */
-    p_uvp->bind_mw = NULL; /* __bind_mw: Not implemented */
+    p_uvp->rearm_n_cq = NULL;
+    p_uvp->peek_cq  = NULL;
+    p_uvp->bind_mw = NULL;
+	p_uvp->poll_cq_array = __poll_cq_array;
 }
 
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/hw/mthca/user/mlnx_uvp.h branches\winverbs/hw/mthca/user/mlnx_uvp.h
--- trunk/hw/mthca/user/mlnx_uvp.h	2008-06-03 20:27:50.041625000 -0700
+++ branches\winverbs/hw/mthca/user/mlnx_uvp.h	2008-06-03 20:33:53.963500000 -0700
@@ -277,7 +277,7 @@ struct ibv_cq *mthca_create_cq_pre(struc
 struct ibv_cq *mthca_create_cq_post(struct ibv_context *context, 
 				 struct ibv_create_cq_resp *resp);
 int mthca_destroy_cq(struct ibv_cq *cq);
-int mthca_poll_cq(struct ibv_cq *cq, int ne, struct _ib_wc *wc);
+int mthca_poll_cq(struct ibv_cq *cq, int ne, struct _uvp_wc *wc);
 int mthca_poll_cq_list(struct ibv_cq *ibcq, 
 	struct _ib_wc** const pp_free_wclist,
 	struct _ib_wc** const pp_done_wclist );
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/hw/mthca/user/mlnx_uvp_cq.c branches\winverbs/hw/mthca/user/mlnx_uvp_cq.c
--- trunk/hw/mthca/user/mlnx_uvp_cq.c	2008-06-03 20:27:50.072875000 -0700
+++ branches\winverbs/hw/mthca/user/mlnx_uvp_cq.c	2008-06-03 20:33:53.979125000 -0700
@@ -37,6 +37,7 @@
 #include <opcode.h>
 #include "mlnx_uvp.h"
 #include "mlnx_uvp_doorbell.h"
+#include <iba\ib_uvp.h>
 
 #if defined(EVENT_TRACING)
 #include "mlnx_uvp_cq.tmh"
@@ -442,7 +443,7 @@ out:
 	return err;
 }
 
-int mthca_poll_cq(struct ibv_cq *ibcq, int num_entries, struct _ib_wc *entry)
+int mthca_poll_cq(struct ibv_cq *ibcq, int num_entries, struct _uvp_wc *entry)
 {
 	struct mthca_cq *cq = to_mcq(ibcq);
 	struct mthca_qp *qp = NULL;
@@ -453,9 +454,10 @@ int mthca_poll_cq(struct ibv_cq *ibcq, i
 	cl_spinlock_acquire(&cq->lock);
 
 	for (npolled = 0; npolled < num_entries; ++npolled) {
-		err = mthca_poll_one(cq, &qp, &freed, entry + npolled);
+		err = mthca_poll_one(cq, &qp, &freed, (struct _ib_wc *) (entry + npolled));
 		if (err)
 			break;
+		entry[npolled].qp_context = qp->ibv_qp.qp_context;
 	}
 
 	if (freed) {
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/hw/mthca/user/mlnx_uvp_verbs.h
branches\winverbs/hw/mthca/user/mlnx_uvp_verbs.h
--- trunk/hw/mthca/user/mlnx_uvp_verbs.h	2008-06-03 20:27:50.088500000 -0700
+++ branches\winverbs/hw/mthca/user/mlnx_uvp_verbs.h	2008-06-03 20:33:53.994750000 -0700
@@ -446,7 +446,7 @@ struct ibv_context_ops {
 			       struct ibv_create_cq *req);
 	struct ibv_cq * (*create_cq_post)(struct ibv_context *context, 
 			       struct ibv_create_cq_resp *resp);
-	int			(*poll_cq)(struct ibv_cq *cq, int num_entries, struct _ib_wc *wc);
+	int			(*poll_cq)(struct ibv_cq *cq, int num_entries, struct _uvp_wc *wc);
 	int 			(*poll_cq_list)( struct ibv_cq *ibcq, 
 		struct _ib_wc** const 			pp_free_wclist,
 		struct _ib_wc** const 			pp_done_wclist );
diff -up -r -X trunk\docs\dontdiff.txt -I '\$Id:' trunk/inc/user/iba/ib_uvp.h branches\winverbs/inc/user/iba/ib_uvp.h
--- trunk/inc/user/iba/ib_uvp.h	2008-06-03 20:33:17.838500000 -0700
+++ branches\winverbs/inc/user/iba/ib_uvp.h	2008-06-03 20:33:54.010375000 -0700
 * NAME
@@ -3011,6 +3010,51 @@ typedef ib_api_status_t
 
 /********/
 
+/*
+ * Define uvp_wc_t so that we can cast directly to ib_wc_t.
+ */
+typedef struct _uvp_wc
+{
+	void*					qp_context;
+	/* If pointer size is 32-bits, then compiler will pad before uint64_t */
+	uint64_t				wr_id;
+	ib_wc_type_t			wc_type;
+
+	uint32_t				length;
+	uint64_t				vendor_specific;
+	ib_wc_status_t			status;
+
+	union _uvp_wc_recv
+	{
+		struct _uvp_wc_conn
+		{
+			ib_recv_opt_t	recv_opt;
+			ib_net32_t		immediate_data;
+
+		}	conn;
+
+		struct _uvp_wc_ud
+		{
+			ib_recv_opt_t	recv_opt;
+			ib_net32_t		immediate_data;
+			ib_net32_t		remote_qp;
+			uint16_t		pkey_index;
+			ib_net16_t		remote_lid;
+			uint8_t			remote_sl;
+			uint8_t			path_bits;
+
+		}	ud;
+	}	recv;
+}	uvp_wc_t;
+
+typedef int
+(AL_API *uvp_poll_cq_array) (
+	IN		const	void*						h_cq,
+	IN		const	int							num_entries,
+	IN	OUT			uvp_wc_t*	const			wcs);
+
+/********/
+
 /****f* user-mode Verbs/uvp_rearm_cq
 * NAME
 *	uvp_rearm_cq -- Invoke the Completion handler, on next entry added.
@@ -3455,6 +3499,7 @@ typedef struct _uvp_interface
 	uvp_nd_modify_qp_t			nd_modify_qp;
 	uvp_nd_get_qp_state_t		nd_get_qp_state;
 	uvp_wv_pre_create_qp		wv_pre_create_qp;
+	uvp_poll_cq_array			poll_cq_array;
 
 } uvp_interface_t;
 





More information about the ofw mailing list