]> git.itanic.dy.fi Git - linux-stable/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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 May 2022 10:32:33 +0000 (12:32 +0200)
commit 7b8943b821bafab492f43aafbd006b57c6b65845 upstream.

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: b48c24c2d710 ("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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/infiniband/hw/irdma/cm.c
drivers/infiniband/hw/irdma/verbs.c

index 6dea0a49d1718384d662df8071c4fec98791a475..bfe2e6fd50ad36b3d8b5ab225cd40bcdca695bdb 100644 (file)
@@ -3465,12 +3465,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;
@@ -3492,11 +3486,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 1bf6404ec8340728bd723ac42b0938ea764b6151..c2aa713e0f4d7e1f8ae746efea4e182f2d2a9bf4 100644 (file)
@@ -1620,13 +1620,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;