From patchwork Fri Jul 27 07:41:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixian Liu X-Patchwork-Id: 10546717 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 89EECA635 for ; Fri, 27 Jul 2018 07:43:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7E7EA2B1F2 for ; Fri, 27 Jul 2018 07:43:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 72A952B20B; Fri, 27 Jul 2018 07:43:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C68BE2B1F2 for ; Fri, 27 Jul 2018 07:43:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729493AbeG0JEG (ORCPT ); Fri, 27 Jul 2018 05:04:06 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46232 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729492AbeG0JEG (ORCPT ); Fri, 27 Jul 2018 05:04:06 -0400 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 21D64C6084142; Fri, 27 Jul 2018 15:43:26 +0800 (CST) Received: from localhost.localdomain (10.67.212.132) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.382.0; Fri, 27 Jul 2018 15:43:23 +0800 From: Yixian Liu To: , CC: , Subject: [PATCH v3 rdma-core 2/2] libhns: Support flush cqe for hip08 in user space Date: Fri, 27 Jul 2018 15:41:53 +0800 Message-ID: <1532677313-40721-3-git-send-email-liuyixian@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1532677313-40721-1-git-send-email-liuyixian@huawei.com> References: <1532677313-40721-1-git-send-email-liuyixian@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.132] X-CFilter-Loop: Reflected Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The cqe should be flushed error completion status if an related error is detected while poll cqe, post send or post recv. Record doorbell is used to notify the head pointer of sq and rq to the kernel. Signed-off-by: Yixian Liu --- v1->v2: 1. Remove unnecessary prints. --- --- providers/hns/hns_roce_u.h | 1 + providers/hns/hns_roce_u_hw_v2.c | 51 ++++++++++++++++++++++++++++++++++++++++ providers/hns/hns_roce_u_hw_v2.h | 1 + providers/hns/hns_roce_u_verbs.c | 22 ++++++++++++++--- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h index 8426569..2b2070f 100644 --- a/providers/hns/hns_roce_u.h +++ b/providers/hns/hns_roce_u.h @@ -211,6 +211,7 @@ struct hns_roce_qp { struct hns_roce_wq sq; struct hns_roce_wq rq; uint32_t *rdb; + uint32_t *sdb; struct hns_roce_sge_ex sge; unsigned int next_sge; int port_num; diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c index ca59011..9a1bd49 100644 --- a/providers/hns/hns_roce_u_hw_v2.c +++ b/providers/hns/hns_roce_u_hw_v2.c @@ -237,6 +237,9 @@ static void hns_roce_v2_clear_qp(struct hns_roce_context *ctx, uint32_t qpn) ctx->qp_table[tind].table[qpn & ctx->qp_table_mask] = NULL; } +static int hns_roce_u_v2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, + int attr_mask); + static int hns_roce_v2_poll_one(struct hns_roce_cq *cq, struct hns_roce_qp **cur_qp, struct ibv_wc *wc) { @@ -248,6 +251,9 @@ static int hns_roce_v2_poll_one(struct hns_roce_cq *cq, struct hns_roce_v2_cqe *cqe = NULL; struct hns_roce_rinl_sge *sge_list; uint32_t opcode; + struct ibv_qp_attr attr; + int attr_mask; + int ret; /* According to CI, find the relative cqe */ cqe = next_cqe_sw_v2(cq); @@ -314,6 +320,17 @@ static int hns_roce_v2_poll_one(struct hns_roce_cq *cq, if (roce_get_field(cqe->byte_4, CQE_BYTE_4_STATUS_M, CQE_BYTE_4_STATUS_S) != HNS_ROCE_V2_CQE_SUCCESS) { hns_roce_v2_handle_error_cqe(cqe, wc); + + /* flush cqe */ + if ((wc->status != IBV_WC_SUCCESS) && + (wc->status != IBV_WC_WR_FLUSH_ERR)) { + attr_mask = IBV_QP_STATE; + attr.qp_state = IBV_QPS_ERR; + ret = hns_roce_u_v2_modify_qp(&(*cur_qp)->ibv_qp, + &attr, attr_mask); + if (ret) + return ret; + } return V2_CQ_OK; } @@ -533,6 +550,8 @@ static int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr, struct hns_roce_context *ctx = to_hr_ctx(ibvqp->context); struct hns_roce_rc_sq_wqe *rc_sq_wqe; struct hns_roce_v2_wqe_data_seg *dseg; + struct ibv_qp_attr attr; + int attr_mask; pthread_spin_lock(&qp->sq.lock); @@ -760,7 +779,22 @@ out: hns_roce_update_sq_db(ctx, qp->ibv_qp.qp_num, qp->sl, qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1)); + if (qp->flags & HNS_ROCE_SUPPORT_SQ_RECORD_DB) + *(qp->sdb) = qp->sq.head & 0xffff; + qp->next_sge = ind_sge; + + if (ibvqp->state == IBV_QPS_ERR) { + attr_mask = IBV_QP_STATE; + attr.qp_state = IBV_QPS_ERR; + + ret = hns_roce_u_v2_modify_qp(ibvqp, &attr, attr_mask); + if (ret) { + pthread_spin_unlock(&qp->sq.lock); + *bad_wr = wr; + return ret; + } + } } pthread_spin_unlock(&qp->sq.lock); @@ -778,6 +812,8 @@ static int hns_roce_u_v2_post_recv(struct ibv_qp *ibvqp, struct ibv_recv_wr *wr, struct hns_roce_context *ctx = to_hr_ctx(ibvqp->context); struct hns_roce_v2_wqe_data_seg *dseg; struct hns_roce_rinl_sge *sge_list; + struct ibv_qp_attr attr; + int attr_mask; void *wqe; int i; @@ -848,6 +884,18 @@ out: else hns_roce_update_rq_db(ctx, qp->ibv_qp.qp_num, qp->rq.head & ((qp->rq.wqe_cnt << 1) - 1)); + + if (ibvqp->state == IBV_QPS_ERR) { + attr_mask = IBV_QP_STATE; + attr.qp_state = IBV_QPS_ERR; + + ret = hns_roce_u_v2_modify_qp(ibvqp, &attr, attr_mask); + if (ret) { + pthread_spin_unlock(&qp->rq.lock); + *bad_wr = wr; + return ret; + } + } } pthread_spin_unlock(&qp->rq.lock); @@ -991,6 +1039,9 @@ static int hns_roce_u_v2_destroy_qp(struct ibv_qp *ibqp) if (qp->rq.max_gs) hns_roce_free_db(to_hr_ctx(ibqp->context), qp->rdb, HNS_ROCE_QP_TYPE_DB); + if (qp->sq.max_gs) + hns_roce_free_db(to_hr_ctx(ibqp->context), qp->sdb, + HNS_ROCE_QP_TYPE_DB); hns_roce_free_buf(&qp->buf); if (qp->rq_rinl_buf.wqe_list) { diff --git a/providers/hns/hns_roce_u_hw_v2.h b/providers/hns/hns_roce_u_hw_v2.h index 84a7726..73b65bc 100644 --- a/providers/hns/hns_roce_u_hw_v2.h +++ b/providers/hns/hns_roce_u_hw_v2.h @@ -42,6 +42,7 @@ enum { HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0, + HNS_ROCE_SUPPORT_SQ_RECORD_DB = 1 << 1, }; enum { diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c index 13b6d71..962cdb5 100644 --- a/providers/hns/hns_roce_u_verbs.c +++ b/providers/hns/hns_roce_u_verbs.c @@ -573,7 +573,7 @@ struct ibv_qp *hns_roce_u_create_qp(struct ibv_pd *pd, if (hns_roce_alloc_qp_buf(pd, &attr->cap, attr->qp_type, qp)) { fprintf(stderr, "hns_roce_alloc_qp_buf failed!\n"); - goto err; + goto err_buf; } hns_roce_init_qp_indices(qp); @@ -585,10 +585,21 @@ struct ibv_qp *hns_roce_u_create_qp(struct ibv_pd *pd, } if ((to_hr_dev(pd->context->device)->hw_version != HNS_ROCE_HW_VER1) && + attr->cap.max_send_sge) { + qp->sdb = hns_roce_alloc_db(context, HNS_ROCE_QP_TYPE_DB); + if (!qp->sdb) + goto err_free; + + *(qp->sdb) = 0; + cmd.sdb_addr = (uintptr_t)qp->sdb; + } else + cmd.sdb_addr = 0; + + if ((to_hr_dev(pd->context->device)->hw_version != HNS_ROCE_HW_VER1) && attr->cap.max_recv_sge) { qp->rdb = hns_roce_alloc_db(context, HNS_ROCE_QP_TYPE_DB); if (!qp->rdb) - goto err_free; + goto err_sq_db; *(qp->rdb) = 0; cmd.db_addr = (uintptr_t) qp->rdb; @@ -643,13 +654,18 @@ err_rq_db: attr->cap.max_recv_sge) hns_roce_free_db(context, qp->rdb, HNS_ROCE_QP_TYPE_DB); +err_sq_db: + if ((to_hr_dev(pd->context->device)->hw_version != HNS_ROCE_HW_VER1) && + attr->cap.max_send_sge) + hns_roce_free_db(context, qp->sdb, HNS_ROCE_QP_TYPE_DB); + err_free: free(qp->sq.wrid); if (qp->rq.wqe_cnt) free(qp->rq.wrid); hns_roce_free_buf(&qp->buf); -err: +err_buf: free(qp); return NULL;