aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorDon Wood <donald.e.wood@intel.com>2009-09-05 23:36:39 -0400
committerRoland Dreier <rolandd@cisco.com>2009-09-05 23:36:39 -0400
commit6eed5e7c8bdce6ee21bbe0be4a3f3dce4d4b392a (patch)
treef9b6dc7cef73fb401acbb3b04947fe8b527d7a50 /drivers/infiniband
parent4b281faec3ad00f7fb00080078321e4d819795eb (diff)
RDMA/nes: Make poll_cq return correct number of wqes during flush
When a flush request is given to the hw, it will place one cqe marked as flushed (unless there is nothing to flush). An application that is waiting for all wqe's to complete will be left hanging. This modifies poll_cq to return the correct number of flushes for the pending elements on the wq. Signed-off-by: Don Wood <donald.e.wood@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 36666ac2f546..ad3c891d0f65 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -3615,11 +3615,13 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3615 struct nes_qp *nesqp; 3615 struct nes_qp *nesqp;
3616 struct nes_hw_cqe cqe; 3616 struct nes_hw_cqe cqe;
3617 u32 head; 3617 u32 head;
3618 u32 wq_tail; 3618 u32 wq_tail = 0;
3619 u32 cq_size; 3619 u32 cq_size;
3620 u32 cqe_count = 0; 3620 u32 cqe_count = 0;
3621 u32 wqe_index; 3621 u32 wqe_index;
3622 u32 u32temp; 3622 u32 u32temp;
3623 u32 move_cq_head = 1;
3624 u32 err_code;
3623 3625
3624 nes_debug(NES_DBG_CQ, "\n"); 3626 nes_debug(NES_DBG_CQ, "\n");
3625 3627
@@ -3640,7 +3642,6 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3640 rmb(); 3642 rmb();
3641 3643
3642 cqe = nescq->hw_cq.cq_vbase[head]; 3644 cqe = nescq->hw_cq.cq_vbase[head];
3643 nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
3644 u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); 3645 u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]);
3645 wqe_index = u32temp & (nesdev->nesadapter->max_qp_wr - 1); 3646 wqe_index = u32temp & (nesdev->nesadapter->max_qp_wr - 1);
3646 u32temp &= ~(NES_SW_CONTEXT_ALIGN-1); 3647 u32temp &= ~(NES_SW_CONTEXT_ALIGN-1);
@@ -3667,16 +3668,14 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3667 } 3668 }
3668 3669
3669 /* Working on a SQ Completion*/ 3670 /* Working on a SQ Completion*/
3670 wq_tail = wqe_index; 3671 wrid = (((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wqe_index].
3671 nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1);
3672 wrid = (((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail].
3673 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) | 3672 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) |
3674 ((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail]. 3673 ((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wqe_index].
3675 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX]))); 3674 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX])));
3676 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3675 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index].
3677 wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]); 3676 wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]);
3678 3677
3679 switch (le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3678 switch (le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index].
3680 wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) { 3679 wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) {
3681 case NES_IWARP_SQ_OP_RDMAW: 3680 case NES_IWARP_SQ_OP_RDMAW:
3682 nes_debug(NES_DBG_CQ, "Operation = RDMA WRITE.\n"); 3681 nes_debug(NES_DBG_CQ, "Operation = RDMA WRITE.\n");
@@ -3685,7 +3684,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3685 case NES_IWARP_SQ_OP_RDMAR: 3684 case NES_IWARP_SQ_OP_RDMAR:
3686 nes_debug(NES_DBG_CQ, "Operation = RDMA READ.\n"); 3685 nes_debug(NES_DBG_CQ, "Operation = RDMA READ.\n");
3687 entry->opcode = IB_WC_RDMA_READ; 3686 entry->opcode = IB_WC_RDMA_READ;
3688 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3687 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index].
3689 wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]); 3688 wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]);
3690 break; 3689 break;
3691 case NES_IWARP_SQ_OP_SENDINV: 3690 case NES_IWARP_SQ_OP_SENDINV:
@@ -3696,14 +3695,24 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3696 entry->opcode = IB_WC_SEND; 3695 entry->opcode = IB_WC_SEND;
3697 break; 3696 break;
3698 } 3697 }
3698
3699 nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1);
3700 if ((entry->status != IB_WC_SUCCESS) && (nesqp->hwqp.sq_tail != nesqp->hwqp.sq_head)) {
3701 move_cq_head = 0;
3702 wq_tail = nesqp->hwqp.sq_tail;
3703 }
3699 } else { 3704 } else {
3700 /* Working on a RQ Completion*/ 3705 /* Working on a RQ Completion*/
3701 wq_tail = wqe_index;
3702 nesqp->hwqp.rq_tail = (wqe_index+1)&(nesqp->hwqp.rq_size - 1);
3703 entry->byte_len = le32_to_cpu(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]); 3706 entry->byte_len = le32_to_cpu(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]);
3704 wrid = ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX]))) | 3707 wrid = ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX]))) |
3705 ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32); 3708 ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32);
3706 entry->opcode = IB_WC_RECV; 3709 entry->opcode = IB_WC_RECV;
3710
3711 nesqp->hwqp.rq_tail = (wqe_index+1)&(nesqp->hwqp.rq_size - 1);
3712 if ((entry->status != IB_WC_SUCCESS) && (nesqp->hwqp.rq_tail != nesqp->hwqp.rq_head)) {
3713 move_cq_head = 0;
3714 wq_tail = nesqp->hwqp.rq_tail;
3715 }
3707 } 3716 }
3708 3717
3709 entry->wr_id = wrid; 3718 entry->wr_id = wrid;
@@ -3711,18 +3720,28 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3711 cqe_count++; 3720 cqe_count++;
3712 } 3721 }
3713 3722
3714 if (++head >= cq_size) 3723 if (move_cq_head) {
3715 head = 0; 3724 nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
3716 nescq->polled_completions++; 3725 if (++head >= cq_size)
3726 head = 0;
3727 nescq->polled_completions++;
3717 3728
3718 if ((nescq->polled_completions > (cq_size / 2)) || 3729 if ((nescq->polled_completions > (cq_size / 2)) ||
3719 (nescq->polled_completions == 255)) { 3730 (nescq->polled_completions == 255)) {
3720 nes_debug(NES_DBG_CQ, "CQ%u Issuing CQE Allocate since more than half of cqes" 3731 nes_debug(NES_DBG_CQ, "CQ%u Issuing CQE Allocate since more than half of cqes"
3721 " are pending %u of %u.\n", 3732 " are pending %u of %u.\n",
3722 nescq->hw_cq.cq_number, nescq->polled_completions, cq_size); 3733 nescq->hw_cq.cq_number, nescq->polled_completions, cq_size);
3723 nes_write32(nesdev->regs+NES_CQE_ALLOC, 3734 nes_write32(nesdev->regs+NES_CQE_ALLOC,
3724 nescq->hw_cq.cq_number | (nescq->polled_completions << 16)); 3735 nescq->hw_cq.cq_number | (nescq->polled_completions << 16));
3725 nescq->polled_completions = 0; 3736 nescq->polled_completions = 0;
3737 }
3738 } else {
3739 /* Update the wqe index and set status to flush */
3740 wqe_index = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]);
3741 wqe_index = (wqe_index & (~(nesdev->nesadapter->max_qp_wr - 1))) | wq_tail;
3742 nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX] =
3743 cpu_to_le32(wqe_index);
3744 move_cq_head = 1; /* ready for next pass */
3726 } 3745 }
3727 } 3746 }
3728 3747