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

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/zcrx: always dma map in advance

zcrx was originally establisihing dma mappings at a late stage when it
was being bound to a page pool. Dma-buf couldn't work this way, so it's
initialised during area creation.

It's messy having them do it at different spots, just move everything to
the area creation time.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://patch.msgid.link/334092a2cbdd4aabd7c025050aa99f05ace89bb5.1774261953.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Pavel Begunkov and committed by
Jens Axboe
b8d6eb6c 41041562

+15 -29
+15 -29
io_uring/zcrx.c
··· 194 194 { 195 195 struct page **pages; 196 196 int nr_pages, ret; 197 + bool mapped = false; 197 198 198 199 if (area_reg->dmabuf_fd) 199 200 return -EINVAL; ··· 211 210 if (ret) 212 211 goto out_err; 213 212 213 + ret = dma_map_sgtable(ifq->dev, &mem->page_sg_table, 214 + DMA_FROM_DEVICE, IO_DMA_ATTR); 215 + if (ret < 0) 216 + goto out_err; 217 + mapped = true; 218 + 214 219 mem->account_pages = io_count_account_pages(pages, nr_pages); 215 220 ret = io_account_mem(ifq->user, ifq->mm_account, mem->account_pages); 216 221 if (ret < 0) { ··· 230 223 mem->size = area_reg->len; 231 224 return ret; 232 225 out_err: 226 + if (mapped) 227 + dma_unmap_sgtable(ifq->dev, &mem->page_sg_table, 228 + DMA_FROM_DEVICE, IO_DMA_ATTR); 233 229 sg_free_table(&mem->page_sg_table); 234 230 unpin_user_pages(pages, nr_pages); 235 231 kvfree(pages); ··· 296 286 dma_unmap_sgtable(ifq->dev, &area->mem.page_sg_table, 297 287 DMA_FROM_DEVICE, IO_DMA_ATTR); 298 288 } 299 - } 300 - 301 - static int io_zcrx_map_area(struct io_zcrx_ifq *ifq, struct io_zcrx_area *area) 302 - { 303 - int ret; 304 - 305 - guard(mutex)(&ifq->pp_lock); 306 - if (area->is_mapped) 307 - return 0; 308 - 309 - if (!area->mem.is_dmabuf) { 310 - ret = dma_map_sgtable(ifq->dev, &area->mem.page_sg_table, 311 - DMA_FROM_DEVICE, IO_DMA_ATTR); 312 - if (ret < 0) 313 - return ret; 314 - } 315 - 316 - ret = io_populate_area_dma(ifq, area); 317 - if (ret && !area->mem.is_dmabuf) 318 - dma_unmap_sgtable(ifq->dev, &area->mem.page_sg_table, 319 - DMA_FROM_DEVICE, IO_DMA_ATTR); 320 - if (ret == 0) 321 - area->is_mapped = true; 322 - return ret; 323 289 } 324 290 325 291 static void io_zcrx_sync_for_device(struct page_pool *pool, ··· 450 464 ret = io_import_area(ifq, &area->mem, area_reg); 451 465 if (ret) 452 466 goto err; 467 + area->is_mapped = true; 453 468 454 469 if (buf_size_shift > io_area_max_shift(&area->mem)) { 455 470 ret = -ERANGE; ··· 485 498 atomic_set(&area->user_refs[i], 0); 486 499 niov->type = NET_IOV_IOURING; 487 500 } 501 + 502 + ret = io_populate_area_dma(ifq, area); 503 + if (ret) 504 + goto err; 488 505 489 506 area->free_count = nr_iovs; 490 507 /* we're only supporting one area per ifq for now */ ··· 1073 1082 static int io_pp_zc_init(struct page_pool *pp) 1074 1083 { 1075 1084 struct io_zcrx_ifq *ifq = io_pp_to_ifq(pp); 1076 - int ret; 1077 1085 1078 1086 if (WARN_ON_ONCE(!ifq)) 1079 1087 return -EINVAL; ··· 1084 1094 return -EINVAL; 1085 1095 if (pp->p.dma_dir != DMA_FROM_DEVICE) 1086 1096 return -EOPNOTSUPP; 1087 - 1088 - ret = io_zcrx_map_area(ifq, ifq->area); 1089 - if (ret) 1090 - return ret; 1091 1097 1092 1098 refcount_inc(&ifq->refs); 1093 1099 return 0;