mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
RDMA/core: add bio_vec based RDMA read/write API
The existing rdma_rw_ctx_init() API requires callers to construct a scatterlist, which is then DMA-mapped page by page. Callers that already have data in bio_vec form (such as the NVMe-oF target) must first convert to scatterlist, adding overhead and complexity. Introduce rdma_rw_ctx_init_bvec() and rdma_rw_ctx_destroy_bvec() to accept bio_vec arrays directly. The new helpers use dma_map_phys() for hardware RDMA devices and virtual addressing for software RDMA devices (rxe, siw), avoiding intermediate scatterlist construction. Memory registration (MR) path support is deferred to a follow-up series; callers requiring MR-based transfers (iWARP devices or force_mr=1) receive -EOPNOTSUPP and should use the scatterlist API. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260128005400.25147-2-cel@kernel.org Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
committed by
Leon Romanovsky
parent
959d2c356e
commit
5e54155358
@@ -15,6 +15,7 @@
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/bvec.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/list.h>
|
||||
@@ -4266,6 +4267,47 @@ static inline void ib_dma_unmap_page(struct ib_device *dev,
|
||||
dma_unmap_page(dev->dma_device, addr, size, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_dma_map_bvec - Map a bio_vec to DMA address
|
||||
* @dev: The device for which the dma_addr is to be created
|
||||
* @bvec: The bio_vec to map
|
||||
* @direction: The direction of the DMA
|
||||
*
|
||||
* Returns a DMA address for the bio_vec. The caller must check the
|
||||
* result with ib_dma_mapping_error() before use; a failed mapping
|
||||
* must not be passed to ib_dma_unmap_bvec().
|
||||
*
|
||||
* For software RDMA devices (rxe, siw), returns a virtual address
|
||||
* and no actual DMA mapping occurs.
|
||||
*/
|
||||
static inline u64 ib_dma_map_bvec(struct ib_device *dev,
|
||||
struct bio_vec *bvec,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (ib_uses_virt_dma(dev))
|
||||
return (uintptr_t)bvec_virt(bvec);
|
||||
return dma_map_phys(dev->dma_device, bvec_phys(bvec),
|
||||
bvec->bv_len, direction, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_dma_unmap_bvec - Unmap a bio_vec DMA mapping
|
||||
* @dev: The device for which the DMA address was created
|
||||
* @addr: The DMA address returned by ib_dma_map_bvec()
|
||||
* @size: The size of the region in bytes
|
||||
* @direction: The direction of the DMA
|
||||
*
|
||||
* Releases a DMA mapping created by ib_dma_map_bvec(). For software
|
||||
* RDMA devices this is a no-op since no actual mapping occurred.
|
||||
*/
|
||||
static inline void ib_dma_unmap_bvec(struct ib_device *dev,
|
||||
u64 addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (!ib_uses_virt_dma(dev))
|
||||
dma_unmap_phys(dev->dma_device, addr, size, direction, 0);
|
||||
}
|
||||
|
||||
int ib_dma_virt_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents);
|
||||
static inline int ib_dma_map_sg_attrs(struct ib_device *dev,
|
||||
struct scatterlist *sg, int nents,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef _RDMA_RW_H
|
||||
#define _RDMA_RW_H
|
||||
|
||||
#include <linux/bvec.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <rdma/ib_verbs.h>
|
||||
@@ -49,6 +50,16 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
||||
u32 port_num, struct scatterlist *sg, u32 sg_cnt,
|
||||
enum dma_data_direction dir);
|
||||
|
||||
struct bio_vec;
|
||||
|
||||
int rdma_rw_ctx_init_bvec(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
||||
u32 port_num, const struct bio_vec *bvecs, u32 nr_bvec,
|
||||
struct bvec_iter iter, u64 remote_addr, u32 rkey,
|
||||
enum dma_data_direction dir);
|
||||
void rdma_rw_ctx_destroy_bvec(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
||||
u32 port_num, const struct bio_vec *bvecs, u32 nr_bvec,
|
||||
enum dma_data_direction dir);
|
||||
|
||||
int rdma_rw_ctx_signature_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
||||
u32 port_num, struct scatterlist *sg, u32 sg_cnt,
|
||||
struct scatterlist *prot_sg, u32 prot_sg_cnt,
|
||||
|
||||
Reference in New Issue
Block a user