• Steve Wise's avatar
    RDMA/cxgb4: Fix endpoint mutex deadlocks · cc18b939
    Steve Wise authored
    In cases where the cm calls c4iw_modify_rc_qp() with the endpoint
    mutex held, they must be called with internal == 1.  rx_data() and
    process_mpa_reply() are not doing this.  This causes a deadlock
    because c4iw_modify_rc_qp() might call c4iw_ep_disconnect() in some
    !internal cases, and c4iw_ep_disconnect() acquires the endpoint mutex.
    The design was intended to only do the disconnect for !internal calls.
    
    Change rx_data(), FPDU_MODE case, to call c4iw_modify_rc_qp() with
    internal == 1, and then disconnect only after releasing the mutex.
    
    Change process_mpa_reply() to call c4iw_modify_rc_qp(TERMINATE) with
    internal == 1 and set a new attr flag telling it to send a TERMINATE
    message.  Previously this was implied by !internal.
    
    Change process_mpa_reply() to return whether the caller should
    disconnect after releasing the endpoint mutex.  Now rx_data() will do
    the disconnect in the cases where process_mpa_reply() wants to
    disconnect after the TERMINATE is sent.
    
    Change c4iw_modify_rc_qp() RTS->TERM to only disconnect if !internal,
    and to send a TERMINATE message if attrs->send_term is 1.
    
    Change abort_connection() to not aquire the ep mutex for setting the
    state, and make all calls to abort_connection() do so with the mutex
    held.
    Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
    Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
    cc18b939
qp.c 48.3 KB