]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA: Move DMA block iterator logic into dedicated files
authorLeon Romanovsky <leonro@nvidia.com>
Fri, 13 Feb 2026 10:57:37 +0000 (12:57 +0200)
committerLeon Romanovsky <leonro@nvidia.com>
Wed, 25 Feb 2026 13:15:30 +0000 (08:15 -0500)
The DMA iterator logic was mixed into verbs and umem-specific code,
forcing all users to include rdma/ib_umem.h. Move the block iterator
logic into iter.c and rdma/iter.h so that rdma/ib_umem.h and
rdma/ib_verbs.h can be separated in a follow-up patch.

Link: https://patch.msgid.link/20260213-refactor-umem-v1-1-f3be85847922@nvidia.com
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
21 files changed:
drivers/infiniband/core/Makefile
drivers/infiniband/core/iter.c [new file with mode: 0644]
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/bnxt_re/qplib_res.c
drivers/infiniband/hw/cxgb4/mem.c
drivers/infiniband/hw/efa/efa_verbs.c
drivers/infiniband/hw/erdma/erdma_verbs.c
drivers/infiniband/hw/hns/hns_roce_alloc.c
drivers/infiniband/hw/ionic/ionic_ibdev.h
drivers/infiniband/hw/irdma/main.h
drivers/infiniband/hw/mana/mana_ib.h
drivers/infiniband/hw/mlx4/mr.c
drivers/infiniband/hw/mlx5/mem.c
drivers/infiniband/hw/mlx5/umr.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
include/rdma/ib_umem.h
include/rdma/ib_verbs.h
include/rdma/iter.h [new file with mode: 0644]

index a2a7a9d2e0d3e8b07b4c7ed8524a5723a2fe1099..deffb03c45746869e0fd32fd117dcbf366d1de4e 100644 (file)
@@ -12,7 +12,7 @@ ib_core-y :=                  packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \
                                roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \
                                multicast.o mad.o smi.o agent.o mad_rmpp.o \
                                nldev.o restrack.o counters.o ib_core_uverbs.o \
-                               trace.o lag.o
+                               trace.o lag.o iter.o
 
 ib_core-$(CONFIG_SECURITY_INFINIBAND) += security.o
 ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o
diff --git a/drivers/infiniband/core/iter.c b/drivers/infiniband/core/iter.c
new file mode 100644 (file)
index 0000000..8e543d1
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. */
+
+#include <linux/export.h>
+#include <rdma/iter.h>
+
+void __rdma_block_iter_start(struct ib_block_iter *biter,
+                            struct scatterlist *sglist, unsigned int nents,
+                            unsigned long pgsz)
+{
+       memset(biter, 0, sizeof(struct ib_block_iter));
+       biter->__sg = sglist;
+       biter->__sg_nents = nents;
+
+       /* Driver provides best block size to use */
+       biter->__pg_bit = __fls(pgsz);
+}
+EXPORT_SYMBOL(__rdma_block_iter_start);
+
+bool __rdma_block_iter_next(struct ib_block_iter *biter)
+{
+       unsigned int block_offset;
+       unsigned int delta;
+
+       if (!biter->__sg_nents || !biter->__sg)
+               return false;
+
+       biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
+       block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
+       delta = BIT_ULL(biter->__pg_bit) - block_offset;
+
+       while (biter->__sg_nents && biter->__sg &&
+              sg_dma_len(biter->__sg) - biter->__sg_advance <= delta) {
+               delta -= sg_dma_len(biter->__sg) - biter->__sg_advance;
+               biter->__sg_advance = 0;
+               biter->__sg = sg_next(biter->__sg);
+               biter->__sg_nents--;
+       }
+       biter->__sg_advance += delta;
+
+       return true;
+}
+EXPORT_SYMBOL(__rdma_block_iter_next);
index 575b4a4b200bbfbfcbfca981eba186a13b2a92cd..dc2c46f3bf648e1cbb414a3ef5d38aba9c851d22 100644 (file)
@@ -3154,44 +3154,6 @@ int rdma_init_netdev(struct ib_device *device, u32 port_num,
 }
 EXPORT_SYMBOL(rdma_init_netdev);
 
-void __rdma_block_iter_start(struct ib_block_iter *biter,
-                            struct scatterlist *sglist, unsigned int nents,
-                            unsigned long pgsz)
-{
-       memset(biter, 0, sizeof(struct ib_block_iter));
-       biter->__sg = sglist;
-       biter->__sg_nents = nents;
-
-       /* Driver provides best block size to use */
-       biter->__pg_bit = __fls(pgsz);
-}
-EXPORT_SYMBOL(__rdma_block_iter_start);
-
-bool __rdma_block_iter_next(struct ib_block_iter *biter)
-{
-       unsigned int block_offset;
-       unsigned int delta;
-
-       if (!biter->__sg_nents || !biter->__sg)
-               return false;
-
-       biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
-       block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
-       delta = BIT_ULL(biter->__pg_bit) - block_offset;
-
-       while (biter->__sg_nents && biter->__sg &&
-              sg_dma_len(biter->__sg) - biter->__sg_advance <= delta) {
-               delta -= sg_dma_len(biter->__sg) - biter->__sg_advance;
-               biter->__sg_advance = 0;
-               biter->__sg = sg_next(biter->__sg);
-               biter->__sg_nents--;
-       }
-       biter->__sg_advance += delta;
-
-       return true;
-}
-EXPORT_SYMBOL(__rdma_block_iter_next);
-
 /**
  * rdma_alloc_hw_stats_struct - Helper function to allocate dynamic struct
  *   for the drivers.
index 341bae3d8a1d9bafd5303bd7e77eaf9fdaeb8315..41ad8c2018fdcd4e6d6bbf4a777410f944f42f7e 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/if_vlan.h>
 #include <linux/vmalloc.h>
 #include <rdma/ib_verbs.h>
-#include <rdma/ib_umem.h>
+#include <rdma/iter.h>
 
 #include "roce_hsi.h"
 #include "qplib_res.h"
index b8d49abde0994032708767736d5e98b1b0530300..9fde78b746900b65fefe070b76ef36e313f065ae 100644 (file)
@@ -32,9 +32,9 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <rdma/ib_umem.h>
 #include <linux/atomic.h>
 #include <rdma/ib_user_verbs.h>
+#include <rdma/iter.h>
 
 #include "iw_cxgb4.h"
 
index bb59c02b807c54bb5675b1fa7a11044faf8a0a6d..1ef9da94b98ff83bb6497441aa3832777d136a45 100644 (file)
@@ -9,9 +9,9 @@
 #include <linux/log2.h>
 
 #include <rdma/ib_addr.h>
-#include <rdma/ib_umem.h>
 #include <rdma/ib_user_verbs.h>
 #include <rdma/ib_verbs.h>
+#include <rdma/iter.h>
 #include <rdma/uverbs_ioctl.h>
 #define UVERBS_MODULE_NAME efa_ib
 #include <rdma/uverbs_named_ioctl.h>
index 9f74aadc304709c7f79222ae2925d6e285862ec2..04136a0281aa4c0da42cc66dfeecd096cb40a283 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/vmalloc.h>
 #include <net/addrconf.h>
 #include <rdma/erdma-abi.h>
-#include <rdma/ib_umem.h>
+#include <rdma/iter.h>
 #include <rdma/uverbs_ioctl.h>
 
 #include "erdma.h"
index 8e802f118bc92c432eb1d057d187ca6ce28ab228..142c86f462fa957de28afe832a69d74c68698c72 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include <linux/vmalloc.h>
-#include <rdma/ib_umem.h>
+#include <rdma/iter.h>
 #include "hns_roce_device.h"
 
 void hns_roce_buf_free(struct hns_roce_dev *hr_dev, struct hns_roce_buf *buf)
index 82fda1e3cdb65f731319e80dfbe2a316c6c89f93..63828240d6590b40a1af28214a90228d3c838b6c 100644 (file)
@@ -4,9 +4,9 @@
 #ifndef _IONIC_IBDEV_H_
 #define _IONIC_IBDEV_H_
 
-#include <rdma/ib_umem.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_pack.h>
+#include <rdma/iter.h>
 #include <rdma/uverbs_ioctl.h>
 
 #include <rdma/ionic-abi.h>
index d320d1a228b33473b72ed6f287a564ad93901663..3d49bd57bae7cf56923b48def0417239aed4f812 100644 (file)
@@ -37,8 +37,8 @@
 #include <rdma/rdma_cm.h>
 #include <rdma/iw_cm.h>
 #include <rdma/ib_user_verbs.h>
-#include <rdma/ib_umem.h>
 #include <rdma/ib_cache.h>
+#include <rdma/iter.h>
 #include <rdma/uverbs_ioctl.h>
 #include "osdep.h"
 #include "defs.h"
index e447acfd2071a439bf9f962b2ff6e5aff2a9a084..a7c8c0fd70192e98900d8085104c3ba806c1078e 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_mad.h>
-#include <rdma/ib_umem.h>
+#include <rdma/iter.h>
 #include <rdma/mana-abi.h>
 #include <rdma/uverbs_ioctl.h>
 #include <linux/dmapool.h>
index 77a72d2b0dd23f38a6100b8590959e6e7ab274bf..650b4a9121ff6d6e149eb16217f9dd7b57907094 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/slab.h>
 #include <rdma/ib_user_verbs.h>
+#include <rdma/iter.h>
 
 #include "mlx4_ib.h"
 
index af321f6ef7f5477a778e8898f245a31530156981..75d5b5672b5cf3dafbb60ba51cbe4a87fa5bc35c 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <rdma/ib_umem_odp.h>
+#include <rdma/iter.h>
 #include "mlx5_ib.h"
 
 /*
index 4e562e0dd9e125acb1bcd6558b68def07c271722..29488fba21a034f0d5eefe2d98a2b92ec08c8245 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
 
 #include <rdma/ib_umem_odp.h>
+#include <rdma/iter.h>
 #include "mlx5_ib.h"
 #include "umr.h"
 #include "wr.h"
index ef0635064fbaf39763c0518f30b8b902130cc490..ee1d3583bbb9da10574e49af62d44ca45e3fe6ca 100644 (file)
@@ -35,8 +35,8 @@
  */
 
 #include <rdma/ib_smi.h>
-#include <rdma/ib_umem.h>
 #include <rdma/ib_user_verbs.h>
+#include <rdma/iter.h>
 #include <rdma/uverbs_ioctl.h>
 
 #include <linux/sched.h>
index e89be2fbd5eb2708b3d94e58dfa39e98562b1950..c73d4bbee71fcf2b01f96117790bec7a7d904b86 100644 (file)
@@ -45,9 +45,9 @@
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_user_verbs.h>
 #include <rdma/iw_cm.h>
-#include <rdma/ib_umem.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib_cache.h>
+#include <rdma/iter.h>
 #include <rdma/uverbs_ioctl.h>
 
 #include "ocrdma.h"
index 33b4a0e6d3a8fa04c724f15772752ffa18f75f46..2fa9e07710d31f821569e77db44ecef4f3dbc177 100644 (file)
@@ -39,9 +39,9 @@
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_user_verbs.h>
 #include <rdma/iw_cm.h>
-#include <rdma/ib_umem.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib_cache.h>
+#include <rdma/iter.h>
 #include <rdma/uverbs_ioctl.h>
 
 #include <linux/qed/common_hsi.h>
index 763ddc6f25d1ae9aca097bcc3de9f9d86425baf4..23e547d4b3a715e5843b2f93853816b8dbf46ffd 100644 (file)
@@ -53,8 +53,8 @@
 #include <linux/pci.h>
 #include <linux/semaphore.h>
 #include <linux/workqueue.h>
-#include <rdma/ib_umem.h>
 #include <rdma/ib_verbs.h>
+#include <rdma/iter.h>
 #include <rdma/vmw_pvrdma-abi.h>
 
 #include "pvrdma_ring.h"
index 09b7f7d4685ed851b56b5cb505251285543c7a98..db92d4623647b0ebec6c203537f48544bd54b3cd 100644 (file)
@@ -75,38 +75,6 @@ static inline size_t ib_umem_num_pages(struct ib_umem *umem)
 {
        return ib_umem_num_dma_blocks(umem, PAGE_SIZE);
 }
-
-static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter,
-                                               struct ib_umem *umem,
-                                               unsigned long pgsz)
-{
-       __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl,
-                               umem->sgt_append.sgt.nents, pgsz);
-       biter->__sg_advance = ib_umem_offset(umem) & ~(pgsz - 1);
-       biter->__sg_numblocks = ib_umem_num_dma_blocks(umem, pgsz);
-}
-
-static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter)
-{
-       return __rdma_block_iter_next(biter) && biter->__sg_numblocks--;
-}
-
-/**
- * rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem
- * @umem: umem to iterate over
- * @biter: block iterator variable
- * @pgsz: Page size to split the list into
- *
- * pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The
- * returned DMA blocks will be aligned to pgsz and span the range:
- * ALIGN_DOWN(umem->address, pgsz) to ALIGN(umem->address + umem->length, pgsz)
- *
- * Performs exactly ib_umem_num_dma_blocks() iterations.
- */
-#define rdma_umem_for_each_dma_block(umem, biter, pgsz)                        \
-       for (__rdma_umem_block_iter_start(biter, umem, pgsz);                  \
-            __rdma_umem_block_iter_next(biter);)
-
 #ifdef CONFIG_INFINIBAND_USER_MEM
 
 struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
index 3f3827e1c711d8048cb58c0ef3d11caafeef8985..7bdd77ed7e20a9b4ef7882a052a5698169eb8398 100644 (file)
@@ -2959,22 +2959,6 @@ struct ib_client {
        u8 no_kverbs_req:1;
 };
 
-/*
- * IB block DMA iterator
- *
- * Iterates the DMA-mapped SGL in contiguous memory blocks aligned
- * to a HW supported page size.
- */
-struct ib_block_iter {
-       /* internal states */
-       struct scatterlist *__sg;       /* sg holding the current aligned block */
-       dma_addr_t __dma_addr;          /* unaligned DMA address of this block */
-       size_t __sg_numblocks;          /* ib_umem_num_dma_blocks() */
-       unsigned int __sg_nents;        /* number of SG entries */
-       unsigned int __sg_advance;      /* number of bytes to advance in sg in next step */
-       unsigned int __pg_bit;          /* alignment of current block */
-};
-
 struct ib_device *_ib_alloc_device(size_t size, struct net *net);
 #define ib_alloc_device(drv_struct, member)                                    \
        container_of(_ib_alloc_device(sizeof(struct drv_struct) +              \
@@ -3003,38 +2987,6 @@ void ib_unregister_device_queued(struct ib_device *ib_dev);
 int ib_register_client   (struct ib_client *client);
 void ib_unregister_client(struct ib_client *client);
 
-void __rdma_block_iter_start(struct ib_block_iter *biter,
-                            struct scatterlist *sglist,
-                            unsigned int nents,
-                            unsigned long pgsz);
-bool __rdma_block_iter_next(struct ib_block_iter *biter);
-
-/**
- * rdma_block_iter_dma_address - get the aligned dma address of the current
- * block held by the block iterator.
- * @biter: block iterator holding the memory block
- */
-static inline dma_addr_t
-rdma_block_iter_dma_address(struct ib_block_iter *biter)
-{
-       return biter->__dma_addr & ~(BIT_ULL(biter->__pg_bit) - 1);
-}
-
-/**
- * rdma_for_each_block - iterate over contiguous memory blocks of the sg list
- * @sglist: sglist to iterate over
- * @biter: block iterator holding the memory block
- * @nents: maximum number of sg entries to iterate over
- * @pgsz: best HW supported page size to use
- *
- * Callers may use rdma_block_iter_dma_address() to get each
- * blocks aligned DMA address.
- */
-#define rdma_for_each_block(sglist, biter, nents, pgsz)                \
-       for (__rdma_block_iter_start(biter, sglist, nents,      \
-                                    pgsz);                     \
-            __rdma_block_iter_next(biter);)
-
 /**
  * ib_get_client_data - Get IB client context
  * @device:Device to get context for
diff --git a/include/rdma/iter.h b/include/rdma/iter.h
new file mode 100644 (file)
index 0000000..19d64ef
--- /dev/null
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. */
+
+#ifndef _RDMA_ITER_H_
+#define _RDMA_ITER_H_
+
+#include <linux/scatterlist.h>
+#include <rdma/ib_umem.h>
+
+/**
+ * IB block DMA iterator
+ *
+ * Iterates the DMA-mapped SGL in contiguous memory blocks aligned
+ * to a HW supported page size.
+ */
+struct ib_block_iter {
+       /* internal states */
+       struct scatterlist *__sg;       /* sg holding the current aligned block */
+       dma_addr_t __dma_addr;          /* unaligned DMA address of this block */
+       size_t __sg_numblocks;          /* ib_umem_num_dma_blocks() */
+       unsigned int __sg_nents;        /* number of SG entries */
+       unsigned int __sg_advance;      /* number of bytes to advance in sg in next step */
+       unsigned int __pg_bit;          /* alignment of current block */
+};
+
+void __rdma_block_iter_start(struct ib_block_iter *biter,
+                            struct scatterlist *sglist,
+                            unsigned int nents,
+                            unsigned long pgsz);
+bool __rdma_block_iter_next(struct ib_block_iter *biter);
+
+/**
+ * rdma_block_iter_dma_address - get the aligned dma address of the current
+ * block held by the block iterator.
+ * @biter: block iterator holding the memory block
+ */
+static inline dma_addr_t
+rdma_block_iter_dma_address(struct ib_block_iter *biter)
+{
+       return biter->__dma_addr & ~(BIT_ULL(biter->__pg_bit) - 1);
+}
+
+/**
+ * rdma_for_each_block - iterate over contiguous memory blocks of the sg list
+ * @sglist: sglist to iterate over
+ * @biter: block iterator holding the memory block
+ * @nents: maximum number of sg entries to iterate over
+ * @pgsz: best HW supported page size to use
+ *
+ * Callers may use rdma_block_iter_dma_address() to get each
+ * blocks aligned DMA address.
+ */
+#define rdma_for_each_block(sglist, biter, nents, pgsz)                \
+       for (__rdma_block_iter_start(biter, sglist, nents,      \
+                                    pgsz);                     \
+            __rdma_block_iter_next(biter);)
+
+static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter,
+                                               struct ib_umem *umem,
+                                               unsigned long pgsz)
+{
+       __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl,
+                               umem->sgt_append.sgt.nents, pgsz);
+       biter->__sg_advance = ib_umem_offset(umem) & ~(pgsz - 1);
+       biter->__sg_numblocks = ib_umem_num_dma_blocks(umem, pgsz);
+}
+
+static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter)
+{
+       return __rdma_block_iter_next(biter) && biter->__sg_numblocks--;
+}
+
+/**
+ * rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem
+ * @umem: umem to iterate over
+ * @pgsz: Page size to split the list into
+ *
+ * pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The
+ * returned DMA blocks will be aligned to pgsz and span the range:
+ * ALIGN_DOWN(umem->address, pgsz) to ALIGN(umem->address + umem->length, pgsz)
+ *
+ * Performs exactly ib_umem_num_dma_blocks() iterations.
+ */
+#define rdma_umem_for_each_dma_block(umem, biter, pgsz)                        \
+       for (__rdma_umem_block_iter_start(biter, umem, pgsz);                  \
+            __rdma_umem_block_iter_next(biter);)
+
+#endif /* _RDMA_ITER_H_ */