aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@mellanox.co.il>2005-11-09 17:59:57 -0500
committerRoland Dreier <rolandd@cisco.com>2005-11-10 13:22:51 -0500
commitae57e24a4006fd46b73d842ee99db9580ef74a02 (patch)
tree17115437026be55dcd74641be21561fecf33dcdb
parent64044bcf75063cb5a6d42712886a712449df2ce3 (diff)
[IB] mthca: fix posting long lists of receive work requests
In Tavor mode, when posting a long list of receive work requests, a doorbell must be rung every 256 requests. Add code to do this when required. Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c19
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c22
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h3
3 files changed, 39 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 190c1dc0ee27..760c418d5bc9 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1707,6 +1707,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1707{ 1707{
1708 struct mthca_dev *dev = to_mdev(ibqp->device); 1708 struct mthca_dev *dev = to_mdev(ibqp->device);
1709 struct mthca_qp *qp = to_mqp(ibqp); 1709 struct mthca_qp *qp = to_mqp(ibqp);
1710 __be32 doorbell[2];
1710 unsigned long flags; 1711 unsigned long flags;
1711 int err = 0; 1712 int err = 0;
1712 int nreq; 1713 int nreq;
@@ -1724,6 +1725,22 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1724 ind = qp->rq.next_ind; 1725 ind = qp->rq.next_ind;
1725 1726
1726 for (nreq = 0; wr; ++nreq, wr = wr->next) { 1727 for (nreq = 0; wr; ++nreq, wr = wr->next) {
1728 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
1729 nreq = 0;
1730
1731 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1732 doorbell[1] = cpu_to_be32(qp->qpn << 8);
1733
1734 wmb();
1735
1736 mthca_write64(doorbell,
1737 dev->kar + MTHCA_RECEIVE_DOORBELL,
1738 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
1739
1740 qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
1741 size0 = 0;
1742 }
1743
1727 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { 1744 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
1728 mthca_err(dev, "RQ %06x full (%u head, %u tail," 1745 mthca_err(dev, "RQ %06x full (%u head, %u tail,"
1729 " %d max, %d nreq)\n", qp->qpn, 1746 " %d max, %d nreq)\n", qp->qpn,
@@ -1781,8 +1798,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1781 1798
1782out: 1799out:
1783 if (likely(nreq)) { 1800 if (likely(nreq)) {
1784 __be32 doorbell[2];
1785
1786 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); 1801 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1787 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); 1802 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
1788 1803
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 292f55be8cbd..c3c0331a1f6e 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -414,6 +414,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
414{ 414{
415 struct mthca_dev *dev = to_mdev(ibsrq->device); 415 struct mthca_dev *dev = to_mdev(ibsrq->device);
416 struct mthca_srq *srq = to_msrq(ibsrq); 416 struct mthca_srq *srq = to_msrq(ibsrq);
417 __be32 doorbell[2];
417 unsigned long flags; 418 unsigned long flags;
418 int err = 0; 419 int err = 0;
419 int first_ind; 420 int first_ind;
@@ -429,6 +430,25 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
429 first_ind = srq->first_free; 430 first_ind = srq->first_free;
430 431
431 for (nreq = 0; wr; ++nreq, wr = wr->next) { 432 for (nreq = 0; wr; ++nreq, wr = wr->next) {
433 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
434 nreq = 0;
435
436 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
437 doorbell[1] = cpu_to_be32(srq->srqn << 8);
438
439 /*
440 * Make sure that descriptors are written
441 * before doorbell is rung.
442 */
443 wmb();
444
445 mthca_write64(doorbell,
446 dev->kar + MTHCA_RECEIVE_DOORBELL,
447 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
448
449 first_ind = srq->first_free;
450 }
451
432 ind = srq->first_free; 452 ind = srq->first_free;
433 453
434 if (ind < 0) { 454 if (ind < 0) {
@@ -491,8 +511,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
491 } 511 }
492 512
493 if (likely(nreq)) { 513 if (likely(nreq)) {
494 __be32 doorbell[2];
495
496 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift); 514 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
497 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq); 515 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
498 516
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
index 1f4c0ff28f79..73f1c0b9021e 100644
--- a/drivers/infiniband/hw/mthca/mthca_wqe.h
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -49,7 +49,8 @@ enum {
49}; 49};
50 50
51enum { 51enum {
52 MTHCA_INVAL_LKEY = 0x100 52 MTHCA_INVAL_LKEY = 0x100,
53 MTHCA_TAVOR_MAX_WQES_PER_RECV_DB = 256
53}; 54};
54 55
55struct mthca_next_seg { 56struct mthca_next_seg {