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

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.comSigned-off-by: default avatarBob Pearson <rpearsonhpe@gmail.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 02e35244
...@@ -101,26 +101,19 @@ const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num); ...@@ -101,26 +101,19 @@ const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num);
/* rxe_qp.c */ /* rxe_qp.c */
int rxe_qp_chk_init(struct rxe_dev *rxe, struct ib_qp_init_attr *init); 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, int rxe_qp_from_init(struct rxe_dev *rxe, struct rxe_qp *qp, struct rxe_pd *pd,
struct ib_qp_init_attr *init, struct ib_qp_init_attr *init,
struct rxe_create_qp_resp __user *uresp, struct rxe_create_qp_resp __user *uresp,
struct ib_pd *ibpd, struct ib_udata *udata); 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_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, int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp,
struct ib_qp_attr *attr, int mask); struct ib_qp_attr *attr, int mask);
int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr,
int mask, struct ib_udata *udata); int mask, struct ib_udata *udata);
int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask); int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask);
void rxe_qp_error(struct rxe_qp *qp); 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_destroy(struct rxe_qp *qp);
void rxe_qp_cleanup(struct rxe_pool_elem *elem); void rxe_qp_cleanup(struct rxe_pool_elem *elem);
static inline int qp_num(struct rxe_qp *qp) static inline int qp_num(struct rxe_qp *qp)
......
...@@ -114,6 +114,7 @@ static int rxe_mcast_add_grp_elem(struct rxe_dev *rxe, struct rxe_qp *qp, ...@@ -114,6 +114,7 @@ static int rxe_mcast_add_grp_elem(struct rxe_dev *rxe, struct rxe_qp *qp,
grp->num_qp++; grp->num_qp++;
elem->qp = qp; elem->qp = qp;
elem->grp = grp; elem->grp = grp;
atomic_inc(&qp->mcg_num);
list_add(&elem->qp_list, &grp->qp_list); list_add(&elem->qp_list, &grp->qp_list);
list_add(&elem->grp_list, &qp->grp_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, ...@@ -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->qp_list);
list_del(&elem->grp_list); list_del(&elem->grp_list);
grp->num_qp--; grp->num_qp--;
atomic_dec(&qp->mcg_num);
spin_unlock_bh(&grp->mcg_lock); spin_unlock_bh(&grp->mcg_lock);
spin_unlock_bh(&qp->grp_lock); spin_unlock_bh(&qp->grp_lock);
......
...@@ -770,6 +770,20 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask) ...@@ -770,6 +770,20 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)
return 0; 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 */ /* called by the destroy qp verb */
void rxe_qp_destroy(struct rxe_qp *qp) void rxe_qp_destroy(struct rxe_qp *qp)
{ {
......
...@@ -493,6 +493,11 @@ static int rxe_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, ...@@ -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) static int rxe_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
{ {
struct rxe_qp *qp = to_rqp(ibqp); struct rxe_qp *qp = to_rqp(ibqp);
int ret;
ret = rxe_qp_chk_destroy(qp);
if (ret)
return ret;
rxe_qp_destroy(qp); rxe_qp_destroy(qp);
rxe_drop_index(qp); rxe_drop_index(qp);
......
...@@ -235,6 +235,7 @@ struct rxe_qp { ...@@ -235,6 +235,7 @@ struct rxe_qp {
/* list of mcast groups qp has joined (for cleanup) */ /* list of mcast groups qp has joined (for cleanup) */
struct list_head grp_list; struct list_head grp_list;
spinlock_t grp_lock; /* guard grp_list */ spinlock_t grp_lock; /* guard grp_list */
atomic_t mcg_num;
struct sk_buff_head req_pkts; struct sk_buff_head req_pkts;
struct sk_buff_head resp_pkts; struct sk_buff_head resp_pkts;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment