[ofw] [PATCH 5/9] cq: allow polling with an array of wc's
Sean Hefty
sean.hefty at intel.com
Wed Jun 25 16:54:01 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 * FUNC_PTR64 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* FUNC_PTR64 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 * FUNC_PTR64 h_cq,
+int mlx4_poll_cq_array(const void * FUNC_PTR64 h_cq,
+ const int num_entries, uvp_wc_t* const wc);
+ib_api_status_t mlx4_poll_cq_list(const void * FUNC_PTR64 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 * FUNC_PTR64 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