aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ehca/ehca_reqs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_reqs.c')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 64928079eafa..00a648f4316c 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -179,6 +179,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
179 179
180 qmap_entry->app_wr_id = get_app_wr_id(send_wr->wr_id); 180 qmap_entry->app_wr_id = get_app_wr_id(send_wr->wr_id);
181 qmap_entry->reported = 0; 181 qmap_entry->reported = 0;
182 qmap_entry->cqe_req = 0;
182 183
183 switch (send_wr->opcode) { 184 switch (send_wr->opcode) {
184 case IB_WR_SEND: 185 case IB_WR_SEND:
@@ -203,8 +204,10 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
203 204
204 if ((send_wr->send_flags & IB_SEND_SIGNALED || 205 if ((send_wr->send_flags & IB_SEND_SIGNALED ||
205 qp->init_attr.sq_sig_type == IB_SIGNAL_ALL_WR) 206 qp->init_attr.sq_sig_type == IB_SIGNAL_ALL_WR)
206 && !hidden) 207 && !hidden) {
207 wqe_p->wr_flag |= WQE_WRFLAG_REQ_SIGNAL_COM; 208 wqe_p->wr_flag |= WQE_WRFLAG_REQ_SIGNAL_COM;
209 qmap_entry->cqe_req = 1;
210 }
208 211
209 if (send_wr->opcode == IB_WR_SEND_WITH_IMM || 212 if (send_wr->opcode == IB_WR_SEND_WITH_IMM ||
210 send_wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) { 213 send_wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) {
@@ -569,6 +572,7 @@ static int internal_post_recv(struct ehca_qp *my_qp,
569 qmap_entry = &my_qp->rq_map.map[rq_map_idx]; 572 qmap_entry = &my_qp->rq_map.map[rq_map_idx];
570 qmap_entry->app_wr_id = get_app_wr_id(cur_recv_wr->wr_id); 573 qmap_entry->app_wr_id = get_app_wr_id(cur_recv_wr->wr_id);
571 qmap_entry->reported = 0; 574 qmap_entry->reported = 0;
575 qmap_entry->cqe_req = 1;
572 576
573 wqe_cnt++; 577 wqe_cnt++;
574 } /* eof for cur_recv_wr */ 578 } /* eof for cur_recv_wr */
@@ -706,27 +710,34 @@ repoll:
706 goto repoll; 710 goto repoll;
707 wc->qp = &my_qp->ib_qp; 711 wc->qp = &my_qp->ib_qp;
708 712
713 qmap_tail_idx = get_app_wr_id(cqe->work_request_id);
714 if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT))
715 /* We got a send completion. */
716 qmap = &my_qp->sq_map;
717 else
718 /* We got a receive completion. */
719 qmap = &my_qp->rq_map;
720
721 /* advance the tail pointer */
722 qmap->tail = qmap_tail_idx;
723
709 if (is_error) { 724 if (is_error) {
710 /* 725 /*
711 * set left_to_poll to 0 because in error state, we will not 726 * set left_to_poll to 0 because in error state, we will not
712 * get any additional CQEs 727 * get any additional CQEs
713 */ 728 */
714 ehca_add_to_err_list(my_qp, 1); 729 my_qp->sq_map.next_wqe_idx = (my_qp->sq_map.tail + 1) %
730 my_qp->sq_map.entries;
715 my_qp->sq_map.left_to_poll = 0; 731 my_qp->sq_map.left_to_poll = 0;
732 ehca_add_to_err_list(my_qp, 1);
716 733
734 my_qp->rq_map.next_wqe_idx = (my_qp->rq_map.tail + 1) %
735 my_qp->rq_map.entries;
736 my_qp->rq_map.left_to_poll = 0;
717 if (HAS_RQ(my_qp)) 737 if (HAS_RQ(my_qp))
718 ehca_add_to_err_list(my_qp, 0); 738 ehca_add_to_err_list(my_qp, 0);
719 my_qp->rq_map.left_to_poll = 0;
720 } 739 }
721 740
722 qmap_tail_idx = get_app_wr_id(cqe->work_request_id);
723 if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT))
724 /* We got a send completion. */
725 qmap = &my_qp->sq_map;
726 else
727 /* We got a receive completion. */
728 qmap = &my_qp->rq_map;
729
730 qmap_entry = &qmap->map[qmap_tail_idx]; 741 qmap_entry = &qmap->map[qmap_tail_idx];
731 if (qmap_entry->reported) { 742 if (qmap_entry->reported) {
732 ehca_warn(cq->device, "Double cqe on qp_num=%#x", 743 ehca_warn(cq->device, "Double cqe on qp_num=%#x",
@@ -738,10 +749,6 @@ repoll:
738 wc->wr_id = replace_wr_id(cqe->work_request_id, qmap_entry->app_wr_id); 749 wc->wr_id = replace_wr_id(cqe->work_request_id, qmap_entry->app_wr_id);
739 qmap_entry->reported = 1; 750 qmap_entry->reported = 1;
740 751
741 /* this is a proper completion, we need to advance the tail pointer */
742 if (++qmap->tail == qmap->entries)
743 qmap->tail = 0;
744
745 /* if left_to_poll is decremented to 0, add the QP to the error list */ 752 /* if left_to_poll is decremented to 0, add the QP to the error list */
746 if (qmap->left_to_poll > 0) { 753 if (qmap->left_to_poll > 0) {
747 qmap->left_to_poll--; 754 qmap->left_to_poll--;
@@ -805,13 +812,14 @@ static int generate_flush_cqes(struct ehca_qp *my_qp, struct ib_cq *cq,
805 else 812 else
806 qmap = &my_qp->rq_map; 813 qmap = &my_qp->rq_map;
807 814
808 qmap_entry = &qmap->map[qmap->tail]; 815 qmap_entry = &qmap->map[qmap->next_wqe_idx];
809 816
810 while ((nr < num_entries) && (qmap_entry->reported == 0)) { 817 while ((nr < num_entries) && (qmap_entry->reported == 0)) {
811 /* generate flush CQE */ 818 /* generate flush CQE */
819
812 memset(wc, 0, sizeof(*wc)); 820 memset(wc, 0, sizeof(*wc));
813 821
814 offset = qmap->tail * ipz_queue->qe_size; 822 offset = qmap->next_wqe_idx * ipz_queue->qe_size;
815 wqe = (struct ehca_wqe *)ipz_qeit_calc(ipz_queue, offset); 823 wqe = (struct ehca_wqe *)ipz_qeit_calc(ipz_queue, offset);
816 if (!wqe) { 824 if (!wqe) {
817 ehca_err(cq->device, "Invalid wqe offset=%#lx on " 825 ehca_err(cq->device, "Invalid wqe offset=%#lx on "
@@ -850,11 +858,12 @@ static int generate_flush_cqes(struct ehca_qp *my_qp, struct ib_cq *cq,
850 858
851 wc->qp = &my_qp->ib_qp; 859 wc->qp = &my_qp->ib_qp;
852 860
853 /* mark as reported and advance tail pointer */ 861 /* mark as reported and advance next_wqe pointer */
854 qmap_entry->reported = 1; 862 qmap_entry->reported = 1;
855 if (++qmap->tail == qmap->entries) 863 qmap->next_wqe_idx++;
856 qmap->tail = 0; 864 if (qmap->next_wqe_idx == qmap->entries)
857 qmap_entry = &qmap->map[qmap->tail]; 865 qmap->next_wqe_idx = 0;
866 qmap_entry = &qmap->map[qmap->next_wqe_idx];
858 867
859 wc++; nr++; 868 wc++; nr++;
860 } 869 }