Commit 222f7a9a authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Doug Ledford
Browse files

IB/rdmavt: Add qp init function



Add an rvt_qp_init() to initialize specific
common fields as the qp is created or reset.

The routine is shared by the rvt_reset_qp() and
the rvt_create_qp().

The intent is that lock dep assertions will only
appear in the rvt_reset_qp().

Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 30a345cc
Loading
Loading
Loading
Loading
+58 −42
Original line number Diff line number Diff line
@@ -493,50 +493,18 @@ static void rvt_remove_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp)
}

/**
 * reset_qp - initialize the QP state to the reset state
 * @qp: the QP to reset
 * rvt_init_qp - initialize the QP state to the reset state
 * @qp: the QP to init or reinit
 * @type: the QP type
 * r and s lock are required to be held by the caller
 *
 * This function is called from both rvt_create_qp() and
 * rvt_reset_qp().   The difference is that the reset
 * patch the necessary locks to protect against concurent
 * access.
 */
static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
static void rvt_init_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
			enum ib_qp_type type)
	__must_hold(&qp->r_lock)
	__must_hold(&qp->s_hlock)
	__must_hold(&qp->s_lock)
{
	if (qp->state != IB_QPS_RESET) {
		qp->state = IB_QPS_RESET;

		/* Let drivers flush their waitlist */
		rdi->driver_f.flush_qp_waiters(qp);
		qp->s_flags &= ~(RVT_S_TIMER | RVT_S_ANY_WAIT);
		spin_unlock(&qp->s_lock);
		spin_unlock(&qp->s_hlock);
		spin_unlock_irq(&qp->r_lock);

		/* Stop the send queue and the retry timer */
		rdi->driver_f.stop_send_queue(qp);

		/* Wait for things to stop */
		rdi->driver_f.quiesce_qp(qp);

		/* take qp out the hash and wait for it to be unused */
		rvt_remove_qp(rdi, qp);
		wait_event(qp->wait, !atomic_read(&qp->refcount));

		/* grab the lock b/c it was locked at call time */
		spin_lock_irq(&qp->r_lock);
		spin_lock(&qp->s_hlock);
		spin_lock(&qp->s_lock);

		rvt_clear_mr_refs(qp, 1);
		/*
		 * Let the driver do any tear down it needs to for a qp
		 * that has been reset
		 */
		rdi->driver_f.notify_qp_reset(qp);
	}

	qp->remote_qpn = 0;
	qp->qkey = 0;
	qp->qp_access_flags = 0;
@@ -581,6 +549,54 @@ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
	atomic_set(&qp->s_reserved_used, 0);
}

/**
 * rvt_reset_qp - initialize the QP state to the reset state
 * @qp: the QP to reset
 * @type: the QP type
 *
 * r_lock, s_hlock, and s_lock are required to be held by the caller
 */
static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
			 enum ib_qp_type type)
	__must_hold(&qp->s_lock)
	__must_hold(&qp->s_hlock)
	__must_hold(&qp->r_lock)
{
	if (qp->state != IB_QPS_RESET) {
		qp->state = IB_QPS_RESET;

		/* Let drivers flush their waitlist */
		rdi->driver_f.flush_qp_waiters(qp);
		qp->s_flags &= ~(RVT_S_TIMER | RVT_S_ANY_WAIT);
		spin_unlock(&qp->s_lock);
		spin_unlock(&qp->s_hlock);
		spin_unlock_irq(&qp->r_lock);

		/* Stop the send queue and the retry timer */
		rdi->driver_f.stop_send_queue(qp);

		/* Wait for things to stop */
		rdi->driver_f.quiesce_qp(qp);

		/* take qp out the hash and wait for it to be unused */
		rvt_remove_qp(rdi, qp);
		wait_event(qp->wait, !atomic_read(&qp->refcount));

		/* grab the lock b/c it was locked at call time */
		spin_lock_irq(&qp->r_lock);
		spin_lock(&qp->s_hlock);
		spin_lock(&qp->s_lock);

		rvt_clear_mr_refs(qp, 1);
		/*
		 * Let the driver do any tear down or re-init it needs to for
		 * a qp that has been reset
		 */
		rdi->driver_f.notify_qp_reset(qp);
	}
	rvt_init_qp(rdi, qp, type);
}

/**
 * rvt_create_qp - create a queue pair for a device
 * @ibpd: the protection domain who's device we create the queue pair for
@@ -761,7 +777,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
		}
		qp->ibqp.qp_num = err;
		qp->port_num = init_attr->port_num;
		rvt_reset_qp(rdi, qp, init_attr->qp_type);
		rvt_init_qp(rdi, qp, init_attr->qp_type);
		break;

	default: