Skip to content

Commit

Permalink
libxscale: Add support for qp management
Browse files Browse the repository at this point in the history
This patch adds support for following qp management verbs:
1. create_qp
2. query_qp
3. modify_qp
4. destroy_qp

Signed-off-by: Tian Xin <[email protected]>
Signed-off-by: Wei Honggang <[email protected]>
Signed-off-by: Zhao Qianwei <[email protected]>
Signed-off-by: Li Qiang <[email protected]>
Signed-off-by: Yan Lei <[email protected]>
  • Loading branch information
tianx666 committed Sep 26, 2024
1 parent 5ab0c72 commit 4eaa669
Show file tree
Hide file tree
Showing 5 changed files with 772 additions and 10 deletions.
1 change: 1 addition & 0 deletions providers/xscale/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ rdma_provider(xscale
xscale.c
verbs.c
cq.c
qp.c
xsc_hsi.c
buf.c
)
72 changes: 62 additions & 10 deletions providers/xscale/cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,6 @@ static inline u8 xsc_get_cqe_opcode(struct xsc_context *ctx,
return xsc_msg_opcode[msg_opcode][cqe->type][cqe->with_immdt];
}

struct xsc_qp *xsc_find_qp(struct xsc_context *ctx, u32 qpn)
{
int tind = qpn >> XSC_QP_TABLE_SHIFT;

if (ctx->qp_table[tind].refcnt)
return ctx->qp_table[tind].table[qpn & XSC_QP_TABLE_MASK];
else
return NULL;
}

static inline int get_qp_ctx(struct xsc_context *xctx,
struct xsc_resource **cur_rsc,
u32 qpn) ALWAYS_INLINE;
Expand Down Expand Up @@ -519,3 +509,65 @@ void xsc_free_cq_buf(struct xsc_context *ctx, struct xsc_buf *buf)
{
return xsc_free_buf(buf);
}

void __xsc_cq_clean(struct xsc_cq *cq, u32 qpn)
{
u32 prod_index;
int nfreed = 0;
void *cqe, *dest;

if (!cq || cq->flags & XSC_CQ_FLAGS_DV_OWNED)
return;
xsc_dbg(to_xctx(cq->verbs_cq.cq_ex.context)->dbg_fp, XSC_DBG_CQ, "\n");

/*
* First we need to find the current producer index, so we
* know where to start cleaning from. It doesn't matter if HW
* adds new entries after this loop -- the QP we're worried
* about is already in RESET, so the new entries won't come
* from our QP and therefore don't need to be checked.
*/
for (prod_index = cq->cons_index; get_sw_cqe(cq, prod_index);
++prod_index)
if (prod_index == cq->cons_index + cq->verbs_cq.cq_ex.cqe)
break;

/*
* Now sweep backwards through the CQ, removing CQ entries
* that match our QP by copying older entries on top of them.
*/
while ((int)(--prod_index) - (int)cq->cons_index >= 0) {
u16 qp_id_combined;
u32 qp_id;

cqe = get_cqe(cq, prod_index & (cq->verbs_cq.cq_ex.cqe - 1));
qp_id_combined = __le16_to_cpu(*(u16 *)((void *)cqe + 1));
qp_id = qp_id_combined & 0x7fff;
if (qpn == qp_id) {
++nfreed;
} else if (nfreed) {
dest = get_cqe(cq,
(prod_index + nfreed) &
(cq->verbs_cq.cq_ex.cqe - 1));
memcpy(dest, cqe, cq->cqe_sz);
}
}

if (nfreed) {
cq->cons_index += nfreed;
/*
* Make sure update of buffer contents is done before
* updating consumer index.
*/
udma_to_device_barrier();
update_cons_index(cq);
}
}

void xsc_cq_clean(struct xsc_cq *cq, uint32_t qpn)
{
xsc_spin_lock(&cq->lock);
__xsc_cq_clean(cq, qpn);
xsc_spin_unlock(&cq->lock);
}

110 changes: 110 additions & 0 deletions providers/xscale/qp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021 - 2022, Shanghai Yunsilicon Technology Co., Ltd.
* All rights reserved.
*/

#include <config.h>

#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <util/compiler.h>

#include "xscale.h"
#include "xsc_hsi.h"

struct xsc_qp *xsc_find_qp(struct xsc_context *ctx, uint32_t qpn)
{
int tind = qpn >> XSC_QP_TABLE_SHIFT;

if (ctx->qp_table[tind].refcnt)
return ctx->qp_table[tind].table[qpn & XSC_QP_TABLE_MASK];
else
return NULL;
}

int xsc_store_qp(struct xsc_context *ctx, uint32_t qpn, struct xsc_qp *qp)
{
int tind = qpn >> XSC_QP_TABLE_SHIFT;

if (!ctx->qp_table[tind].refcnt) {
ctx->qp_table[tind].table =
calloc(XSC_QP_TABLE_MASK + 1, sizeof(struct xsc_qp *));
if (!ctx->qp_table[tind].table)
return -1;
}

++ctx->qp_table[tind].refcnt;
ctx->qp_table[tind].table[qpn & XSC_QP_TABLE_MASK] = qp;
return 0;
}

void xsc_clear_qp(struct xsc_context *ctx, uint32_t qpn)
{
int tind = qpn >> XSC_QP_TABLE_SHIFT;

if (!--ctx->qp_table[tind].refcnt)
free(ctx->qp_table[tind].table);
else
ctx->qp_table[tind].table[qpn & XSC_QP_TABLE_MASK] = NULL;
}

int xsc_err_state_qp(struct ibv_qp *qp, enum ibv_qp_state cur_state,
enum ibv_qp_state state)
{
struct xsc_err_state_qp_node *tmp, *err_rq_node, *err_sq_node;
struct xsc_qp *xqp = to_xqp(qp);
int ret = 0;

xsc_dbg(to_xctx(qp->context)->dbg_fp, XSC_DBG_QP,
"modify qp: qpid %d, cur_qp_state %d, qp_state %d\n",
xqp->rsc.rsn, cur_state, state);
if (cur_state == IBV_QPS_ERR && state != IBV_QPS_ERR) {
if (qp->recv_cq) {
list_for_each_safe(&to_xcq(qp->recv_cq)->err_state_qp_list,
err_rq_node, tmp, entry) {
if (err_rq_node->qp_id == xqp->rsc.rsn) {
list_del(&err_rq_node->entry);
free(err_rq_node);
}
}
}

if (qp->send_cq) {
list_for_each_safe(&to_xcq(qp->send_cq)->err_state_qp_list,
err_sq_node, tmp, entry) {
if (err_sq_node->qp_id == xqp->rsc.rsn) {
list_del(&err_sq_node->entry);
free(err_sq_node);
}
}
}
return ret;
}

if (cur_state != IBV_QPS_ERR && state == IBV_QPS_ERR) {
if (qp->recv_cq) {
err_rq_node = calloc(1, sizeof(*err_rq_node));
if (!err_rq_node)
return ENOMEM;
err_rq_node->qp_id = xqp->rsc.rsn;
err_rq_node->is_sq = false;
list_add_tail(&to_xcq(qp->recv_cq)->err_state_qp_list,
&err_rq_node->entry);
}

if (qp->send_cq) {
err_sq_node = calloc(1, sizeof(*err_sq_node));
if (!err_sq_node)
return ENOMEM;
err_sq_node->qp_id = xqp->rsc.rsn;
err_sq_node->is_sq = true;
list_add_tail(&to_xcq(qp->send_cq)->err_state_qp_list,
&err_sq_node->entry);
}
}
return ret;
}
Loading

0 comments on commit 4eaa669

Please sign in to comment.