All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] amd/amdkfd: correct mem limit calculation for small APUs
@ 2025-09-01  2:27 Yifan Zhang
  2025-09-03  4:57 ` Mario Limonciello
  0 siblings, 1 reply; 2+ messages in thread
From: Yifan Zhang @ 2025-09-01  2:27 UTC (permalink / raw)
  To: amd-gfx; +Cc: Alexander.Deucher, Felix.Kuehling, Mario.Limonciello, Yifan Zhang

Current mem limit check leaks some GTT memory (reserved_for_pt
reserved_for_ras + adev->vram_pin_size) for small APUs.

Since carveout VRAM is tunable on APUs, there are three case
regarding the carveout VRAM size relative to GTT:

1. 0 < carveout < gtt
   apu_prefer_gtt = true, is_app_apu = false

2. carveout > gtt / 2
   apu_prefer_gtt = false, is_app_apu = false

3. 0 = carveout
   apu_prefer_gtt = true, is_app_apu = true

It doesn't make sense to check below limitation in case 1
(default case, small carveout) because the values in the below
expression are mixed with carveout and gtt.

adev->kfd.vram_used[xcp_id] + vram_needed >
    vram_size - reserved_for_pt - reserved_for_ras -
    atomic64_read(&adev->vram_pin_size)

gtt: kfd.vram_used, vram_needed, vram_size
carveout: reserved_for_pt, reserved_for_ras, adev->vram_pin_size

In case 1, vram allocation will go to gtt domain, skip vram check
since ttm_mem_limit check already cover this allocation.

v2: simplify judgement logic (Mario)

Signed-off-by: Yifan Zhang <yifan1.zhang@amd.com>
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 44 ++++++++++++++-----
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d478acb4568a..c3b34a410375 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -213,19 +213,35 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
 	spin_lock(&kfd_mem_limit.mem_limit_lock);
 
 	if (kfd_mem_limit.system_mem_used + system_mem_needed >
-	    kfd_mem_limit.max_system_mem_limit)
+	    kfd_mem_limit.max_system_mem_limit) {
 		pr_debug("Set no_system_mem_limit=1 if using shared memory\n");
+		if (!no_system_mem_limit) {
+			ret = -ENOMEM;
+			goto release;
+		}
+	}
 
-	if ((kfd_mem_limit.system_mem_used + system_mem_needed >
-	     kfd_mem_limit.max_system_mem_limit && !no_system_mem_limit) ||
-	    (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
-	     kfd_mem_limit.max_ttm_mem_limit) ||
-	    (adev && xcp_id >= 0 && adev->kfd.vram_used[xcp_id] + vram_needed >
-	     vram_size - reserved_for_pt - reserved_for_ras - atomic64_read(&adev->vram_pin_size))) {
+	if (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
+		kfd_mem_limit.max_ttm_mem_limit) {
 		ret = -ENOMEM;
 		goto release;
 	}
 
+	/*if is_app_apu is false and apu_prefer_gtt is true, it is an APU with
+	 * carve out < gtt. In that case, VRAM allocation will go to gtt domain, skip
+	 * VRAM check since ttm_mem_limit check already cover this allocation
+	 */
+
+	if (adev && xcp_id >= 0 && (!adev->apu_prefer_gtt || adev->gmc.is_app_apu)) {
+		uint64_t vram_available =
+			vram_size - reserved_for_pt - reserved_for_ras -
+			atomic64_read(&adev->vram_pin_size);
+		if (adev->kfd.vram_used[xcp_id] + vram_needed > vram_available) {
+			ret = -ENOMEM;
+			goto release;
+		}
+	}
+
 	/* Update memory accounting by decreasing available system
 	 * memory, TTM memory and GPU memory as computed above
 	 */
@@ -1627,11 +1643,15 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev,
 	uint64_t vram_available, system_mem_available, ttm_mem_available;
 
 	spin_lock(&kfd_mem_limit.mem_limit_lock);
-	vram_available = KFD_XCP_MEMORY_SIZE(adev, xcp_id)
-		- adev->kfd.vram_used_aligned[xcp_id]
-		- atomic64_read(&adev->vram_pin_size)
-		- reserved_for_pt
-		- reserved_for_ras;
+	if (adev->apu_prefer_gtt && !adev->gmc.is_app_apu)
+		vram_available = KFD_XCP_MEMORY_SIZE(adev, xcp_id)
+			- adev->kfd.vram_used_aligned[xcp_id];
+	else
+		vram_available = KFD_XCP_MEMORY_SIZE(adev, xcp_id)
+			- adev->kfd.vram_used_aligned[xcp_id]
+			- atomic64_read(&adev->vram_pin_size)
+			- reserved_for_pt
+			- reserved_for_ras;
 
 	if (adev->apu_prefer_gtt) {
 		system_mem_available = no_system_mem_limit ?
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] amd/amdkfd: correct mem limit calculation for small APUs
  2025-09-01  2:27 [PATCH] amd/amdkfd: correct mem limit calculation for small APUs Yifan Zhang
@ 2025-09-03  4:57 ` Mario Limonciello
  0 siblings, 0 replies; 2+ messages in thread
From: Mario Limonciello @ 2025-09-03  4:57 UTC (permalink / raw)
  To: Yifan Zhang, amd-gfx; +Cc: Alexander.Deucher, Felix.Kuehling

On 8/31/2025 9:27 PM, Yifan Zhang wrote:
> Current mem limit check leaks some GTT memory (reserved_for_pt
> reserved_for_ras + adev->vram_pin_size) for small APUs.
> 
> Since carveout VRAM is tunable on APUs, there are three case
> regarding the carveout VRAM size relative to GTT:
> 
> 1. 0 < carveout < gtt
>     apu_prefer_gtt = true, is_app_apu = false
> 
> 2. carveout > gtt / 2
>     apu_prefer_gtt = false, is_app_apu = false
> 
> 3. 0 = carveout
>     apu_prefer_gtt = true, is_app_apu = true
> 
> It doesn't make sense to check below limitation in case 1
> (default case, small carveout) because the values in the below
> expression are mixed with carveout and gtt.
> 
> adev->kfd.vram_used[xcp_id] + vram_needed >
>      vram_size - reserved_for_pt - reserved_for_ras -
>      atomic64_read(&adev->vram_pin_size)
> 
> gtt: kfd.vram_used, vram_needed, vram_size
> carveout: reserved_for_pt, reserved_for_ras, adev->vram_pin_size
> 
> In case 1, vram allocation will go to gtt domain, skip vram check
> since ttm_mem_limit check already cover this allocation.
> 
> v2: simplify judgement logic (Mario)

You can strip the changelog from the commit message.

> 
> Signed-off-by: Yifan Zhang <yifan1.zhang@amd.com>

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>

> ---
>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 44 ++++++++++++++-----
>   1 file changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> index d478acb4568a..c3b34a410375 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> @@ -213,19 +213,35 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
>   	spin_lock(&kfd_mem_limit.mem_limit_lock);
>   
>   	if (kfd_mem_limit.system_mem_used + system_mem_needed >
> -	    kfd_mem_limit.max_system_mem_limit)
> +	    kfd_mem_limit.max_system_mem_limit) {
>   		pr_debug("Set no_system_mem_limit=1 if using shared memory\n");
> +		if (!no_system_mem_limit) {
> +			ret = -ENOMEM;
> +			goto release;
> +		}
> +	}
>   
> -	if ((kfd_mem_limit.system_mem_used + system_mem_needed >
> -	     kfd_mem_limit.max_system_mem_limit && !no_system_mem_limit) ||
> -	    (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
> -	     kfd_mem_limit.max_ttm_mem_limit) ||
> -	    (adev && xcp_id >= 0 && adev->kfd.vram_used[xcp_id] + vram_needed >
> -	     vram_size - reserved_for_pt - reserved_for_ras - atomic64_read(&adev->vram_pin_size))) {
> +	if (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
> +		kfd_mem_limit.max_ttm_mem_limit) {
>   		ret = -ENOMEM;
>   		goto release;
>   	}
>   
> +	/*if is_app_apu is false and apu_prefer_gtt is true, it is an APU with
> +	 * carve out < gtt. In that case, VRAM allocation will go to gtt domain, skip
> +	 * VRAM check since ttm_mem_limit check already cover this allocation
> +	 */
> +
> +	if (adev && xcp_id >= 0 && (!adev->apu_prefer_gtt || adev->gmc.is_app_apu)) {
> +		uint64_t vram_available =
> +			vram_size - reserved_for_pt - reserved_for_ras -
> +			atomic64_read(&adev->vram_pin_size);
> +		if (adev->kfd.vram_used[xcp_id] + vram_needed > vram_available) {
> +			ret = -ENOMEM;
> +			goto release;
> +		}
> +	}
> +
>   	/* Update memory accounting by decreasing available system
>   	 * memory, TTM memory and GPU memory as computed above
>   	 */
> @@ -1627,11 +1643,15 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev,
>   	uint64_t vram_available, system_mem_available, ttm_mem_available;
>   
>   	spin_lock(&kfd_mem_limit.mem_limit_lock);
> -	vram_available = KFD_XCP_MEMORY_SIZE(adev, xcp_id)
> -		- adev->kfd.vram_used_aligned[xcp_id]
> -		- atomic64_read(&adev->vram_pin_size)
> -		- reserved_for_pt
> -		- reserved_for_ras;
> +	if (adev->apu_prefer_gtt && !adev->gmc.is_app_apu)
> +		vram_available = KFD_XCP_MEMORY_SIZE(adev, xcp_id)
> +			- adev->kfd.vram_used_aligned[xcp_id];
> +	else
> +		vram_available = KFD_XCP_MEMORY_SIZE(adev, xcp_id)
> +			- adev->kfd.vram_used_aligned[xcp_id]
> +			- atomic64_read(&adev->vram_pin_size)
> +			- reserved_for_pt
> +			- reserved_for_ras;
>   
>   	if (adev->apu_prefer_gtt) {
>   		system_mem_available = no_system_mem_limit ?


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-09-03  4:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-01  2:27 [PATCH] amd/amdkfd: correct mem limit calculation for small APUs Yifan Zhang
2025-09-03  4:57 ` Mario Limonciello

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.