diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4/cq.c')
-rw-r--r-- | drivers/infiniband/hw/mlx4/cq.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index a3b70f6c4035..543ecdd8667b 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
@@ -188,6 +188,8 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector | |||
188 | spin_lock_init(&cq->lock); | 188 | spin_lock_init(&cq->lock); |
189 | cq->resize_buf = NULL; | 189 | cq->resize_buf = NULL; |
190 | cq->resize_umem = NULL; | 190 | cq->resize_umem = NULL; |
191 | INIT_LIST_HEAD(&cq->send_qp_list); | ||
192 | INIT_LIST_HEAD(&cq->recv_qp_list); | ||
191 | 193 | ||
192 | if (context) { | 194 | if (context) { |
193 | struct mlx4_ib_create_cq ucmd; | 195 | struct mlx4_ib_create_cq ucmd; |
@@ -594,6 +596,55 @@ static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct | |||
594 | return 0; | 596 | return 0; |
595 | } | 597 | } |
596 | 598 | ||
599 | static void mlx4_ib_qp_sw_comp(struct mlx4_ib_qp *qp, int num_entries, | ||
600 | struct ib_wc *wc, int *npolled, int is_send) | ||
601 | { | ||
602 | struct mlx4_ib_wq *wq; | ||
603 | unsigned cur; | ||
604 | int i; | ||
605 | |||
606 | wq = is_send ? &qp->sq : &qp->rq; | ||
607 | cur = wq->head - wq->tail; | ||
608 | |||
609 | if (cur == 0) | ||
610 | return; | ||
611 | |||
612 | for (i = 0; i < cur && *npolled < num_entries; i++) { | ||
613 | wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)]; | ||
614 | wc->status = IB_WC_WR_FLUSH_ERR; | ||
615 | wc->vendor_err = MLX4_CQE_SYNDROME_WR_FLUSH_ERR; | ||
616 | wq->tail++; | ||
617 | (*npolled)++; | ||
618 | wc->qp = &qp->ibqp; | ||
619 | wc++; | ||
620 | } | ||
621 | } | ||
622 | |||
623 | static void mlx4_ib_poll_sw_comp(struct mlx4_ib_cq *cq, int num_entries, | ||
624 | struct ib_wc *wc, int *npolled) | ||
625 | { | ||
626 | struct mlx4_ib_qp *qp; | ||
627 | |||
628 | *npolled = 0; | ||
629 | /* Find uncompleted WQEs belonging to that cq and retrun | ||
630 | * simulated FLUSH_ERR completions | ||
631 | */ | ||
632 | list_for_each_entry(qp, &cq->send_qp_list, cq_send_list) { | ||
633 | mlx4_ib_qp_sw_comp(qp, num_entries, wc, npolled, 1); | ||
634 | if (*npolled >= num_entries) | ||
635 | goto out; | ||
636 | } | ||
637 | |||
638 | list_for_each_entry(qp, &cq->recv_qp_list, cq_recv_list) { | ||
639 | mlx4_ib_qp_sw_comp(qp, num_entries, wc + *npolled, npolled, 0); | ||
640 | if (*npolled >= num_entries) | ||
641 | goto out; | ||
642 | } | ||
643 | |||
644 | out: | ||
645 | return; | ||
646 | } | ||
647 | |||
597 | static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, | 648 | static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, |
598 | struct mlx4_ib_qp **cur_qp, | 649 | struct mlx4_ib_qp **cur_qp, |
599 | struct ib_wc *wc) | 650 | struct ib_wc *wc) |
@@ -836,8 +887,13 @@ int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
836 | unsigned long flags; | 887 | unsigned long flags; |
837 | int npolled; | 888 | int npolled; |
838 | int err = 0; | 889 | int err = 0; |
890 | struct mlx4_ib_dev *mdev = to_mdev(cq->ibcq.device); | ||
839 | 891 | ||
840 | spin_lock_irqsave(&cq->lock, flags); | 892 | spin_lock_irqsave(&cq->lock, flags); |
893 | if (mdev->dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR) { | ||
894 | mlx4_ib_poll_sw_comp(cq, num_entries, wc, &npolled); | ||
895 | goto out; | ||
896 | } | ||
841 | 897 | ||
842 | for (npolled = 0; npolled < num_entries; ++npolled) { | 898 | for (npolled = 0; npolled < num_entries; ++npolled) { |
843 | err = mlx4_ib_poll_one(cq, &cur_qp, wc + npolled); | 899 | err = mlx4_ib_poll_one(cq, &cur_qp, wc + npolled); |
@@ -847,6 +903,7 @@ int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
847 | 903 | ||
848 | mlx4_cq_set_ci(&cq->mcq); | 904 | mlx4_cq_set_ci(&cq->mcq); |
849 | 905 | ||
906 | out: | ||
850 | spin_unlock_irqrestore(&cq->lock, flags); | 907 | spin_unlock_irqrestore(&cq->lock, flags); |
851 | 908 | ||
852 | if (err == 0 || err == -EAGAIN) | 909 | if (err == 0 || err == -EAGAIN) |