]> git.baikalelectronics.ru Git - kernel.git/commitdiff
RDMA/irdma: Flush iWARP QP if modified to ERR from RTR state
authorTatyana Nikolova <tatyana.e.nikolova@intel.com>
Mon, 25 Apr 2022 18:17:01 +0000 (13:17 -0500)
committerJason Gunthorpe <jgg@nvidia.com>
Mon, 2 May 2022 14:10:33 +0000 (11:10 -0300)
When connection establishment fails in iWARP mode, an app can drain the
QPs and hang because flush isn't issued when the QP is modified from RTR
state to error. Issue a flush in this case using function
irdma_cm_disconn().

Update irdma_cm_disconn() to do flush when cm_id is NULL, which is the
case when the QP is in RTR state and there is an error in the connection
establishment.

Fixes: 434ed3ceee5a ("RDMA/irdma: Implement device supported verb APIs")
Link: https://lore.kernel.org/r/20220425181703.1634-2-shiraz.saleem@intel.com
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/irdma/cm.c
drivers/infiniband/hw/irdma/verbs.c

index a98d962e5efb6601e7d543ce31ab1cf941d27b75..90b4113e7071a8fef30cab7e09a26670a993e35a 100644 (file)
@@ -3462,12 +3462,6 @@ static void irdma_cm_disconn_true(struct irdma_qp *iwqp)
        }
 
        cm_id = iwqp->cm_id;
-       /* make sure we havent already closed this connection */
-       if (!cm_id) {
-               spin_unlock_irqrestore(&iwqp->lock, flags);
-               return;
-       }
-
        original_hw_tcp_state = iwqp->hw_tcp_state;
        original_ibqp_state = iwqp->ibqp_state;
        last_ae = iwqp->last_aeq;
@@ -3489,11 +3483,11 @@ static void irdma_cm_disconn_true(struct irdma_qp *iwqp)
                        disconn_status = -ECONNRESET;
        }
 
-       if ((original_hw_tcp_state == IRDMA_TCP_STATE_CLOSED ||
-            original_hw_tcp_state == IRDMA_TCP_STATE_TIME_WAIT ||
-            last_ae == IRDMA_AE_RDMAP_ROE_BAD_LLP_CLOSE ||
-            last_ae == IRDMA_AE_BAD_CLOSE ||
-            last_ae == IRDMA_AE_LLP_CONNECTION_RESET || iwdev->rf->reset)) {
+       if (original_hw_tcp_state == IRDMA_TCP_STATE_CLOSED ||
+           original_hw_tcp_state == IRDMA_TCP_STATE_TIME_WAIT ||
+           last_ae == IRDMA_AE_RDMAP_ROE_BAD_LLP_CLOSE ||
+           last_ae == IRDMA_AE_BAD_CLOSE ||
+           last_ae == IRDMA_AE_LLP_CONNECTION_RESET || iwdev->rf->reset || !cm_id) {
                issue_close = 1;
                iwqp->cm_id = NULL;
                qp->term_flags = 0;
index 46f475394af5f5d1f995317a967851c1331b8aad..52f3e88f85695728b294533d7482cd0cfc9b3373 100644 (file)
@@ -1618,13 +1618,13 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
 
        if (issue_modify_qp && iwqp->ibqp_state > IB_QPS_RTS) {
                if (dont_wait) {
-                       if (iwqp->cm_id && iwqp->hw_tcp_state) {
+                       if (iwqp->hw_tcp_state) {
                                spin_lock_irqsave(&iwqp->lock, flags);
                                iwqp->hw_tcp_state = IRDMA_TCP_STATE_CLOSED;
                                iwqp->last_aeq = IRDMA_AE_RESET_SENT;
                                spin_unlock_irqrestore(&iwqp->lock, flags);
-                               irdma_cm_disconn(iwqp);
                        }
+                       irdma_cm_disconn(iwqp);
                } else {
                        int close_timer_started;