[PATCH] drm/amdgpu: Support >=4GB GTT memory mapping

Christian König christian.koenig at amd.com
Mon Jan 29 10:06:17 UTC 2024


Am 26.01.24 um 20:47 schrieb Philip Yang:
> This is to work around a bug in function drm_prime_pages_to_sg if length
> of nr_pages >= 4GB, by doing the same check for max_segment and then
> calling sg_alloc_table_from_pages_segment directly instead.
>
> This issue shows up on APU because VRAM is allocated as GTT memory. It
> also fixes >=4GB GTT memory mapping for mGPUs with IOMMU isolation mode.

Well that was talked about before and rejected. If we really want more 
than 4GiB in DMA-bufs we need to fix drm_prime_pages_to_sg() instead.

Regards,
Christian.

>
> Signed-off-by: Philip Yang <Philip.Yang at amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 50 ++++++++++++++-------
>   1 file changed, 34 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 055ba2ea4c12..a203633fd629 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -171,18 +171,41 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   	}
>   
>   	switch (bo->tbo.resource->mem_type) {
> -	case TTM_PL_TT:
> -		sgt = drm_prime_pages_to_sg(obj->dev,
> -					    bo->tbo.ttm->pages,
> -					    bo->tbo.ttm->num_pages);
> -		if (IS_ERR(sgt))
> -			return sgt;
> -
> -		if (dma_map_sgtable(attach->dev, sgt, dir,
> -				    DMA_ATTR_SKIP_CPU_SYNC))
> -			goto error_free;
> -		break;
> +	case TTM_PL_TT: {
> +		size_t max_segment = 0;
> +		u64 num_pages;
> +		int err;
> +
> +		sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
> +		if (!sgt)
> +			return ERR_PTR(-ENOMEM);
> +
> +		if (obj->dev)
> +			max_segment = dma_max_mapping_size(obj->dev->dev);
> +		if (max_segment == 0)
> +			max_segment = UINT_MAX;
> +
> +		/*
> +		 * Use u64, otherwise if length of num_pages >= 4GB then size
> +		 * (num_pages << PAGE_SHIFT) becomes 0
> +		 */
> +		num_pages = bo->tbo.ttm->num_pages;
> +		err = sg_alloc_table_from_pages_segment(sgt, bo->tbo.ttm->pages,
> +							num_pages, 0,
> +							num_pages << PAGE_SHIFT,
> +							max_segment, GFP_KERNEL);
> +		if (err) {
> +			kfree(sgt);
> +			return ERR_PTR(err);
> +		}
>   
> +		if (dma_map_sgtable(attach->dev, sgt, dir, DMA_ATTR_SKIP_CPU_SYNC)) {
> +			sg_free_table(sgt);
> +			kfree(sgt);
> +			return ERR_PTR(-EBUSY);
> +		}
> +		break;
> +	}
>   	case TTM_PL_VRAM:
>   		r = amdgpu_vram_mgr_alloc_sgt(adev, bo->tbo.resource, 0,
>   					      bo->tbo.base.size, attach->dev,
> @@ -195,11 +218,6 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   	}
>   
>   	return sgt;
> -
> -error_free:
> -	sg_free_table(sgt);
> -	kfree(sgt);
> -	return ERR_PTR(-EBUSY);
>   }
>   
>   /**



More information about the amd-gfx mailing list