lkml.org 
[lkml]   [2019]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 079/123] iw_cxgb4: fix srqidx leak during connection abort
    Date
    From: Raju Rangoju <rajur@chelsio.com>

    [ Upstream commit f368ff188ae4b3ef6f740a15999ea0373261b619 ]

    When an application aborts the connection by moving QP from RTS to ERROR,
    then iw_cxgb4's modify_rc_qp() RTS->ERROR logic sets the
    *srqidxp to 0 via t4_set_wq_in_error(&qhp->wq, 0), and aborts the
    connection by calling c4iw_ep_disconnect().

    c4iw_ep_disconnect() does the following:
    1. sends up a close_complete_upcall(ep, -ECONNRESET) to libcxgb4.
    2. sends abort request CPL to hw.

    But, since the close_complete_upcall() is sent before sending the
    ABORT_REQ to hw, libcxgb4 would fail to release the srqidx if the
    connection holds one. Because, the srqidx is passed up to libcxgb4 only
    after corresponding ABORT_RPL is processed by kernel in abort_rpl().

    This patch handle the corner-case by moving the call to
    close_complete_upcall() from c4iw_ep_disconnect() to abort_rpl(). So that
    libcxgb4 is notified about the -ECONNRESET only after abort_rpl(), and
    libcxgb4 can relinquish the srqidx properly.

    Signed-off-by: Raju Rangoju <rajur@chelsio.com>
    Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/infiniband/hw/cxgb4/cm.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
    index daf7a56e5d7e..e17f11782821 100644
    --- a/drivers/infiniband/hw/cxgb4/cm.c
    +++ b/drivers/infiniband/hw/cxgb4/cm.c
    @@ -1884,8 +1884,10 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
    }
    mutex_unlock(&ep->com.mutex);

    - if (release)
    + if (release) {
    + close_complete_upcall(ep, -ECONNRESET);
    release_ep_resources(ep);
    + }
    c4iw_put_ep(&ep->com);
    return 0;
    }
    @@ -3584,7 +3586,6 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
    if (close) {
    if (abrupt) {
    set_bit(EP_DISC_ABORT, &ep->com.history);
    - close_complete_upcall(ep, -ECONNRESET);
    ret = send_abort(ep);
    } else {
    set_bit(EP_DISC_CLOSE, &ep->com.history);
    --
    2.19.1
    \
     
     \ /
      Last update: 2019-03-27 19:49    [W:4.044 / U:1.920 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site