Commit f9f48460 authored by Bob Pearson's avatar Bob Pearson Committed by Jason Gunthorpe
Browse files

RDMA/rxe: Enforce IBA o10-2.2.3

Add code to check if a QP is attached to one or more multicast groups
when destroy_qp is called and return an error if so.

Link: https://lore.kernel.org/r/20220127213755.31697-5-rpearsonhpe@gmail.com


Signed-off-by: default avatarBob Pearson <rpearsonhpe@gmail.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 02e35244
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -101,26 +101,19 @@ const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num);

/* rxe_qp.c */
int rxe_qp_chk_init(struct rxe_dev *rxe, struct ib_qp_init_attr *init);

int rxe_qp_from_init(struct rxe_dev *rxe, struct rxe_qp *qp, struct rxe_pd *pd,
		     struct ib_qp_init_attr *init,
		     struct rxe_create_qp_resp __user *uresp,
		     struct ib_pd *ibpd, struct ib_udata *udata);

int rxe_qp_to_init(struct rxe_qp *qp, struct ib_qp_init_attr *init);

int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp,
		    struct ib_qp_attr *attr, int mask);

int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr,
		     int mask, struct ib_udata *udata);

int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask);

void rxe_qp_error(struct rxe_qp *qp);

int rxe_qp_chk_destroy(struct rxe_qp *qp);
void rxe_qp_destroy(struct rxe_qp *qp);

void rxe_qp_cleanup(struct rxe_pool_elem *elem);

static inline int qp_num(struct rxe_qp *qp)
+2 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ static int rxe_mcast_add_grp_elem(struct rxe_dev *rxe, struct rxe_qp *qp,
	grp->num_qp++;
	elem->qp = qp;
	elem->grp = grp;
	atomic_inc(&qp->mcg_num);

	list_add(&elem->qp_list, &grp->qp_list);
	list_add(&elem->grp_list, &qp->grp_list);
@@ -143,6 +144,7 @@ static int rxe_mcast_drop_grp_elem(struct rxe_dev *rxe, struct rxe_qp *qp,
			list_del(&elem->qp_list);
			list_del(&elem->grp_list);
			grp->num_qp--;
			atomic_dec(&qp->mcg_num);

			spin_unlock_bh(&grp->mcg_lock);
			spin_unlock_bh(&qp->grp_lock);
+14 −0
Original line number Diff line number Diff line
@@ -770,6 +770,20 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)
	return 0;
}

int rxe_qp_chk_destroy(struct rxe_qp *qp)
{
	/* See IBA o10-2.2.3
	 * An attempt to destroy a QP while attached to a mcast group
	 * will fail immediately.
	 */
	if (atomic_read(&qp->mcg_num)) {
		pr_debug("Attempt to destroy QP while attached to multicast group\n");
		return -EBUSY;
	}

	return 0;
}

/* called by the destroy qp verb */
void rxe_qp_destroy(struct rxe_qp *qp)
{
+5 −0
Original line number Diff line number Diff line
@@ -493,6 +493,11 @@ static int rxe_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
static int rxe_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
{
	struct rxe_qp *qp = to_rqp(ibqp);
	int ret;

	ret = rxe_qp_chk_destroy(qp);
	if (ret)
		return ret;

	rxe_qp_destroy(qp);
	rxe_drop_index(qp);
+1 −0
Original line number Diff line number Diff line
@@ -235,6 +235,7 @@ struct rxe_qp {
	/* list of mcast groups qp has joined (for cleanup) */
	struct list_head	grp_list;
	spinlock_t		grp_lock; /* guard grp_list */
	atomic_t		mcg_num;

	struct sk_buff_head	req_pkts;
	struct sk_buff_head	resp_pkts;