aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShiraz Saleem <shiraz.saleem@intel.com>2016-12-06 16:49:31 -0500
committerDoug Ledford <dledford@redhat.com>2016-12-12 17:20:27 -0500
commit1cda28bb5b503bab734072d97a41b2e7eda6b6b9 (patch)
treeea0369d13cead018e0dd94d0b9bbd7bf30a58513
parentf4a87ca12a1c203913a5cc889ec49b817a1f45fc (diff)
i40iw: Fix QP flush to not hang on empty queues or failure
When flush QP and there are no pending work requests, signal completion to unblock i40iw_drain_sq and i40iw_drain_rq which are waiting on completion for iwqp->sq_drained and iwqp->sq_drained respectively. Also, signal completion if flush QP fails to prevent the drain SQ or RQ from being blocked indefintely. Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw.h9
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_hw.c26
2 files changed, 30 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/i40iw/i40iw.h b/drivers/infiniband/hw/i40iw/i40iw.h
index 51b828026b53..2aab85bbcbc7 100644
--- a/drivers/infiniband/hw/i40iw/i40iw.h
+++ b/drivers/infiniband/hw/i40iw/i40iw.h
@@ -112,9 +112,12 @@
112#define I40IW_DRV_OPT_MCAST_LOGPORT_MAP 0x00000800 112#define I40IW_DRV_OPT_MCAST_LOGPORT_MAP 0x00000800
113 113
114#define IW_HMC_OBJ_TYPE_NUM ARRAY_SIZE(iw_hmc_obj_types) 114#define IW_HMC_OBJ_TYPE_NUM ARRAY_SIZE(iw_hmc_obj_types)
115#define IW_CFG_FPM_QP_COUNT 32768 115#define IW_CFG_FPM_QP_COUNT 32768
116#define I40IW_MAX_PAGES_PER_FMR 512 116#define I40IW_MAX_PAGES_PER_FMR 512
117#define I40IW_MIN_PAGES_PER_FMR 1 117#define I40IW_MIN_PAGES_PER_FMR 1
118#define I40IW_CQP_COMPL_RQ_WQE_FLUSHED 2
119#define I40IW_CQP_COMPL_SQ_WQE_FLUSHED 3
120#define I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED 4
118 121
119#define I40IW_MTU_TO_MSS 40 122#define I40IW_MTU_TO_MSS 40
120#define I40IW_DEFAULT_MSS 1460 123#define I40IW_DEFAULT_MSS 1460
diff --git a/drivers/infiniband/hw/i40iw/i40iw_hw.c b/drivers/infiniband/hw/i40iw/i40iw_hw.c
index b2854b11a240..4394a6713bdf 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_hw.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_hw.c
@@ -622,6 +622,7 @@ enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
622 struct i40iw_qp_flush_info *hw_info; 622 struct i40iw_qp_flush_info *hw_info;
623 struct i40iw_cqp_request *cqp_request; 623 struct i40iw_cqp_request *cqp_request;
624 struct cqp_commands_info *cqp_info; 624 struct cqp_commands_info *cqp_info;
625 struct i40iw_qp *iwqp = (struct i40iw_qp *)qp->back_qp;
625 626
626 cqp_request = i40iw_get_cqp_request(&iwdev->cqp, wait); 627 cqp_request = i40iw_get_cqp_request(&iwdev->cqp, wait);
627 if (!cqp_request) 628 if (!cqp_request)
@@ -636,9 +637,30 @@ enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
636 cqp_info->in.u.qp_flush_wqes.qp = qp; 637 cqp_info->in.u.qp_flush_wqes.qp = qp;
637 cqp_info->in.u.qp_flush_wqes.scratch = (uintptr_t)cqp_request; 638 cqp_info->in.u.qp_flush_wqes.scratch = (uintptr_t)cqp_request;
638 status = i40iw_handle_cqp_op(iwdev, cqp_request); 639 status = i40iw_handle_cqp_op(iwdev, cqp_request);
639 if (status) 640 if (status) {
640 i40iw_pr_err("CQP-OP Flush WQE's fail"); 641 i40iw_pr_err("CQP-OP Flush WQE's fail");
641 return status; 642 complete(&iwqp->sq_drained);
643 complete(&iwqp->rq_drained);
644 return status;
645 }
646 if (!cqp_request->compl_info.maj_err_code) {
647 switch (cqp_request->compl_info.min_err_code) {
648 case I40IW_CQP_COMPL_RQ_WQE_FLUSHED:
649 complete(&iwqp->sq_drained);
650 break;
651 case I40IW_CQP_COMPL_SQ_WQE_FLUSHED:
652 complete(&iwqp->rq_drained);
653 break;
654 case I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED:
655 break;
656 default:
657 complete(&iwqp->sq_drained);
658 complete(&iwqp->rq_drained);
659 break;
660 }
661 }
662
663 return 0;
642} 664}
643 665
644/** 666/**