[PATCH] drm/amd/amdgpu: solve the issue of allocate continuous pages under xen dom0

Shane Xiao shane.xiao at amd.com
Thu Sep 22 07:11:33 UTC 2022


[Why]
sg_alloc_table_from_pages alloc too large continuous PFN pages under xen dom0.
However, xen should check continuous MFN pages in range_straddles_page_boundary.
When range_straddles_page_boundary return false, some cases fall back into
swiotlb process and the continuous allocable page is not enough.

[How]
In fact, xen swiotlb set max_segment default value as UINT_MAX and
xen_swiotlb_init_early already change the value to PAGE_SIZE under xen dom0.
However amdgpu driver doesn't use the value, which may cause issue such
as swiotlb buffer full. Add amd_sg_segment_size according to iommu setting,
the details are as follows:
	iommu setting		|	amd_sg_segment_size
-------------------------------------------------------------------------------
	iommu=on		|	UINT_MAX
    iommu=off && swiotlb on	|	IO_TLB_DEFAULT_SIZE(64M)
	xen_swiotlb on		|	PAGE_SIZE(4K)
-------------------------------------------------------------------------------

Signed-off-by: Shane Xiao <shane.xiao at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 134575a3893c..d081fcd22d6b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -80,6 +80,23 @@ static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev,
 				  false, size_in_page);
 }
 
+static inline unsigned int amdgpu_sg_segment_size(void)
+{
+	unsigned int size = swiotlb_max_segment();
+
+	/* size=0 when amd iommu enabled */
+	if (size == 0)
+		size = UINT_MAX;
+
+	size = rounddown(size, PAGE_SIZE);
+	/* swiotlb_max_segment_size can return 1 byte when it means one page. */
+	if (size < PAGE_SIZE)
+		size = PAGE_SIZE;
+
+	return size;
+}
+
+
 /**
  * amdgpu_evict_flags - Compute placement flags
  *
@@ -760,9 +777,10 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_device *bdev,
 	int r;
 
 	/* Allocate an SG array and squash pages into it */
-	r = sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_pages, 0,
-				      (u64)ttm->num_pages << PAGE_SHIFT,
+	r = sg_alloc_table_from_pages_segment(ttm->sg, ttm->pages, ttm->num_pages, 0,
+				      (u64)ttm->num_pages << PAGE_SHIFT, amdgpu_sg_segment_size(),
 				      GFP_KERNEL);
+
 	if (r)
 		goto release_sg;
 
-- 
2.25.1



More information about the amd-gfx mailing list