aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/sw/rdmavt/rc.c
diff options
context:
space:
mode:
authorKamenee Arumugam <kamenee.arumugam@intel.com>2019-06-28 14:04:30 -0400
committerJason Gunthorpe <jgg@mellanox.com>2019-06-28 22:32:16 -0300
commitf592ae3c999fbe4faeeb90dfde8ff7da49ee4ae6 (patch)
tree3f208eeed24e4a4f8107dccfe19414c444941af5 /drivers/infiniband/sw/rdmavt/rc.c
parentIB/hfi1: Move receive work queue struct into uapi directory (diff)
downloadlinux-dev-f592ae3c999fbe4faeeb90dfde8ff7da49ee4ae6.tar.xz
linux-dev-f592ae3c999fbe4faeeb90dfde8ff7da49ee4ae6.zip
IB/rdmavt: Fracture single lock used for posting and processing RWQEs
Usage of single lock prevents fetching posted and processing receive work queue entries from progressing simultaneously and impacts overall performance. Fracture the single lock used for posting and processing Receive Work Queue Entries (RWQEs) to allow the circular buffer to be filled and emptied at the same time. Two new spinlocks - one for the producers and one for the consumers used for posting and processing RWQEs simultaneously and the two indices are define on two different cache lines. The threshold count is used to avoid reading other index in different cache line every time. Signed-off-by: Harish Chegondi <harish.chegondi@intel.com> Signed-off-by: Kamenee Arumugam <kamenee.arumugam@intel.com> Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/sw/rdmavt/rc.c')
-rw-r--r--drivers/infiniband/sw/rdmavt/rc.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/infiniband/sw/rdmavt/rc.c b/drivers/infiniband/sw/rdmavt/rc.c
index 44cc7ee1b321..890d7b760d2e 100644
--- a/drivers/infiniband/sw/rdmavt/rc.c
+++ b/drivers/infiniband/sw/rdmavt/rc.c
@@ -107,27 +107,30 @@ __be32 rvt_compute_aeth(struct rvt_qp *qp)
u32 head;
u32 tail;
- /* sanity check pointers before trusting them */
- if (qp->ip) {
- head = RDMA_READ_UAPI_ATOMIC(qp->r_rq.wq->head);
- tail = RDMA_READ_UAPI_ATOMIC(qp->r_rq.wq->tail);
- } else {
- head = READ_ONCE(qp->r_rq.kwq->head);
- tail = READ_ONCE(qp->r_rq.kwq->tail);
+ credits = READ_ONCE(qp->r_rq.kwq->count);
+ if (credits == 0) {
+ /* sanity check pointers before trusting them */
+ if (qp->ip) {
+ head = RDMA_READ_UAPI_ATOMIC(qp->r_rq.wq->head);
+ tail = RDMA_READ_UAPI_ATOMIC(qp->r_rq.wq->tail);
+ } else {
+ head = READ_ONCE(qp->r_rq.kwq->head);
+ tail = READ_ONCE(qp->r_rq.kwq->tail);
+ }
+ if (head >= qp->r_rq.size)
+ head = 0;
+ if (tail >= qp->r_rq.size)
+ tail = 0;
+ /*
+ * Compute the number of credits available (RWQEs).
+ * There is a small chance that the pair of reads are
+ * not atomic, which is OK, since the fuzziness is
+ * resolved as further ACKs go out.
+ */
+ credits = head - tail;
+ if ((int)credits < 0)
+ credits += qp->r_rq.size;
}
- if (head >= qp->r_rq.size)
- head = 0;
- if (tail >= qp->r_rq.size)
- tail = 0;
- /*
- * Compute the number of credits available (RWQEs).
- * There is a small chance that the pair of reads are
- * not atomic, which is OK, since the fuzziness is
- * resolved as further ACKs go out.
- */
- credits = head - tail;
- if ((int)credits < 0)
- credits += qp->r_rq.size;
/*
* Binary search the credit table to find the code to
* use.