mirror of
https://github.com/torvalds/linux.git
synced 2026-09-28 12:02:03 +02:00
RDMA/mana_ib: extend mana QP table
Enable mana QP table to store UD/GSI QPs. For send queues, set the most significant bit to one, as send and receive WQs can have the same ID in mana. Signed-off-by: Konstantin Taranov <kotaranov@microsoft.com> Link: https://patch.msgid.link/1737394039-28772-12-git-send-email-kotaranov@linux.microsoft.com Reviewed-by: Shiraz Saleem <shirazsaleem@microsoft.com> Reviewed-by: Long Li <longli@microsoft.com> Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
parent
40ebdacb4e
commit
8001e9257e
|
|
@ -704,7 +704,7 @@ mana_ib_event_handler(void *ctx, struct gdma_queue *q, struct gdma_event *event)
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case GDMA_EQE_RNIC_QP_FATAL:
|
case GDMA_EQE_RNIC_QP_FATAL:
|
||||||
qpn = event->details[0];
|
qpn = event->details[0];
|
||||||
qp = mana_get_qp_ref(mdev, qpn);
|
qp = mana_get_qp_ref(mdev, qpn, false);
|
||||||
if (!qp)
|
if (!qp)
|
||||||
break;
|
break;
|
||||||
if (qp->ibqp.event_handler) {
|
if (qp->ibqp.event_handler) {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
/* MANA doesn't have any limit for MR size */
|
/* MANA doesn't have any limit for MR size */
|
||||||
#define MANA_IB_MAX_MR_SIZE U64_MAX
|
#define MANA_IB_MAX_MR_SIZE U64_MAX
|
||||||
|
|
||||||
|
/* Send queue ID mask */
|
||||||
|
#define MANA_SENDQ_MASK BIT(31)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The hardware limit of number of MRs is greater than maximum number of MRs
|
* The hardware limit of number of MRs is greater than maximum number of MRs
|
||||||
* that can possibly represent in 24 bits
|
* that can possibly represent in 24 bits
|
||||||
|
|
@ -438,11 +441,14 @@ static inline struct gdma_context *mdev_to_gc(struct mana_ib_dev *mdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct mana_ib_qp *mana_get_qp_ref(struct mana_ib_dev *mdev,
|
static inline struct mana_ib_qp *mana_get_qp_ref(struct mana_ib_dev *mdev,
|
||||||
uint32_t qid)
|
u32 qid, bool is_sq)
|
||||||
{
|
{
|
||||||
struct mana_ib_qp *qp;
|
struct mana_ib_qp *qp;
|
||||||
unsigned long flag;
|
unsigned long flag;
|
||||||
|
|
||||||
|
if (is_sq)
|
||||||
|
qid |= MANA_SENDQ_MASK;
|
||||||
|
|
||||||
xa_lock_irqsave(&mdev->qp_table_wq, flag);
|
xa_lock_irqsave(&mdev->qp_table_wq, flag);
|
||||||
qp = xa_load(&mdev->qp_table_wq, qid);
|
qp = xa_load(&mdev->qp_table_wq, qid);
|
||||||
if (qp)
|
if (qp)
|
||||||
|
|
|
||||||
|
|
@ -444,18 +444,82 @@ static enum gdma_queue_type mana_ib_queue_type(struct ib_qp_init_attr *attr, u32
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mana_table_store_rc_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
||||||
|
{
|
||||||
|
return xa_insert_irq(&mdev->qp_table_wq, qp->ibqp.qp_num, qp,
|
||||||
|
GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mana_table_remove_rc_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
||||||
|
{
|
||||||
|
xa_erase_irq(&mdev->qp_table_wq, qp->ibqp.qp_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mana_table_store_ud_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
||||||
|
{
|
||||||
|
u32 qids = qp->ud_qp.queues[MANA_UD_SEND_QUEUE].id | MANA_SENDQ_MASK;
|
||||||
|
u32 qidr = qp->ud_qp.queues[MANA_UD_RECV_QUEUE].id;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = xa_insert_irq(&mdev->qp_table_wq, qids, qp, GFP_KERNEL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = xa_insert_irq(&mdev->qp_table_wq, qidr, qp, GFP_KERNEL);
|
||||||
|
if (err)
|
||||||
|
goto remove_sq;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
remove_sq:
|
||||||
|
xa_erase_irq(&mdev->qp_table_wq, qids);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mana_table_remove_ud_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
||||||
|
{
|
||||||
|
u32 qids = qp->ud_qp.queues[MANA_UD_SEND_QUEUE].id | MANA_SENDQ_MASK;
|
||||||
|
u32 qidr = qp->ud_qp.queues[MANA_UD_RECV_QUEUE].id;
|
||||||
|
|
||||||
|
xa_erase_irq(&mdev->qp_table_wq, qids);
|
||||||
|
xa_erase_irq(&mdev->qp_table_wq, qidr);
|
||||||
|
}
|
||||||
|
|
||||||
static int mana_table_store_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
static int mana_table_store_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
||||||
{
|
{
|
||||||
refcount_set(&qp->refcount, 1);
|
refcount_set(&qp->refcount, 1);
|
||||||
init_completion(&qp->free);
|
init_completion(&qp->free);
|
||||||
return xa_insert_irq(&mdev->qp_table_wq, qp->ibqp.qp_num, qp,
|
|
||||||
GFP_KERNEL);
|
switch (qp->ibqp.qp_type) {
|
||||||
|
case IB_QPT_RC:
|
||||||
|
return mana_table_store_rc_qp(mdev, qp);
|
||||||
|
case IB_QPT_UD:
|
||||||
|
case IB_QPT_GSI:
|
||||||
|
return mana_table_store_ud_qp(mdev, qp);
|
||||||
|
default:
|
||||||
|
ibdev_dbg(&mdev->ib_dev, "Unknown QP type for storing in mana table, %d\n",
|
||||||
|
qp->ibqp.qp_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mana_table_remove_qp(struct mana_ib_dev *mdev,
|
static void mana_table_remove_qp(struct mana_ib_dev *mdev,
|
||||||
struct mana_ib_qp *qp)
|
struct mana_ib_qp *qp)
|
||||||
{
|
{
|
||||||
xa_erase_irq(&mdev->qp_table_wq, qp->ibqp.qp_num);
|
switch (qp->ibqp.qp_type) {
|
||||||
|
case IB_QPT_RC:
|
||||||
|
mana_table_remove_rc_qp(mdev, qp);
|
||||||
|
break;
|
||||||
|
case IB_QPT_UD:
|
||||||
|
case IB_QPT_GSI:
|
||||||
|
mana_table_remove_ud_qp(mdev, qp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ibdev_dbg(&mdev->ib_dev, "Unknown QP type for removing from mana table, %d\n",
|
||||||
|
qp->ibqp.qp_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
mana_put_qp_ref(qp);
|
mana_put_qp_ref(qp);
|
||||||
wait_for_completion(&qp->free);
|
wait_for_completion(&qp->free);
|
||||||
}
|
}
|
||||||
|
|
@ -586,8 +650,14 @@ static int mana_ib_create_ud_qp(struct ib_qp *ibqp, struct ib_pd *ibpd,
|
||||||
for (i = 0; i < MANA_UD_QUEUE_TYPE_MAX; ++i)
|
for (i = 0; i < MANA_UD_QUEUE_TYPE_MAX; ++i)
|
||||||
qp->ud_qp.queues[i].kmem->id = qp->ud_qp.queues[i].id;
|
qp->ud_qp.queues[i].kmem->id = qp->ud_qp.queues[i].id;
|
||||||
|
|
||||||
|
err = mana_table_store_qp(mdev, qp);
|
||||||
|
if (err)
|
||||||
|
goto destroy_qp;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
destroy_qp:
|
||||||
|
mana_ib_gd_destroy_ud_qp(mdev, qp);
|
||||||
destroy_shadow_queues:
|
destroy_shadow_queues:
|
||||||
destroy_shadow_queue(&qp->shadow_rq);
|
destroy_shadow_queue(&qp->shadow_rq);
|
||||||
destroy_shadow_queue(&qp->shadow_sq);
|
destroy_shadow_queue(&qp->shadow_sq);
|
||||||
|
|
@ -770,6 +840,8 @@ static int mana_ib_destroy_ud_qp(struct mana_ib_qp *qp, struct ib_udata *udata)
|
||||||
container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev);
|
container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
mana_table_remove_qp(mdev, qp);
|
||||||
|
|
||||||
destroy_shadow_queue(&qp->shadow_rq);
|
destroy_shadow_queue(&qp->shadow_rq);
|
||||||
destroy_shadow_queue(&qp->shadow_sq);
|
destroy_shadow_queue(&qp->shadow_sq);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user