From: Jacob Moroni <jmoroni@google.com>
To: tatyana.e.nikolova@intel.com, jgg@ziepe.ca, leon@kernel.org
Cc: linux-rdma@vger.kernel.org, Jacob Moroni <jmoroni@google.com>,
Leah Li <leahlijuan@google.com>
Subject: [PATCH rdma-next 2/2] RDMA/irdma: Fix paged PBLE and virtual AEQ for PAGE_SIZE > 4K
Date: Thu, 22 Oct 2026 21:06:50 +0000 [thread overview]
Message-ID: <20261022210650.1182000-3-jmoroni@google.com> (raw)
In-Reply-To: <20261022210650.1182000-1-jmoroni@google.com>
HMC page descriptors and the virtual AEQ PBL always assume 4K
HW pages, but irdma_map_vm_page_list() returns one DMA address
per PAGE_SIZE page and irdma_pble_get_paged_mem() sizes the chunk
as PAGE_SIZE * pg_cnt.
This breaks when PAGE_SIZE is greater than 4K. For example, with
a 64K PAGE_SIZE, the second HW page points to vaddr+64K whereas
the driver assumes it to be at vaddr+4096, etc.
It also ends up using an incorrect chunk size which causes each
paged chunk to claim 16x more PBL entries than what actually exist.
Fix these issues by taking into account the potential difference
between the HW page size (4K) and the system PAGE_SIZE during
allocation and mapping (so on a 64K kernel, each page ends up
populating 16 PDs, etc.).
Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions")
Tested-by: Leah Li <leahlijuan@google.com>
Signed-off-by: Jacob Moroni <jmoroni@google.com>
---
drivers/infiniband/hw/irdma/hw.c | 4 ++--
drivers/infiniband/hw/irdma/utils.c | 22 +++++++++++++---------
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
index fbb8fb47d0d1..1d57b3c9f490 100644
--- a/drivers/infiniband/hw/irdma/hw.c
+++ b/drivers/infiniband/hw/irdma/hw.c
@@ -700,7 +700,7 @@ static void irdma_destroy_cqp(struct irdma_pci_f *rf)
static void irdma_destroy_virt_aeq(struct irdma_pci_f *rf)
{
struct irdma_aeq *aeq = &rf->aeq;
- u32 pg_cnt = DIV_ROUND_UP(aeq->mem.size, PAGE_SIZE);
+ u32 pg_cnt = DIV_ROUND_UP(aeq->mem.size, IRDMA_HW_PAGE_SIZE);
dma_addr_t *pg_arr = (dma_addr_t *)aeq->palloc.level1.addr;
irdma_unmap_vm_page_list(&rf->hw, pg_arr, pg_cnt);
@@ -1479,7 +1479,7 @@ static int irdma_create_virt_aeq(struct irdma_pci_f *rf, u32 size)
if (!aeq->mem.va)
return -ENOMEM;
- pg_cnt = DIV_ROUND_UP(aeq->mem.size, PAGE_SIZE);
+ pg_cnt = DIV_ROUND_UP(aeq->mem.size, IRDMA_HW_PAGE_SIZE);
status = irdma_get_pble(rf->pble_rsrc, &aeq->palloc, pg_cnt, true);
if (status) {
vfree(aeq->mem.va);
diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
index 290ad02ed657..3efc4125bb59 100644
--- a/drivers/infiniband/hw/irdma/utils.c
+++ b/drivers/infiniband/hw/irdma/utils.c
@@ -2199,20 +2199,24 @@ int irdma_map_vm_page_list(struct irdma_hw *hw, void *va, dma_addr_t *pg_dma,
u32 pg_cnt)
{
struct page *vm_page;
- int i;
+ dma_addr_t dma;
+ u32 i, j;
u8 *addr;
addr = (u8 *)(uintptr_t)va;
- for (i = 0; i < pg_cnt; i++) {
+ for (i = 0; i < pg_cnt; i += IRDMA_HW_PAGES_PER_PAGE) {
vm_page = vmalloc_to_page(addr);
if (!vm_page)
goto err;
- pg_dma[i] = dma_map_page(hw->device, vm_page, 0, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(hw->device, pg_dma[i]))
+ dma = dma_map_page(hw->device, vm_page, 0, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(hw->device, dma))
goto err;
+ for (j = 0; j < IRDMA_HW_PAGES_PER_PAGE && i + j < pg_cnt; j++)
+ pg_dma[i + j] = dma + j * IRDMA_HW_PAGE_SIZE;
+
addr += PAGE_SIZE;
}
@@ -2225,9 +2229,9 @@ int irdma_map_vm_page_list(struct irdma_hw *hw, void *va, dma_addr_t *pg_dma,
void irdma_unmap_vm_page_list(struct irdma_hw *hw, dma_addr_t *pg_dma, u32 pg_cnt)
{
- int i;
+ u32 i;
- for (i = 0; i < pg_cnt; i++)
+ for (i = 0; i < pg_cnt; i += IRDMA_HW_PAGES_PER_PAGE)
dma_unmap_page(hw->device, pg_dma[i], PAGE_SIZE, DMA_BIDIRECTIONAL);
}
@@ -2254,7 +2258,7 @@ void irdma_pble_free_paged_mem(struct irdma_chunk *chunk)
/**
* irdma_pble_get_paged_mem -allocate paged memory for pbles
* @chunk: chunk to add for paged memory
- * @pg_cnt: number of pages needed
+ * @pg_cnt: number of HW (4K) pages needed
*/
int irdma_pble_get_paged_mem(struct irdma_chunk *chunk, u32 pg_cnt)
{
@@ -2265,7 +2269,7 @@ int irdma_pble_get_paged_mem(struct irdma_chunk *chunk, u32 pg_cnt)
if (!chunk->dmainfo.dmaaddrs)
return -ENOMEM;
- size = PAGE_SIZE * pg_cnt;
+ size = pg_cnt * IRDMA_HW_PAGE_SIZE;
va = vmalloc(size);
if (!va)
goto err;
--
2.56.0.218.g1ec904b173-goog
next prev parent reply other threads:[~2026-10-22 21:07 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 21:06 [PATCH rdma-next 0/2] RDMA/irdma: Fix FRWR and PBLE handling for PAGE_SIZE > 4K Jacob Moroni
2026-10-22 21:06 ` [PATCH rdma-next 1/2] RDMA/irdma: Fix FRWR logic " Jacob Moroni
2026-10-22 21:13 ` sashiko-bot
2026-10-28 19:59 ` Nikolova, Tatyana E
2026-10-22 21:06 ` Jacob Moroni [this message]
2026-10-22 21:12 ` [PATCH rdma-next 2/2] RDMA/irdma: Fix paged PBLE and virtual AEQ " sashiko-bot
2026-10-28 19:59 ` Nikolova, Tatyana E
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=20261022210650.1182000-3-jmoroni@google.com \
--to=jmoroni@google.com \
--cc=jgg@ziepe.ca \
--cc=leahlijuan@google.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