]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
i40iw: Fix QP flush to not hang on empty queues or failure
authorShiraz Saleem <shiraz.saleem@intel.com>
Tue, 6 Dec 2016 21:49:31 +0000 (15:49 -0600)
committerDoug Ledford <dledford@redhat.com>
Mon, 12 Dec 2016 22:20:27 +0000 (17:20 -0500)
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>
drivers/infiniband/hw/i40iw/i40iw.h
drivers/infiniband/hw/i40iw/i40iw_hw.c

index 51b828026b539e381a8606ea1aa55d1f23979450..2aab85bbcbc7164f86b444a7cc767f52dca94614 100644 (file)
 #define I40IW_DRV_OPT_MCAST_LOGPORT_MAP    0x00000800
 
 #define IW_HMC_OBJ_TYPE_NUM ARRAY_SIZE(iw_hmc_obj_types)
-#define IW_CFG_FPM_QP_COUNT            32768
-#define I40IW_MAX_PAGES_PER_FMR                512
-#define I40IW_MIN_PAGES_PER_FMR                1
+#define IW_CFG_FPM_QP_COUNT               32768
+#define I40IW_MAX_PAGES_PER_FMR           512
+#define I40IW_MIN_PAGES_PER_FMR           1
+#define I40IW_CQP_COMPL_RQ_WQE_FLUSHED    2
+#define I40IW_CQP_COMPL_SQ_WQE_FLUSHED    3
+#define I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED 4
 
 #define I40IW_MTU_TO_MSS               40
 #define I40IW_DEFAULT_MSS              1460
index b2854b11a240d6fbadeeea53f7fd3098981eeb7b..4394a6713bdf8d3bd5419afec480123fc5cce188 100644 (file)
@@ -622,6 +622,7 @@ enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
        struct i40iw_qp_flush_info *hw_info;
        struct i40iw_cqp_request *cqp_request;
        struct cqp_commands_info *cqp_info;
+       struct i40iw_qp *iwqp = (struct i40iw_qp *)qp->back_qp;
 
        cqp_request = i40iw_get_cqp_request(&iwdev->cqp, wait);
        if (!cqp_request)
@@ -636,9 +637,30 @@ enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
        cqp_info->in.u.qp_flush_wqes.qp = qp;
        cqp_info->in.u.qp_flush_wqes.scratch = (uintptr_t)cqp_request;
        status = i40iw_handle_cqp_op(iwdev, cqp_request);
-       if (status)
+       if (status) {
                i40iw_pr_err("CQP-OP Flush WQE's fail");
-       return status;
+               complete(&iwqp->sq_drained);
+               complete(&iwqp->rq_drained);
+               return status;
+       }
+       if (!cqp_request->compl_info.maj_err_code) {
+               switch (cqp_request->compl_info.min_err_code) {
+               case I40IW_CQP_COMPL_RQ_WQE_FLUSHED:
+                       complete(&iwqp->sq_drained);
+                       break;
+               case I40IW_CQP_COMPL_SQ_WQE_FLUSHED:
+                       complete(&iwqp->rq_drained);
+                       break;
+               case I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED:
+                       break;
+               default:
+                       complete(&iwqp->sq_drained);
+                       complete(&iwqp->rq_drained);
+                       break;
+               }
+       }
+
+       return 0;
 }
 
 /**