Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d627b506 authored by Shiraz Saleem's avatar Shiraz Saleem Committed by Doug Ledford
Browse files

i40iw: Fix race condition in terminate timer's handler



Add a QP reference when terminate timer is started to ensure
the destroy QP doesn't race ahead to free the QP while it is being
referenced in the terminate timer's handler.

Signed-off-by: default avatarShiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent fd90d4d4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3471,7 +3471,7 @@ static void i40iw_cm_disconn_true(struct i40iw_qp *iwqp)
		 *terminate-handler to issue cm_disconn which can re-free
		 *a QP even after its refcnt=0.
		 */
		del_timer(&iwqp->terminate_timer);
		i40iw_terminate_del_timer(qp);
		if (!iwqp->flush_issued) {
			iwqp->flush_issued = 1;
			issue_flush = 1;
+4 −1
Original line number Diff line number Diff line
@@ -823,6 +823,7 @@ static void i40iw_terminate_timeout(unsigned long context)
	struct i40iw_sc_qp *qp = (struct i40iw_sc_qp *)&iwqp->sc_qp;

	i40iw_terminate_done(qp, 1);
	i40iw_rem_ref(&iwqp->ibqp);
}

/**
@@ -834,6 +835,7 @@ void i40iw_terminate_start_timer(struct i40iw_sc_qp *qp)
	struct i40iw_qp *iwqp;

	iwqp = (struct i40iw_qp *)qp->back_qp;
	i40iw_add_ref(&iwqp->ibqp);
	init_timer(&iwqp->terminate_timer);
	iwqp->terminate_timer.function = i40iw_terminate_timeout;
	iwqp->terminate_timer.expires = jiffies + HZ;
@@ -850,7 +852,8 @@ void i40iw_terminate_del_timer(struct i40iw_sc_qp *qp)
	struct i40iw_qp *iwqp;

	iwqp = (struct i40iw_qp *)qp->back_qp;
	del_timer(&iwqp->terminate_timer);
	if (del_timer(&iwqp->terminate_timer))
		i40iw_rem_ref(&iwqp->ibqp);
}

/**
+1 −1
Original line number Diff line number Diff line
@@ -959,7 +959,7 @@ int i40iw_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
				goto exit;
			}
			if (iwqp->sc_qp.term_flags)
				del_timer(&iwqp->terminate_timer);
				i40iw_terminate_del_timer(&iwqp->sc_qp);
			info.next_iwarp_state = I40IW_QP_STATE_ERROR;
			if ((iwqp->hw_tcp_state > I40IW_TCP_STATE_CLOSED) &&
			    iwdev->iw_status &&