[ofw] [RFC] [PATCH 11/12] winverbs\uvp:add poll_cq_array() to interface
Sean Hefty
sean.hefty at intel.com
Fri Mar 14 23:11:58 PDT 2008
Add a new call to the UVP: poll_cq_array(). This exports functionality
in the existing mellanox provider (poll_cq). It allows the user to
pass in an array of work completions, versus the linked-list API exposed
by IBAL.
This call aligns with the WinVerbs API, avoids the memory dereference
associated with walking a completion list, and returns a user's qp_context
information with the work completion. This latter is useful for processing
receive completions when a shared receive queue is used.
The call is added to the end of the uvp_interface_t, which should preserve
binary compatibility with existing applications. A new work completion
structure is defined that can be cast to the existing ib_wc_t completion
structure. This is done to reduce the changes required of the Mellanox
UVP.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
The definition of struct uvp_wc was a compromise between minimizing code
changes and exporting the needed qp_context information for winverbs. It
could be viewed as being really clever or really dumb...
Index: hw/mthca/user/mlnx_ual_osbypass.c
===================================================================
--- hw/mthca/user/mlnx_ual_osbypass.c (revision 960)
+++ hw/mthca/user/mlnx_ual_osbypass.c (working copy)
@@ -176,6 +176,25 @@
}
+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* __ptr64 h_cq,
@@ -236,6 +255,7 @@
* Should the types be same as Verbs?
*/
p_uvp->poll_cq = __poll_cq;
+ p_uvp->poll_cq_array = __poll_cq_array;
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 */
Index: hw/mthca/user/mlnx_uvp.h
===================================================================
--- hw/mthca/user/mlnx_uvp.h (revision 960)
+++ hw/mthca/user/mlnx_uvp.h (working copy)
@@ -277,7 +277,7 @@
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 );
Index: hw/mthca/user/mlnx_uvp_cq.c
===================================================================
--- hw/mthca/user/mlnx_uvp_cq.c (revision 960)
+++ hw/mthca/user/mlnx_uvp_cq.c (working copy)
@@ -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 @@
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 @@
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.context;
}
if (freed) {
Index: hw/mthca/user/mlnx_uvp_verbs.h
===================================================================
--- hw/mthca/user/mlnx_uvp_verbs.h (revision 960)
+++ hw/mthca/user/mlnx_uvp_verbs.h (working copy)
@@ -446,7 +446,7 @@
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 );
Index: inc/user/iba/ib_uvp.h
===================================================================
--- inc/user/iba/ib_uvp.h (revision 960)
+++ inc/user/iba/ib_uvp.h (working copy)
@@ -2992,6 +2992,53 @@
/********/
+/*
+ * Define uvp_wc_t so that we can cast directly to ib_wc_t.
+ *
+ * This allows support for WinVerbs CQ::Poll() with minimal changes to the UVP.
+ */
+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;
+ ib_wc_status_t status;
+ uint64_t vendor_specific;
+
+ 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 wc );
+
+/********/
+
/****f* user-mode Verbs/uvp_rearm_cq
* NAME
* uvp_rearm_cq -- Invoke the Completion handler, on next entry added.
@@ -3435,6 +3482,8 @@
*/
uvp_nd_modify_qp_t nd_modify_qp;
uvp_nd_get_qp_state_t nd_get_qp_state;
+
+ uvp_poll_cq_array poll_cq_array;
} uvp_interface_t;
More information about the ofw
mailing list