Skip to content

Commit 3991393

Browse files
mszyprowChristianKoenigAMD
authored andcommitted
drm: amdgpu: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. Signed-off-by: Marek Szyprowski <[email protected]> Reviewed-by: Christian König <[email protected]> Link: https://patchwork.freedesktop.org/patch/371142/ Signed-off-by: Christian König <[email protected]>
1 parent de48984 commit 3991393

File tree

3 files changed

+10
-13
lines changed

3 files changed

+10
-13
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
307307
if (IS_ERR(sgt))
308308
return sgt;
309309

310-
if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
311-
DMA_ATTR_SKIP_CPU_SYNC))
310+
if (dma_map_sgtable(attach->dev, sgt, dir,
311+
DMA_ATTR_SKIP_CPU_SYNC))
312312
goto error_free;
313313
break;
314314

@@ -349,7 +349,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
349349
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
350350

351351
if (sgt->sgl->page_link) {
352-
dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
352+
dma_unmap_sgtable(attach->dev, sgt, dir, 0);
353353
sg_free_table(sgt);
354354
kfree(sgt);
355355
} else {

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
10431043
{
10441044
struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
10451045
struct amdgpu_ttm_tt *gtt = (void *)ttm;
1046-
unsigned nents;
10471046
int r;
10481047

10491048
int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
@@ -1058,9 +1057,8 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
10581057
goto release_sg;
10591058

10601059
/* Map SG to device */
1061-
r = -ENOMEM;
1062-
nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
1063-
if (nents == 0)
1060+
r = dma_map_sgtable(adev->dev, ttm->sg, direction, 0);
1061+
if (r)
10641062
goto release_sg;
10651063

10661064
/* convert SG to linear array of pages and dma addresses */
@@ -1091,8 +1089,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
10911089
return;
10921090

10931091
/* unmap the pages mapped to the device */
1094-
dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
1095-
1092+
dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
10961093
sg_free_table(ttm->sg);
10971094

10981095
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)

drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -476,11 +476,11 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
476476
if (r)
477477
goto error_free;
478478

479-
for_each_sg((*sgt)->sgl, sg, num_entries, i)
479+
for_each_sgtable_sg((*sgt), sg, i)
480480
sg->length = 0;
481481

482482
node = mem->mm_node;
483-
for_each_sg((*sgt)->sgl, sg, num_entries, i) {
483+
for_each_sgtable_sg((*sgt), sg, i) {
484484
phys_addr_t phys = (node->start << PAGE_SHIFT) +
485485
adev->gmc.aper_base;
486486
size_t size = node->size << PAGE_SHIFT;
@@ -500,7 +500,7 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
500500
return 0;
501501

502502
error_unmap:
503-
for_each_sg((*sgt)->sgl, sg, num_entries, i) {
503+
for_each_sgtable_sg((*sgt), sg, i) {
504504
if (!sg->length)
505505
continue;
506506

@@ -531,7 +531,7 @@ void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev,
531531
struct scatterlist *sg;
532532
int i;
533533

534-
for_each_sg(sgt->sgl, sg, sgt->nents, i)
534+
for_each_sgtable_sg(sgt, sg, i)
535535
dma_unmap_resource(dev, sg->dma_address,
536536
sg->length, dir,
537537
DMA_ATTR_SKIP_CPU_SYNC);

0 commit comments

Comments
 (0)