From patchwork Thu Dec 15 09:27:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Amrani, Ram" X-Patchwork-Id: 9475699 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3DDB660571 for ; Thu, 15 Dec 2016 09:28:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A555286C1 for ; Thu, 15 Dec 2016 09:28:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2E914286C5; Thu, 15 Dec 2016 09:28:11 +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=-6.9 required=2.0 tests=BAYES_00,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 016B1286C1 for ; Thu, 15 Dec 2016 09:28:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755158AbcLOJ2E (ORCPT ); Thu, 15 Dec 2016 04:28:04 -0500 Received: from mx0a-0016ce01.pphosted.com ([67.231.148.157]:60105 "EHLO mx0b-0016ce01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753237AbcLOJ2C (ORCPT ); Thu, 15 Dec 2016 04:28:02 -0500 Received: from pps.filterd (m0095336.ppops.net [127.0.0.1]) by mx0a-0016ce01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id uBF9PsWw024126; Thu, 15 Dec 2016 01:27:26 -0800 Received: from avcashub1.qlogic.com ([198.186.0.117]) by mx0a-0016ce01.pphosted.com with ESMTP id 27brh0g0a7-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Thu, 15 Dec 2016 01:27:25 -0800 Received: from lb-tlvb-ramrani.il.qlogic.org (10.185.6.119) by qlc.com (10.1.4.192) with Microsoft SMTP Server id 14.3.235.1; Thu, 15 Dec 2016 01:27:19 -0800 From: Ram Amrani To: CC: , , , Ram Amrani , Ram Amrani Subject: [PATCH rdma-core] libqedr: fix queue wrapping logic Date: Thu, 15 Dec 2016 11:27:00 +0200 Message-ID: <1481794020-28167-1-git-send-email-Ram.Amrani@Cavium.com> X-Mailer: git-send-email 2.1.0 MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5800 definitions=8379 signatures=670781 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1612150153 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 pointer to a CQ, SQ or RQ may wrap before reaching the end of the queue for certain queue depths. This is fixed by using a wrapping logic based on a pointer rather than an index. Signed-off-by: Ram Amrani Reviewed-by: Elior, Ariel --- providers/qedr/qelr_chain.c | 24 +++++++++++++----------- providers/qedr/qelr_chain.h | 22 ++++++++++++---------- providers/qedr/qelr_verbs.c | 10 +++++----- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/providers/qedr/qelr_chain.c b/providers/qedr/qelr_chain.c index 6101f74..edc72f4 100644 --- a/providers/qedr/qelr_chain.c +++ b/providers/qedr/qelr_chain.c @@ -44,11 +44,11 @@ void *qelr_chain_get_last_elem(struct qelr_chain *p_chain) void *p_virt_addr = NULL; uint32_t size; - if (!p_chain->addr) + if (!p_chain->first_addr) goto out; size = p_chain->elem_size * (p_chain->n_elems - 1); - p_virt_addr = ((uint8_t *)p_chain->addr + size); + p_virt_addr = ((uint8_t *)p_chain->first_addr + size); out: return p_virt_addr; } @@ -58,8 +58,8 @@ void qelr_chain_reset(struct qelr_chain *p_chain) p_chain->prod_idx = 0; p_chain->cons_idx = 0; - p_chain->p_cons_elem = p_chain->addr; - p_chain->p_prod_elem = p_chain->addr; + p_chain->p_cons_elem = p_chain->first_addr; + p_chain->p_prod_elem = p_chain->first_addr; } #define QELR_ANON_FD (-1) /* MAP_ANONYMOUS => file desc.= -1 */ @@ -76,7 +76,7 @@ int qelr_chain_alloc(struct qelr_chain *chain, int chain_size, int page_size, addr = mmap(NULL, a_chain_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, QELR_ANON_FD, QELR_ANON_OFFSET); - if (chain->addr == MAP_FAILED) + if (chain->first_addr == MAP_FAILED) return errno; ret = ibv_dontfork_range(addr, a_chain_size); @@ -87,13 +87,15 @@ int qelr_chain_alloc(struct qelr_chain *chain, int chain_size, int page_size, /* init chain */ memset(chain, 0, sizeof(*chain)); - memset(chain->addr, 0, chain->size); - chain->addr = addr; + memset(chain->first_addr, 0, chain->size); + chain->first_addr = addr; chain->size = a_chain_size; - chain->p_cons_elem = chain->addr; - chain->p_prod_elem = chain->addr; + chain->p_cons_elem = chain->first_addr; + chain->p_prod_elem = chain->first_addr; chain->elem_size = elem_size; chain->n_elems = chain->size / elem_size; + chain->last_addr = (void *) + ((uint8_t *)addr + (elem_size * (chain->n_elems -1))); return 0; } @@ -101,7 +103,7 @@ int qelr_chain_alloc(struct qelr_chain *chain, int chain_size, int page_size, void qelr_chain_free(struct qelr_chain *chain) { if (chain->size) { - ibv_dofork_range(chain->addr, chain->size); - munmap(chain->addr, chain->size); + ibv_dofork_range(chain->first_addr, chain->size); + munmap(chain->first_addr, chain->size); } } diff --git a/providers/qedr/qelr_chain.h b/providers/qedr/qelr_chain.h index 2ff5bf5..12a30df 100644 --- a/providers/qedr/qelr_chain.h +++ b/providers/qedr/qelr_chain.h @@ -34,8 +34,8 @@ #define __QELR_CHAIN_H__ struct qelr_chain { - /* Address of first page of the chain */ - void *addr; + void *first_addr; /* Address of first element in chain */ + void *last_addr; /* Address of last element in chain */ /* Point to next element to produce/consume */ void *p_prod_elem; @@ -64,8 +64,8 @@ static inline void *qelr_chain_produce(struct qelr_chain *p_chain) p_ret = p_chain->p_prod_elem; - if (p_chain->prod_idx % p_chain->n_elems == 0) - p_chain->p_prod_elem = p_chain->addr; + if (p_chain->p_prod_elem == p_chain->last_addr) + p_chain->p_prod_elem = p_chain->first_addr; else p_chain->p_prod_elem = (void *)(((uint8_t *)p_chain->p_prod_elem) + p_chain->elem_size); @@ -83,8 +83,9 @@ static inline void *qelr_chain_produce_n(struct qelr_chain *p_chain, int n) n_wrap = p_chain->prod_idx % p_chain->n_elems; if (n_wrap < n) - p_chain->p_prod_elem = (void *)(((uint8_t *)p_chain->addr) + - (p_chain->elem_size * n_wrap)); + p_chain->p_prod_elem = (void *) + (((uint8_t *)p_chain->first_addr) + + (p_chain->elem_size * n_wrap)); else p_chain->p_prod_elem = (void *)(((uint8_t *)p_chain->p_prod_elem) + (p_chain->elem_size * n)); @@ -100,8 +101,8 @@ static inline void *qelr_chain_consume(struct qelr_chain *p_chain) p_ret = p_chain->p_cons_elem; - if (p_chain->cons_idx % p_chain->n_elems == 0) - p_chain->p_cons_elem = p_chain->addr; + if (p_chain->p_cons_elem == p_chain->last_addr) + p_chain->p_cons_elem = p_chain->first_addr; else p_chain->p_cons_elem = (void *) (((uint8_t *)p_chain->p_cons_elem) + @@ -120,8 +121,9 @@ static inline void *qelr_chain_consume_n(struct qelr_chain *p_chain, int n) n_wrap = p_chain->cons_idx % p_chain->n_elems; if (n_wrap < n) - p_chain->p_cons_elem = (void *)(((uint8_t *)p_chain->addr) + - (p_chain->elem_size * n_wrap)); + p_chain->p_cons_elem = (void *) + (((uint8_t *)p_chain->first_addr) + + (p_chain->elem_size * n_wrap)); else p_chain->p_cons_elem = (void *)(((uint8_t *)p_chain->p_cons_elem) + (p_chain->elem_size * n)); diff --git a/providers/qedr/qelr_verbs.c b/providers/qedr/qelr_verbs.c index 415efc0..793b1f4 100644 --- a/providers/qedr/qelr_verbs.c +++ b/providers/qedr/qelr_verbs.c @@ -248,7 +248,7 @@ struct ibv_cq *qelr_create_cq(struct ibv_context *context, int cqe, if (rc) goto err_0; - cmd.addr = (uintptr_t) cq->chain.addr; + cmd.addr = (uintptr_t) cq->chain.first_addr; cmd.len = cq->chain.size; rc = ibv_cmd_create_cq(context, cqe, channel, comp_vector, &cq->ibv_cq, &cmd.ibv_cmd, sizeof(cmd), @@ -485,7 +485,7 @@ static inline void qelr_create_qp_configure_sq_req(struct qelr_qp *qp, struct qelr_create_qp_req *req) { - req->sq_addr = (uintptr_t)qp->sq.chain.addr; + req->sq_addr = (uintptr_t)qp->sq.chain.first_addr; req->sq_len = qp->sq.chain.size; } @@ -493,7 +493,7 @@ static inline void qelr_create_qp_configure_rq_req(struct qelr_qp *qp, struct qelr_create_qp_req *req) { - req->rq_addr = (uintptr_t)qp->rq.chain.addr; + req->rq_addr = (uintptr_t)qp->rq.chain.first_addr; req->rq_len = qp->rq.chain.size; } @@ -1443,8 +1443,8 @@ int qelr_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, wr->sg_list[i].length, flags); FP_DP_VERBOSE(cxt->dbg_fp, QELR_MSG_CQ, "[%d]: len %d key %x addr %x:%x\n", i, - rqe->length, rqe->flags, rqe->addr.hi, - rqe->addr.lo); + rqe->length, rqe->flags, + rqe->first_addr.hi, rqe->first_addr.lo); } /* Special case of no sges. FW requires between 1-4 sges... * in this case we need to post 1 sge with length zero. this is