From: Jacob Moroni <jmoroni@google.com>
To: tatyana.e.nikolova@intel.com, krzysztof.czurylo@intel.com
Cc: jgg@ziepe.ca, leon@kernel.org, linux-rdma@vger.kernel.org,
Jacob Moroni <jmoroni@google.com>
Subject: [PATCH rdma-next] RDMA/irdma: Convert QP table to xarray
Date: Sun, 18 Jan 2026 01:25:00 +0000 [thread overview]
Message-ID: <20260118012500.681672-1-jmoroni@google.com> (raw)
Some devices can support a very large number of QPs, so convert
the qp_table array into xarray for more efficient memory usage.
This should reduce common-case memory usage by megabytes.
Also, remove the space that was being reserved for the srq table
which doesn't exist.
Tested with KASAN+lockdep and a full cycle of QP/CQ create/destroy
for the entire ID space.
Signed-off-by: Jacob Moroni <jmoroni@google.com>
---
drivers/infiniband/hw/irdma/cm.c | 8 ++++----
drivers/infiniband/hw/irdma/hw.c | 17 +++++++----------
drivers/infiniband/hw/irdma/main.h | 3 +--
drivers/infiniband/hw/irdma/utils.c | 15 ++++++++++-----
drivers/infiniband/hw/irdma/verbs.c | 9 +++++++--
5 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
index f4f4f92ba..3104f3870 100644
--- a/drivers/infiniband/hw/irdma/cm.c
+++ b/drivers/infiniband/hw/irdma/cm.c
@@ -3448,9 +3448,9 @@ void irdma_cm_disconn(struct irdma_qp *iwqp)
if (!work)
return;
- spin_lock_irqsave(&iwdev->rf->qptable_lock, flags);
- if (!iwdev->rf->qp_table[iwqp->ibqp.qp_num]) {
- spin_unlock_irqrestore(&iwdev->rf->qptable_lock, flags);
+ xa_lock_irqsave(&iwdev->rf->qp_xa, flags);
+ if (!xa_load(&iwdev->rf->qp_xa, iwqp->ibqp.qp_num)) {
+ xa_unlock_irqrestore(&iwdev->rf->qp_xa, flags);
ibdev_dbg(&iwdev->ibdev,
"CM: qp_id %d is already freed\n",
iwqp->ibqp.qp_num);
@@ -3458,7 +3458,7 @@ void irdma_cm_disconn(struct irdma_qp *iwqp)
return;
}
irdma_qp_add_ref(&iwqp->ibqp);
- spin_unlock_irqrestore(&iwdev->rf->qptable_lock, flags);
+ xa_unlock_irqrestore(&iwdev->rf->qp_xa, flags);
work->iwqp = iwqp;
INIT_WORK(&work->work, irdma_disconnect_worker);
diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
index 31c67b753..d01fcba7f 100644
--- a/drivers/infiniband/hw/irdma/hw.c
+++ b/drivers/infiniband/hw/irdma/hw.c
@@ -313,11 +313,10 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
info->iwarp_state, info->ae_src);
if (info->qp) {
- spin_lock_irqsave(&rf->qptable_lock, flags);
- iwqp = rf->qp_table[info->qp_cq_id];
+ xa_lock_irqsave(&rf->qp_xa, flags);
+ iwqp = xa_load(&rf->qp_xa, info->qp_cq_id);
if (!iwqp) {
- spin_unlock_irqrestore(&rf->qptable_lock,
- flags);
+ xa_unlock_irqrestore(&rf->qp_xa, flags);
if (info->ae_id == IRDMA_AE_QP_SUSPEND_COMPLETE) {
atomic_dec(&iwdev->vsi.qp_suspend_reqs);
wake_up(&iwdev->suspend_wq);
@@ -328,7 +327,7 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
continue;
}
irdma_qp_add_ref(&iwqp->ibqp);
- spin_unlock_irqrestore(&rf->qptable_lock, flags);
+ xa_unlock_irqrestore(&rf->qp_xa, flags);
qp = &iwqp->sc_qp;
spin_lock_irqsave(&iwqp->lock, flags);
iwqp->hw_tcp_state = info->tcp_state;
@@ -1701,6 +1700,7 @@ static void irdma_del_init_mem(struct irdma_pci_f *rf)
dev->hmc_info->sd_table.sd_entry = NULL;
vfree(rf->mem_rsrc);
rf->mem_rsrc = NULL;
+ xa_destroy(&rf->qp_xa);
dma_free_coherent(rf->hw.device, rf->obj_mem.size, rf->obj_mem.va,
rf->obj_mem.pa);
rf->obj_mem.va = NULL;
@@ -2091,13 +2091,12 @@ static void irdma_set_hw_rsrc(struct irdma_pci_f *rf)
rf->allocated_ahs = &rf->allocated_pds[BITS_TO_LONGS(rf->max_pd)];
rf->allocated_mcgs = &rf->allocated_ahs[BITS_TO_LONGS(rf->max_ah)];
rf->allocated_arps = &rf->allocated_mcgs[BITS_TO_LONGS(rf->max_mcg)];
- rf->qp_table = (struct irdma_qp **)
+ rf->cq_table = (struct irdma_cq **)
(&rf->allocated_arps[BITS_TO_LONGS(rf->arp_table_size)]);
- rf->cq_table = (struct irdma_cq **)(&rf->qp_table[rf->max_qp]);
+ xa_init_flags(&rf->qp_xa, XA_FLAGS_LOCK_IRQ);
spin_lock_init(&rf->rsrc_lock);
spin_lock_init(&rf->arp_lock);
- spin_lock_init(&rf->qptable_lock);
spin_lock_init(&rf->cqtable_lock);
spin_lock_init(&rf->qh_list_lock);
}
@@ -2119,9 +2118,7 @@ static u32 irdma_calc_mem_rsrc_size(struct irdma_pci_f *rf)
rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->arp_table_size);
rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_ah);
rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_mcg);
- rsrc_size += sizeof(struct irdma_qp **) * rf->max_qp;
rsrc_size += sizeof(struct irdma_cq **) * rf->max_cq;
- rsrc_size += sizeof(struct irdma_srq **) * rf->max_srq;
return rsrc_size;
}
diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h
index d320d1a22..6fd3dbef1 100644
--- a/drivers/infiniband/hw/irdma/main.h
+++ b/drivers/infiniband/hw/irdma/main.h
@@ -321,9 +321,8 @@ struct irdma_pci_f {
struct irdma_arp_entry *arp_table;
spinlock_t arp_lock; /*protect ARP table access*/
spinlock_t rsrc_lock; /* protect HW resource array access */
- spinlock_t qptable_lock; /*protect QP table access*/
spinlock_t cqtable_lock; /*protect CQ table access*/
- struct irdma_qp **qp_table;
+ struct xarray qp_xa;
struct irdma_cq **cq_table;
spinlock_t qh_list_lock; /* protect mc_qht_list */
struct mc_table_list mc_qht_list;
diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
index 08b23e24e..34e332ba1 100644
--- a/drivers/infiniband/hw/irdma/utils.c
+++ b/drivers/infiniband/hw/irdma/utils.c
@@ -798,15 +798,15 @@ void irdma_qp_rem_ref(struct ib_qp *ibqp)
u32 qp_num;
unsigned long flags;
- spin_lock_irqsave(&iwdev->rf->qptable_lock, flags);
+ xa_lock_irqsave(&iwdev->rf->qp_xa, flags);
if (!refcount_dec_and_test(&iwqp->refcnt)) {
- spin_unlock_irqrestore(&iwdev->rf->qptable_lock, flags);
+ xa_unlock_irqrestore(&iwdev->rf->qp_xa, flags);
return;
}
qp_num = iwqp->ibqp.qp_num;
- iwdev->rf->qp_table[qp_num] = NULL;
- spin_unlock_irqrestore(&iwdev->rf->qptable_lock, flags);
+ __xa_erase(&iwdev->rf->qp_xa, qp_num);
+ xa_unlock_irqrestore(&iwdev->rf->qp_xa, flags);
complete(&iwqp->free_qp);
}
@@ -849,11 +849,16 @@ struct ib_device *to_ibdev(struct irdma_sc_dev *dev)
struct ib_qp *irdma_get_qp(struct ib_device *device, int qpn)
{
struct irdma_device *iwdev = to_iwdev(device);
+ struct irdma_qp *iqp;
if (qpn < IW_FIRST_QPN || qpn >= iwdev->rf->max_qp)
return NULL;
- return &iwdev->rf->qp_table[qpn]->ibqp;
+ iqp = xa_load(&iwdev->rf->qp_xa, qpn);
+ if (!iqp)
+ return NULL;
+
+ return &iqp->ibqp;
}
/**
diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index cf8d19150..9d80388f4 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -1104,7 +1104,13 @@ static int irdma_create_qp(struct ib_qp *ibqp,
spin_lock_init(&iwqp->lock);
spin_lock_init(&iwqp->sc_qp.pfpdu.lock);
iwqp->sig_all = init_attr->sq_sig_type == IB_SIGNAL_ALL_WR;
- rf->qp_table[qp_num] = iwqp;
+ init_completion(&iwqp->free_qp);
+
+ err_code = xa_err(xa_store_irq(&rf->qp_xa, qp_num, iwqp, GFP_KERNEL));
+ if (err_code) {
+ irdma_destroy_qp(&iwqp->ibqp, udata);
+ return err_code;
+ }
if (udata) {
/* GEN_1 legacy support with libi40iw does not have expanded uresp struct */
@@ -1129,7 +1135,6 @@ static int irdma_create_qp(struct ib_qp *ibqp,
}
}
- init_completion(&iwqp->free_qp);
return 0;
error:
--
2.52.0.457.g6b5491de43-goog
next reply other threads:[~2026-01-18 1:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-18 1:25 Jacob Moroni [this message]
2026-01-19 12:53 ` [PATCH rdma-next] RDMA/irdma: Convert QP table to xarray Czurylo, Krzysztof
2026-01-19 15:56 ` Jacob Moroni
2026-01-20 18:58 ` Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260118012500.681672-1-jmoroni@google.com \
--to=jmoroni@google.com \
--cc=jgg@ziepe.ca \
--cc=krzysztof.czurylo@intel.com \
--cc=leon@kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=tatyana.e.nikolova@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox