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: Bob Pearson <rpearsonhpe@gmail.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
committed by
Jason Gunthorpe
parent
02e3524474
commit
f9f4846057
@ -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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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 {
|
|||||||
/* 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;
|
||||||
|
Reference in New Issue
Block a user