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.

drm/prime: split array import functions v4

Mapping the imported pages of a DMA-buf into an userspace process
doesn't work as expected.

But we have reoccurring requests on this approach, so split the
functions for this and document that dma_buf_mmap() needs to be used
instead.

v2: split it into two functions
v3: rebased on latest changes
v4: update commit message a bit

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/403838/

+62 -53
+4 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 918 918 goto release_sg; 919 919 920 920 /* convert SG to linear array of pages and dma addresses */ 921 - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, gtt->ttm.dma_address, 922 - ttm->num_pages); 921 + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, 922 + ttm->num_pages); 923 923 924 924 return 0; 925 925 ··· 1264 1264 ttm->sg = sgt; 1265 1265 } 1266 1266 1267 - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, 1268 - gtt->ttm.dma_address, 1269 - ttm->num_pages); 1267 + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, 1268 + ttm->num_pages); 1270 1269 return 0; 1271 1270 } 1272 1271
+41 -27
drivers/gpu/drm/drm_prime.c
··· 978 978 EXPORT_SYMBOL(drm_gem_prime_import); 979 979 980 980 /** 981 - * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array 981 + * drm_prime_sg_to_page_array - convert an sg table into a page array 982 982 * @sgt: scatter-gather table to convert 983 - * @pages: optional array of page pointers to store the page array in 984 - * @addrs: optional array to store the dma bus address of each page 985 - * @max_entries: size of both the passed-in arrays 983 + * @pages: array of page pointers to store the pages in 984 + * @max_entries: size of the passed-in array 986 985 * 987 - * Exports an sg table into an array of pages and addresses. This is currently 988 - * required by the TTM driver in order to do correct fault handling. 986 + * Exports an sg table into an array of pages. 989 987 * 990 - * Drivers can use this in their &drm_driver.gem_prime_import_sg_table 991 - * implementation. 988 + * This function is deprecated and strongly discouraged to be used. 989 + * The page array is only useful for page faults and those can corrupt fields 990 + * in the struct page if they are not handled by the exporting driver. 992 991 */ 993 - int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, 994 - dma_addr_t *addrs, int max_entries) 992 + int __deprecated drm_prime_sg_to_page_array(struct sg_table *sgt, 993 + struct page **pages, 994 + int max_entries) 995 995 { 996 - struct sg_dma_page_iter dma_iter; 997 996 struct sg_page_iter page_iter; 998 997 struct page **p = pages; 999 - dma_addr_t *a = addrs; 1000 998 1001 - if (pages) { 1002 - for_each_sgtable_page(sgt, &page_iter, 0) { 1003 - if (WARN_ON(p - pages >= max_entries)) 1004 - return -1; 1005 - *p++ = sg_page_iter_page(&page_iter); 1006 - } 999 + for_each_sgtable_page(sgt, &page_iter, 0) { 1000 + if (WARN_ON(p - pages >= max_entries)) 1001 + return -1; 1002 + *p++ = sg_page_iter_page(&page_iter); 1007 1003 } 1008 - if (addrs) { 1009 - for_each_sgtable_dma_page(sgt, &dma_iter, 0) { 1010 - if (WARN_ON(a - addrs >= max_entries)) 1011 - return -1; 1012 - *a++ = sg_page_iter_dma_address(&dma_iter); 1013 - } 1014 - } 1015 - 1016 1004 return 0; 1017 1005 } 1018 - EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); 1006 + EXPORT_SYMBOL(drm_prime_sg_to_page_array); 1007 + 1008 + /** 1009 + * drm_prime_sg_to_dma_addr_array - convert an sg table into a dma addr array 1010 + * @sgt: scatter-gather table to convert 1011 + * @addrs: array to store the dma bus address of each page 1012 + * @max_entries: size of both the passed-in arrays 1013 + * 1014 + * Exports an sg table into an array of addresses. 1015 + * 1016 + * Drivers should use this in their &drm_driver.gem_prime_import_sg_table 1017 + * implementation. 1018 + */ 1019 + int drm_prime_sg_to_dma_addr_array(struct sg_table *sgt, dma_addr_t *addrs, 1020 + int max_entries) 1021 + { 1022 + struct sg_dma_page_iter dma_iter; 1023 + dma_addr_t *a = addrs; 1024 + 1025 + for_each_sgtable_dma_page(sgt, &dma_iter, 0) { 1026 + if (WARN_ON(a - addrs >= max_entries)) 1027 + return -1; 1028 + *a++ = sg_page_iter_dma_address(&dma_iter); 1029 + } 1030 + return 0; 1031 + } 1032 + EXPORT_SYMBOL(drm_prime_sg_to_dma_addr_array); 1019 1033 1020 1034 /** 1021 1035 * drm_prime_gem_destroy - helper to clean up a PRIME-imported GEM object
+1 -2
drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
··· 135 135 goto fail; 136 136 } 137 137 138 - ret = drm_prime_sg_to_page_addr_arrays(sgt, etnaviv_obj->pages, 139 - NULL, npages); 138 + ret = drm_prime_sg_to_page_array(sgt, etnaviv_obj->pages, npages); 140 139 if (ret) 141 140 goto fail; 142 141
+1 -1
drivers/gpu/drm/mediatek/mtk_drm_gem.c
··· 260 260 return -ENOMEM; 261 261 } 262 262 263 - drm_prime_sg_to_page_addr_arrays(sgt, mtk_gem->pages, NULL, npages); 263 + drm_prime_sg_to_page_array(sgt, mtk_gem->pages, npages); 264 264 265 265 mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, 266 266 pgprot_writecombine(PAGE_KERNEL));
+1 -1
drivers/gpu/drm/msm/msm_gem.c
··· 1180 1180 goto fail; 1181 1181 } 1182 1182 1183 - ret = drm_prime_sg_to_page_addr_arrays(sgt, msm_obj->pages, NULL, npages); 1183 + ret = drm_prime_sg_to_page_array(sgt, msm_obj->pages, npages); 1184 1184 if (ret) { 1185 1185 mutex_unlock(&msm_obj->lock); 1186 1186 goto fail;
+2 -3
drivers/gpu/drm/nouveau/nouveau_bo.c
··· 1235 1235 return 0; 1236 1236 1237 1237 if (slave && ttm->sg) { 1238 - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, 1239 - ttm_dma->dma_address, 1240 - ttm->num_pages); 1238 + drm_prime_sg_to_dma_addr_array(ttm->sg, ttm_dma->dma_address, 1239 + ttm->num_pages); 1241 1240 return 0; 1242 1241 } 1243 1242
+1 -2
drivers/gpu/drm/omapdrm/omap_gem.c
··· 1324 1324 } 1325 1325 1326 1326 omap_obj->pages = pages; 1327 - ret = drm_prime_sg_to_page_addr_arrays(sgt, pages, NULL, 1328 - npages); 1327 + ret = drm_prime_sg_to_page_array(sgt, pages, npages); 1329 1328 if (ret) { 1330 1329 omap_gem_free_object(obj); 1331 1330 obj = ERR_PTR(-ENOMEM);
+4 -5
drivers/gpu/drm/radeon/radeon_ttm.c
··· 395 395 if (r) 396 396 goto release_sg; 397 397 398 - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, gtt->ttm.dma_address, 399 - ttm->num_pages); 398 + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, 399 + ttm->num_pages); 400 400 401 401 return 0; 402 402 ··· 574 574 } 575 575 576 576 if (slave && ttm->sg) { 577 - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, 578 - gtt->ttm.dma_address, 579 - ttm->num_pages); 577 + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, 578 + ttm->num_pages); 580 579 return 0; 581 580 } 582 581
+1 -2
drivers/gpu/drm/vgem/vgem_drv.c
··· 356 356 } 357 357 358 358 obj->pages_pin_count++; /* perma-pinned */ 359 - drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL, 360 - npages); 359 + drm_prime_sg_to_page_array(obj->table, obj->pages, npages); 361 360 return &obj->base; 362 361 } 363 362
+2 -2
drivers/gpu/drm/xen/xen_drm_front_gem.c
··· 220 220 221 221 xen_obj->sgt_imported = sgt; 222 222 223 - ret = drm_prime_sg_to_page_addr_arrays(sgt, xen_obj->pages, 224 - NULL, xen_obj->num_pages); 223 + ret = drm_prime_sg_to_page_array(sgt, xen_obj->pages, 224 + xen_obj->num_pages); 225 225 if (ret < 0) 226 226 return ERR_PTR(ret); 227 227
+4 -3
include/drm/drm_prime.h
··· 105 105 106 106 void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); 107 107 108 - int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, 109 - dma_addr_t *addrs, int max_pages); 110 - 108 + int drm_prime_sg_to_page_array(struct sg_table *sgt, struct page **pages, 109 + int max_pages); 110 + int drm_prime_sg_to_dma_addr_array(struct sg_table *sgt, dma_addr_t *addrs, 111 + int max_pages); 111 112 112 113 #endif /* __DRM_PRIME_H__ */