Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA: Use the sg_table directly and remove the opencoded version from umem

This allows using the normal sg_table APIs and makes all the code
cleaner. Remove sgt, nents and nmapd from ib_umem.

Link: https://lore.kernel.org/r/20210824142531.3877007-4-maorg@nvidia.com
Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Maor Gottlieb and committed by
Jason Gunthorpe
79fbd3e1 3e302dbc

+60 -42
+11 -21
drivers/infiniband/core/umem.c
··· 51 51 struct scatterlist *sg; 52 52 unsigned int i; 53 53 54 - if (umem->nmap > 0) 55 - ib_dma_unmap_sg(dev, umem->sg_head.sgl, umem->sg_nents, 56 - DMA_BIDIRECTIONAL); 54 + if (dirty) 55 + ib_dma_unmap_sgtable_attrs(dev, &umem->sgt_append.sgt, 56 + DMA_BIDIRECTIONAL, 0); 57 57 58 - for_each_sg(umem->sg_head.sgl, sg, umem->sg_nents, i) 58 + for_each_sgtable_sg(&umem->sgt_append.sgt, sg, i) 59 59 unpin_user_page_range_dirty_lock(sg_page(sg), 60 60 DIV_ROUND_UP(sg->length, PAGE_SIZE), make_dirty); 61 61 ··· 111 111 /* offset into first SGL */ 112 112 pgoff = umem->address & ~PAGE_MASK; 113 113 114 - for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i) { 114 + for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, i) { 115 115 /* Walk SGL and reduce max page size if VA/PA bits differ 116 116 * for any address. 117 117 */ ··· 121 121 * the maximum possible page size as the low bits of the iova 122 122 * must be zero when starting the next chunk. 123 123 */ 124 - if (i != (umem->nmap - 1)) 124 + if (i != (umem->sgt_append.sgt.nents - 1)) 125 125 mask |= va; 126 126 pgoff = 0; 127 127 } ··· 231 231 &umem->sgt_append, page_list, pinned, 0, 232 232 pinned << PAGE_SHIFT, ib_dma_max_seg_size(device), 233 233 npages, GFP_KERNEL); 234 - umem->sg_nents = umem->sgt_append.sgt.nents; 235 234 if (ret) { 236 - memcpy(&umem->sg_head.sgl, &umem->sgt_append.sgt, 237 - sizeof(umem->sgt_append.sgt)); 238 235 unpin_user_pages_dirty_lock(page_list, pinned, 0); 239 236 goto umem_release; 240 237 } 241 238 } 242 239 243 - memcpy(&umem->sg_head.sgl, &umem->sgt_append.sgt, 244 - sizeof(umem->sgt_append.sgt)); 245 240 if (access & IB_ACCESS_RELAXED_ORDERING) 246 241 dma_attr |= DMA_ATTR_WEAK_ORDERING; 247 242 248 - umem->nmap = 249 - ib_dma_map_sg_attrs(device, umem->sg_head.sgl, umem->sg_nents, 250 - DMA_BIDIRECTIONAL, dma_attr); 251 - 252 - if (!umem->nmap) { 253 - ret = -ENOMEM; 243 + ret = ib_dma_map_sgtable_attrs(device, &umem->sgt_append.sgt, 244 + DMA_BIDIRECTIONAL, dma_attr); 245 + if (ret) 254 246 goto umem_release; 255 - } 256 - 257 - ret = 0; 258 247 goto out; 259 248 260 249 umem_release: ··· 303 314 return -EINVAL; 304 315 } 305 316 306 - ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->sg_nents, dst, length, 317 + ret = sg_pcopy_to_buffer(umem->sgt_append.sgt.sgl, 318 + umem->sgt_append.sgt.orig_nents, dst, length, 307 319 offset + ib_umem_offset(umem)); 308 320 309 321 if (ret < 0)
+2 -3
drivers/infiniband/core/umem_dmabuf.c
··· 55 55 cur += sg_dma_len(sg); 56 56 } 57 57 58 - umem_dmabuf->umem.sg_head.sgl = umem_dmabuf->first_sg; 59 - umem_dmabuf->umem.sg_head.nents = nmap; 60 - umem_dmabuf->umem.nmap = nmap; 58 + umem_dmabuf->umem.sgt_append.sgt.sgl = umem_dmabuf->first_sg; 59 + umem_dmabuf->umem.sgt_append.sgt.nents = nmap; 61 60 umem_dmabuf->sgt = sgt; 62 61 63 62 wait_fence:
+2 -2
drivers/infiniband/hw/hns/hns_roce_db.c
··· 42 42 43 43 found: 44 44 offset = virt - page_addr; 45 - db->dma = sg_dma_address(page->umem->sg_head.sgl) + offset; 46 - db->virt_addr = sg_virt(page->umem->sg_head.sgl) + offset; 45 + db->dma = sg_dma_address(page->umem->sgt_append.sgt.sgl) + offset; 46 + db->virt_addr = sg_virt(page->umem->sgt_append.sgt.sgl) + offset; 47 47 db->u.user_page = page; 48 48 refcount_inc(&page->refcount); 49 49
+1 -1
drivers/infiniband/hw/irdma/verbs.c
··· 2235 2235 pinfo = (level == PBLE_LEVEL_1) ? NULL : palloc->level2.leaf; 2236 2236 2237 2237 if (iwmr->type == IRDMA_MEMREG_TYPE_QP) 2238 - iwpbl->qp_mr.sq_page = sg_page(region->sg_head.sgl); 2238 + iwpbl->qp_mr.sq_page = sg_page(region->sgt_append.sgt.sgl); 2239 2239 2240 2240 rdma_umem_for_each_dma_block(region, &biter, iwmr->page_size) { 2241 2241 *pbl = rdma_block_iter_dma_address(&biter);
+2 -1
drivers/infiniband/hw/mlx4/doorbell.c
··· 75 75 list_add(&page->list, &context->db_page_list); 76 76 77 77 found: 78 - db->dma = sg_dma_address(page->umem->sg_head.sgl) + (virt & ~PAGE_MASK); 78 + db->dma = sg_dma_address(page->umem->sgt_append.sgt.sgl) + 79 + (virt & ~PAGE_MASK); 79 80 db->u.user_page = page; 80 81 ++page->refcnt; 81 82
+2 -2
drivers/infiniband/hw/mlx4/mr.c
··· 200 200 mtt_shift = mtt->page_shift; 201 201 mtt_size = 1ULL << mtt_shift; 202 202 203 - for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i) { 203 + for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, i) { 204 204 if (cur_start_addr + len == sg_dma_address(sg)) { 205 205 /* still the same block */ 206 206 len += sg_dma_len(sg); ··· 273 273 274 274 *num_of_mtts = ib_umem_num_dma_blocks(umem, PAGE_SIZE); 275 275 276 - for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i) { 276 + for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, i) { 277 277 /* 278 278 * Initialization - save the first chunk start as the 279 279 * current_block_start - block means contiguous pages.
+2 -1
drivers/infiniband/hw/mlx5/doorbell.c
··· 78 78 list_add(&page->list, &context->db_page_list); 79 79 80 80 found: 81 - db->dma = sg_dma_address(page->umem->sg_head.sgl) + (virt & ~PAGE_MASK); 81 + db->dma = sg_dma_address(page->umem->sgt_append.sgt.sgl) + 82 + (virt & ~PAGE_MASK); 82 83 db->u.user_page = page; 83 84 ++page->refcnt; 84 85
+2 -1
drivers/infiniband/hw/mlx5/mr.c
··· 1226 1226 orig_sg_length = sg.length; 1227 1227 1228 1228 cur_mtt = mtt; 1229 - rdma_for_each_block (mr->umem->sg_head.sgl, &biter, mr->umem->nmap, 1229 + rdma_for_each_block (mr->umem->sgt_append.sgt.sgl, &biter, 1230 + mr->umem->sgt_append.sgt.nents, 1230 1231 BIT(mr->page_shift)) { 1231 1232 if (cur_mtt == (void *)mtt + sg.length) { 1232 1233 dma_sync_single_for_device(ddev, sg.addr, sg.length,
+1 -1
drivers/infiniband/hw/qedr/verbs.c
··· 1481 1481 return PTR_ERR(srq->prod_umem); 1482 1482 } 1483 1483 1484 - sg = srq->prod_umem->sg_head.sgl; 1484 + sg = srq->prod_umem->sgt_append.sgt.sgl; 1485 1485 srq->hw_srq.phy_prod_pair_addr = sg_dma_address(sg); 1486 1486 1487 1487 return 0;
+1 -1
drivers/infiniband/sw/rdmavt/mr.c
··· 410 410 mr->mr.page_shift = PAGE_SHIFT; 411 411 m = 0; 412 412 n = 0; 413 - for_each_sg_page (umem->sg_head.sgl, &sg_iter, umem->nmap, 0) { 413 + for_each_sgtable_page (&umem->sgt_append.sgt, &sg_iter, 0) { 414 414 void *vaddr; 415 415 416 416 vaddr = page_address(sg_page_iter_page(&sg_iter));
+1 -1
drivers/infiniband/sw/rxe/rxe_mr.c
··· 143 143 if (length > 0) { 144 144 buf = map[0]->buf; 145 145 146 - for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->nmap, 0) { 146 + for_each_sgtable_page (&umem->sgt_append.sgt, &sg_iter, 0) { 147 147 if (num_buf >= RXE_BUF_PER_MAP) { 148 148 map++; 149 149 buf = map[0]->buf;
+5 -7
include/rdma/ib_umem.h
··· 26 26 u32 is_odp : 1; 27 27 u32 is_dmabuf : 1; 28 28 struct work_struct work; 29 - struct sg_append_table sgt_append; 30 - struct sg_table sg_head; 31 - int nmap; 32 - unsigned int sg_nents; 29 + struct sg_append_table sgt_append; 33 30 }; 34 31 35 32 struct ib_umem_dmabuf { ··· 54 57 static inline unsigned long ib_umem_dma_offset(struct ib_umem *umem, 55 58 unsigned long pgsz) 56 59 { 57 - return (sg_dma_address(umem->sg_head.sgl) + ib_umem_offset(umem)) & 60 + return (sg_dma_address(umem->sgt_append.sgt.sgl) + ib_umem_offset(umem)) & 58 61 (pgsz - 1); 59 62 } 60 63 ··· 75 78 struct ib_umem *umem, 76 79 unsigned long pgsz) 77 80 { 78 - __rdma_block_iter_start(biter, umem->sg_head.sgl, umem->nmap, pgsz); 81 + __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl, 82 + umem->sgt_append.sgt.nents, pgsz); 79 83 } 80 84 81 85 /** ··· 127 129 unsigned long pgsz_bitmap, 128 130 u64 pgoff_bitmask) 129 131 { 130 - struct scatterlist *sg = umem->sg_head.sgl; 132 + struct scatterlist *sg = umem->sgt_append.sgt.sgl; 131 133 dma_addr_t dma_addr; 132 134 133 135 dma_addr = sg_dma_address(sg) + (umem->address & ~PAGE_MASK);
+28
include/rdma/ib_verbs.h
··· 4058 4058 } 4059 4059 4060 4060 /** 4061 + * ib_dma_map_sgtable_attrs - Map a scatter/gather table to DMA addresses 4062 + * @dev: The device for which the DMA addresses are to be created 4063 + * @sg: The sg_table object describing the buffer 4064 + * @direction: The direction of the DMA 4065 + * @attrs: Optional DMA attributes for the map operation 4066 + */ 4067 + static inline int ib_dma_map_sgtable_attrs(struct ib_device *dev, 4068 + struct sg_table *sgt, 4069 + enum dma_data_direction direction, 4070 + unsigned long dma_attrs) 4071 + { 4072 + if (ib_uses_virt_dma(dev)) { 4073 + ib_dma_virt_map_sg(dev, sgt->sgl, sgt->orig_nents); 4074 + return 0; 4075 + } 4076 + return dma_map_sgtable(dev->dma_device, sgt, direction, dma_attrs); 4077 + } 4078 + 4079 + static inline void ib_dma_unmap_sgtable_attrs(struct ib_device *dev, 4080 + struct sg_table *sgt, 4081 + enum dma_data_direction direction, 4082 + unsigned long dma_attrs) 4083 + { 4084 + if (!ib_uses_virt_dma(dev)) 4085 + dma_unmap_sgtable(dev->dma_device, sgt, direction, dma_attrs); 4086 + } 4087 + 4088 + /** 4061 4089 * ib_dma_map_sg - Map a scatter/gather list to DMA addresses 4062 4090 * @dev: The device for which the DMA addresses are to be created 4063 4091 * @sg: The array of scatter/gather entries