All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman
@ 2026-04-03  8:35 Pierre-Eric Pelloux-Prayer
  2026-04-03  8:35 ` [PATCH v5 2/7] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-03  8:35 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Felix Kuehling
  Cc: Pierre-Eric Pelloux-Prayer, Felix Kuehling, amd-gfx, dri-devel,
	linux-kernel

This will allow the use of all of them for clear/fill buffer
operations.
Since drm_sched_entity_init requires a scheduler array, we
store schedulers rather than rings. For the few places that need
access to a ring, we can get it from the sched using container_of.

Since the code is the same for all sdma versions, add a new
helper amdgpu_sdma_set_buffer_funcs_scheds to set buffer_funcs_scheds
based on the number of sdma instances.

Note: the new sched array is identical to the amdgpu_vm_manager one.
These 2 could be merged.

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Acked-by: Felix Kuehling <felix.kuehling@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c    |  4 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 32 ++++++++++++++++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  3 +-
 drivers/gpu/drm/amd/amdgpu/cik_sdma.c      |  3 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c     |  3 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c     |  3 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c     |  8 ++----
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c   |  6 +---
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c     |  5 +---
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c     |  5 +---
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c     |  3 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c     |  3 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c     |  3 +-
 drivers/gpu/drm/amd/amdgpu/si_dma.c        |  3 +-
 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c   |  3 +-
 17 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 49e7881750fa..e3a8701f0b27 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1467,6 +1467,8 @@ ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring);
 ssize_t amdgpu_show_reset_mask(char *buf, uint32_t supported_reset);
 void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev,
 				   const struct amdgpu_vm_pte_funcs *vm_pte_funcs);
+void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
+					 const struct amdgpu_buffer_funcs *buffer_funcs);
 
 /* atpx handler */
 #if defined(CONFIG_VGA_SWITCHEROO)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 0c0489395edf..4da8de34be3d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3700,7 +3700,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 	adev->num_rings = 0;
 	RCU_INIT_POINTER(adev->gang_submit, dma_fence_get_stub());
 	adev->mman.buffer_funcs = NULL;
-	adev->mman.buffer_funcs_ring = NULL;
+	adev->mman.num_buffer_funcs_scheds = 0;
 	adev->vm_manager.vm_pte_funcs = NULL;
 	adev->vm_manager.vm_pte_num_scheds = 0;
 	adev->gmc.gmc_funcs = NULL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index e9e53c7c37d0..1a253e4257ff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -708,12 +708,14 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
 void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
 			      uint32_t vmhub, uint32_t flush_type)
 {
-	struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+	struct amdgpu_ring *ring;
 	struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
 	struct dma_fence *fence;
 	struct amdgpu_job *job;
 	int r;
 
+	ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
+
 	if (!hub->sdma_invalidation_workaround || vmid ||
 	    !adev->mman.buffer_funcs_enabled || !adev->ib_pool_ready ||
 	    !ring->sched.ready) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 3c63f87832e4..4ba7321b75e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -168,7 +168,7 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entit
 {
 	struct amdgpu_ring *ring;
 
-	ring = adev->mman.buffer_funcs_ring;
+	ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
 	amdgpu_ring_pad_ib(ring, &job->ibs[0]);
 	WARN_ON(job->ibs[0].length_dw > num_dw);
 
@@ -2349,18 +2349,17 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 		return;
 
 	if (enable) {
-		struct amdgpu_ring *ring;
 		struct drm_gpu_scheduler *sched;
 
-		if (!adev->mman.buffer_funcs_ring || !adev->mman.buffer_funcs_ring->sched.ready) {
+		if (!adev->mman.num_buffer_funcs_scheds ||
+		    !adev->mman.buffer_funcs_scheds[0]->ready) {
 			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
 			return;
 		}
 
 		num_clear_entities = 1;
 		num_move_entities = 1;
-		ring = adev->mman.buffer_funcs_ring;
-		sched = &ring->sched;
+		sched = adev->mman.buffer_funcs_scheds[0];
 		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
 						  &adev->mman.default_entity,
 						  DRM_SCHED_PRIORITY_KERNEL,
@@ -2497,7 +2496,7 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
 	unsigned int i;
 	int r;
 
-	ring = adev->mman.buffer_funcs_ring;
+	ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
 
 	if (!ring->sched.ready) {
 		dev_err(adev->dev,
@@ -2730,6 +2729,27 @@ int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type)
 	return ttm_resource_manager_evict_all(&adev->mman.bdev, man);
 }
 
+void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
+					 const struct amdgpu_buffer_funcs *buffer_funcs)
+{
+	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
+	struct drm_gpu_scheduler *sched;
+	int i;
+
+	adev->mman.buffer_funcs = buffer_funcs;
+
+	for (i = 0; i < adev->sdma.num_instances; i++) {
+		if (adev->sdma.has_page_queue)
+			sched = &adev->sdma.instance[i].page.sched;
+		else
+			sched = &adev->sdma.instance[i].ring.sched;
+		adev->mman.buffer_funcs_scheds[i] = sched;
+	}
+
+	adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
+		1 : adev->sdma.num_instances;
+}
+
 #if defined(CONFIG_DEBUG_FS)
 
 static int amdgpu_ttm_page_pool_show(struct seq_file *m, void *unused)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 3b1973611446..a6249252948b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -67,7 +67,8 @@ struct amdgpu_mman {
 
 	/* buffer handling */
 	const struct amdgpu_buffer_funcs	*buffer_funcs;
-	struct amdgpu_ring			*buffer_funcs_ring;
+	struct drm_gpu_scheduler		*buffer_funcs_scheds[AMDGPU_MAX_RINGS];
+	u32					num_buffer_funcs_scheds;
 	bool					buffer_funcs_enabled;
 
 	/* @default_entity: for workarounds, has no gart windows */
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index 22780c09177d..26276dcfd458 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -1340,8 +1340,7 @@ static const struct amdgpu_buffer_funcs cik_sdma_buffer_funcs = {
 
 static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &cik_sdma_buffer_funcs;
-	adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &cik_sdma_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version cik_sdma_ip_block =
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
index 0090ace49024..c6a059ca59e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -1235,8 +1235,7 @@ static const struct amdgpu_buffer_funcs sdma_v2_4_buffer_funcs = {
 
 static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &sdma_v2_4_buffer_funcs;
-	adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v2_4_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version sdma_v2_4_ip_block = {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 2526d393162a..cb516a25210d 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -1677,8 +1677,7 @@ static const struct amdgpu_buffer_funcs sdma_v3_0_buffer_funcs = {
 
 static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &sdma_v3_0_buffer_funcs;
-	adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v3_0_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version sdma_v3_0_ip_block =
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 44f0f23e1148..d56be26f216b 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -2626,13 +2626,9 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_buffer_funcs = {
 static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
 {
 	if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) >= IP_VERSION(4, 4, 0))
-		adev->mman.buffer_funcs = &sdma_v4_4_buffer_funcs;
+		amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_buffer_funcs);
 	else
-		adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
-	if (adev->sdma.has_page_queue)
-		adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
-	else
-		adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+		amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_0_buffer_funcs);
 }
 
 static void sdma_v4_0_get_ras_error_count(uint32_t value,
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 78bdfed0a7fd..67e9697301b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -2316,11 +2316,7 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_2_buffer_funcs = {
 
 static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &sdma_v4_4_2_buffer_funcs;
-	if (adev->sdma.has_page_queue)
-		adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
-	else
-		adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_2_buffer_funcs);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index 52f4e9e099cb..86f5eb784d57 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -2052,10 +2052,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_0_buffer_funcs = {
 
 static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	if (adev->mman.buffer_funcs == NULL) {
-		adev->mman.buffer_funcs = &sdma_v5_0_buffer_funcs;
-		adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
-	}
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_0_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version sdma_v5_0_ip_block = {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index b4fb90cc8f7d..3fec838374b2 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -2056,10 +2056,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_2_buffer_funcs = {
 
 static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	if (adev->mman.buffer_funcs == NULL) {
-		adev->mman.buffer_funcs = &sdma_v5_2_buffer_funcs;
-		adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
-	}
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_2_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version sdma_v5_2_ip_block = {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
index b005672f2f96..064508cecd11 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
@@ -1895,8 +1895,7 @@ static const struct amdgpu_buffer_funcs sdma_v6_0_buffer_funcs = {
 
 static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &sdma_v6_0_buffer_funcs;
-	adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v6_0_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version sdma_v6_0_ip_block = {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
index 5679a94d0815..60447729271e 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
@@ -1845,8 +1845,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_0_buffer_funcs = {
 
 static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &sdma_v7_0_buffer_funcs;
-	adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_0_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version sdma_v7_0_ip_block = {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
index f20e0fc3fc74..c3428d2731dc 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
@@ -1764,8 +1764,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_1_buffer_funcs = {
 
 static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &sdma_v7_1_buffer_funcs;
-	adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_1_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version sdma_v7_1_ip_block = {
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
index 3e58feb2d5e4..155067c20a0e 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
@@ -833,8 +833,7 @@ static const struct amdgpu_buffer_funcs si_dma_buffer_funcs = {
 
 static void si_dma_set_buffer_funcs(struct amdgpu_device *adev)
 {
-	adev->mman.buffer_funcs = &si_dma_buffer_funcs;
-	adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
+	amdgpu_sdma_set_buffer_funcs_scheds(adev, &si_dma_buffer_funcs);
 }
 
 const struct amdgpu_ip_block_version si_dma_ip_block =
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 964efa325908..28dc6886c1ff 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -129,13 +129,14 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys,
 			     struct dma_fence **mfence)
 {
 	const u64 GTT_MAX_PAGES = AMDGPU_GTT_MAX_TRANSFER_SIZE;
-	struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+	struct amdgpu_ring *ring;
 	struct amdgpu_ttm_buffer_entity *entity;
 	u64 gart_s, gart_d;
 	struct dma_fence *next;
 	u64 size;
 	int r;
 
+	ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
 	entity = &adev->mman.move_entities[0];
 
 	mutex_lock(&entity->lock);
-- 
2.43.0


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

* [PATCH v5 2/7] drm/amdgpu: only use working sdma schedulers for ttm
  2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
@ 2026-04-03  8:35 ` Pierre-Eric Pelloux-Prayer
  2026-04-07  8:11   ` Christian König
  2026-04-03  8:35 ` [PATCH v5 3/7] drm/amdgpu: create multiple clear/move ttm entities Pierre-Eric Pelloux-Prayer
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-03  8:35 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter
  Cc: Pierre-Eric Pelloux-Prayer, amd-gfx, dri-devel, linux-kernel

It's possible that some sdma instances aren't working so we shouldn't try
to use them from TTM. To achieve this, delay the call to
amdgpu_sdma_set_buffer_funcs_scheds after the rings have been tested, and
then use the 'ready' property to decide if a sched should be used or not.

Note that currently it's not doing much, because if the ring helper fails
for any ring, the whole sdma block init fails.

---
v5: check buffer_funcs_enabled from amdgpu_ttm_access_memory_sdma
---

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c  | 23 ++++++++++++++++-------
 drivers/gpu/drm/amd/amdgpu/cik_sdma.c    | 10 ++++++++--
 drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c   |  5 +++--
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c   |  5 +++--
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c   |  9 +++++++--
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c |  6 ++++--
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c   |  6 ++++--
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c   |  9 +++++++--
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c   |  9 +++++++--
 drivers/gpu/drm/amd/amdgpu/si_dma.c      |  9 +++++++--
 12 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 4ba7321b75e3..bd32113292ec 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1560,7 +1560,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo,
 	if (!adev->mman.sdma_access_ptr)
 		return -EACCES;
 
-	if (!drm_dev_enter(adev_to_drm(adev), &idx))
+	if (!adev->mman.buffer_funcs_enabled || !drm_dev_enter(adev_to_drm(adev), &idx))
 		return -ENODEV;
 
 	if (write)
@@ -2351,8 +2351,7 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 	if (enable) {
 		struct drm_gpu_scheduler *sched;
 
-		if (!adev->mman.num_buffer_funcs_scheds ||
-		    !adev->mman.buffer_funcs_scheds[0]->ready) {
+		if (!adev->mman.num_buffer_funcs_scheds) {
 			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
 			return;
 		}
@@ -2734,20 +2733,30 @@ void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
 {
 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
 	struct drm_gpu_scheduler *sched;
-	int i;
+	int i, n;
 
 	adev->mman.buffer_funcs = buffer_funcs;
 
-	for (i = 0; i < adev->sdma.num_instances; i++) {
+	for (i = 0, n = 0; i < adev->sdma.num_instances; i++) {
 		if (adev->sdma.has_page_queue)
 			sched = &adev->sdma.instance[i].page.sched;
 		else
 			sched = &adev->sdma.instance[i].ring.sched;
-		adev->mman.buffer_funcs_scheds[i] = sched;
+
+		if (!sched->ready)
+			continue;
+
+		adev->mman.buffer_funcs_scheds[n++] = sched;
+	}
+
+	if (n == 0) {
+		adev->mman.num_buffer_funcs_scheds = 0;
+		drm_warn(&adev->ddev, "No working sdma ring available\n");
+		return;
 	}
 
 	adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
-		1 : adev->sdma.num_instances;
+		1 : n;
 }
 
 #if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index 26276dcfd458..120da838ac28 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -939,7 +939,6 @@ static int cik_sdma_early_init(struct amdgpu_ip_block *ip_block)
 
 	cik_sdma_set_ring_funcs(adev);
 	cik_sdma_set_irq_funcs(adev);
-	cik_sdma_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &cik_sdma_vm_pte_funcs);
 
 	return 0;
@@ -1000,8 +999,15 @@ static int cik_sdma_sw_fini(struct amdgpu_ip_block *ip_block)
 static int cik_sdma_hw_init(struct amdgpu_ip_block *ip_block)
 {
 	struct amdgpu_device *adev = ip_block->adev;
+	int r;
 
-	return cik_sdma_start(adev);
+	r = cik_sdma_start(adev);
+	if (r)
+		return r;
+
+	cik_sdma_set_buffer_funcs(adev);
+
+	return 0;
 }
 
 static int cik_sdma_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
index c6a059ca59e5..93ec52c1f367 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -828,7 +828,6 @@ static int sdma_v2_4_early_init(struct amdgpu_ip_block *ip_block)
 		return r;
 
 	sdma_v2_4_set_ring_funcs(adev);
-	sdma_v2_4_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v2_4_vm_pte_funcs);
 	sdma_v2_4_set_irq_funcs(adev);
 
@@ -898,7 +897,9 @@ static int sdma_v2_4_hw_init(struct amdgpu_ip_block *ip_block)
 	if (r)
 		return r;
 
-	return r;
+	sdma_v2_4_set_buffer_funcs(adev);
+
+	return 0;
 }
 
 static int sdma_v2_4_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index cb516a25210d..3fde9be74690 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -1108,7 +1108,6 @@ static int sdma_v3_0_early_init(struct amdgpu_ip_block *ip_block)
 		return r;
 
 	sdma_v3_0_set_ring_funcs(adev);
-	sdma_v3_0_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v3_0_vm_pte_funcs);
 	sdma_v3_0_set_irq_funcs(adev);
 
@@ -1184,7 +1183,9 @@ static int sdma_v3_0_hw_init(struct amdgpu_ip_block *ip_block)
 	if (r)
 		return r;
 
-	return r;
+	sdma_v3_0_set_buffer_funcs(adev);
+
+	return 0;
 }
 
 static int sdma_v3_0_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index d56be26f216b..8a2a4e61867e 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -1775,7 +1775,6 @@ static int sdma_v4_0_early_init(struct amdgpu_ip_block *ip_block)
 		adev->sdma.has_page_queue = true;
 
 	sdma_v4_0_set_ring_funcs(adev);
-	sdma_v4_0_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_0_vm_pte_funcs);
 	sdma_v4_0_set_irq_funcs(adev);
 	sdma_v4_0_set_ras_funcs(adev);
@@ -1961,6 +1960,7 @@ static int sdma_v4_0_sw_fini(struct amdgpu_ip_block *ip_block)
 static int sdma_v4_0_hw_init(struct amdgpu_ip_block *ip_block)
 {
 	struct amdgpu_device *adev = ip_block->adev;
+	int r;
 
 	if (adev->flags & AMD_IS_APU)
 		amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false, 0);
@@ -1968,7 +1968,12 @@ static int sdma_v4_0_hw_init(struct amdgpu_ip_block *ip_block)
 	if (!amdgpu_sriov_vf(adev))
 		sdma_v4_0_init_golden_registers(adev);
 
-	return sdma_v4_0_start(adev);
+	r = sdma_v4_0_start(adev);
+	if (r)
+		return r;
+	sdma_v4_0_set_buffer_funcs(adev);
+
+	return 0;
 }
 
 static int sdma_v4_0_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 67e9697301b4..88428b88e00f 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -1368,7 +1368,6 @@ static int sdma_v4_4_2_early_init(struct amdgpu_ip_block *ip_block)
 		adev->sdma.has_page_queue = true;
 
 	sdma_v4_4_2_set_ring_funcs(adev);
-	sdma_v4_4_2_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_4_2_vm_pte_funcs);
 	sdma_v4_4_2_set_irq_funcs(adev);
 	sdma_v4_4_2_set_ras_funcs(adev);
@@ -1568,8 +1567,11 @@ static int sdma_v4_4_2_hw_init(struct amdgpu_ip_block *ip_block)
 		sdma_v4_4_2_inst_init_golden_registers(adev, inst_mask);
 
 	r = sdma_v4_4_2_inst_start(adev, inst_mask, false);
+	if (r)
+		return r;
+	sdma_v4_4_2_set_buffer_funcs(adev);
 
-	return r;
+	return 0;
 }
 
 static int sdma_v4_4_2_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index 86f5eb784d57..fa02907217e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -1373,7 +1373,6 @@ static int sdma_v5_0_early_init(struct amdgpu_ip_block *ip_block)
 		return r;
 
 	sdma_v5_0_set_ring_funcs(adev);
-	sdma_v5_0_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_0_vm_pte_funcs);
 	sdma_v5_0_set_irq_funcs(adev);
 	sdma_v5_0_set_mqd_funcs(adev);
@@ -1472,8 +1471,11 @@ static int sdma_v5_0_hw_init(struct amdgpu_ip_block *ip_block)
 	sdma_v5_0_init_golden_registers(adev);
 
 	r = sdma_v5_0_start(adev);
+	if (r)
+		return r;
+	sdma_v5_0_set_buffer_funcs(adev);
 
-	return r;
+	return 0;
 }
 
 static int sdma_v5_0_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index 3fec838374b2..f6ecbc524c9b 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -1264,7 +1264,6 @@ static int sdma_v5_2_early_init(struct amdgpu_ip_block *ip_block)
 		return r;
 
 	sdma_v5_2_set_ring_funcs(adev);
-	sdma_v5_2_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_2_vm_pte_funcs);
 	sdma_v5_2_set_irq_funcs(adev);
 	sdma_v5_2_set_mqd_funcs(adev);
@@ -1385,8 +1384,14 @@ static int sdma_v5_2_sw_fini(struct amdgpu_ip_block *ip_block)
 static int sdma_v5_2_hw_init(struct amdgpu_ip_block *ip_block)
 {
 	struct amdgpu_device *adev = ip_block->adev;
+	int r;
 
-	return sdma_v5_2_start(adev);
+	r = sdma_v5_2_start(adev);
+	if (r)
+		return r;
+	sdma_v5_2_set_buffer_funcs(adev);
+
+	return 0;
 }
 
 static int sdma_v5_2_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
index 064508cecd11..ee83d3e5978e 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
@@ -1313,7 +1313,6 @@ static int sdma_v6_0_early_init(struct amdgpu_ip_block *ip_block)
 		return r;
 
 	sdma_v6_0_set_ring_funcs(adev);
-	sdma_v6_0_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v6_0_vm_pte_funcs);
 	sdma_v6_0_set_irq_funcs(adev);
 	sdma_v6_0_set_mqd_funcs(adev);
@@ -1477,6 +1476,7 @@ static int sdma_v6_0_hw_init(struct amdgpu_ip_block *ip_block)
 	r = sdma_v6_0_start(adev);
 	if (r)
 		return r;
+	sdma_v6_0_set_buffer_funcs(adev);
 
 	return sdma_v6_0_set_userq_trap_interrupts(adev, true);
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
index 60447729271e..c8343981c596 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
@@ -1299,7 +1299,6 @@ static int sdma_v7_0_early_init(struct amdgpu_ip_block *ip_block)
 	}
 
 	sdma_v7_0_set_ring_funcs(adev);
-	sdma_v7_0_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_0_vm_pte_funcs);
 	sdma_v7_0_set_irq_funcs(adev);
 	sdma_v7_0_set_mqd_funcs(adev);
@@ -1432,6 +1431,7 @@ static int sdma_v7_0_hw_init(struct amdgpu_ip_block *ip_block)
 	r = sdma_v7_0_start(adev);
 	if (r)
 		return r;
+	sdma_v7_0_set_buffer_funcs(adev);
 
 	return sdma_v7_0_set_userq_trap_interrupts(adev, true);
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
index c3428d2731dc..b1ca95c2623b 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
@@ -1275,7 +1275,6 @@ static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block)
 	}
 
 	sdma_v7_1_set_ring_funcs(adev);
-	sdma_v7_1_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_1_vm_pte_funcs);
 	sdma_v7_1_set_irq_funcs(adev);
 	sdma_v7_1_set_mqd_funcs(adev);
@@ -1374,10 +1373,16 @@ static int sdma_v7_1_hw_init(struct amdgpu_ip_block *ip_block)
 {
 	struct amdgpu_device *adev = ip_block->adev;
 	uint32_t inst_mask;
+	int r;
 
 	inst_mask = GENMASK(adev->sdma.num_instances - 1, 0);
 
-	return sdma_v7_1_inst_start(adev, inst_mask);
+	r = sdma_v7_1_inst_start(adev, inst_mask);
+	if (r)
+		return r;
+	sdma_v7_1_set_buffer_funcs(adev);
+
+	return 0;
 }
 
 static int sdma_v7_1_hw_fini(struct amdgpu_ip_block *ip_block)
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
index 155067c20a0e..549708075eb4 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
@@ -487,7 +487,6 @@ static int si_dma_early_init(struct amdgpu_ip_block *ip_block)
 	adev->sdma.num_instances = SDMA_MAX_INSTANCE;
 
 	si_dma_set_ring_funcs(adev);
-	si_dma_set_buffer_funcs(adev);
 	amdgpu_sdma_set_vm_pte_scheds(adev, &si_dma_vm_pte_funcs);
 	si_dma_set_irq_funcs(adev);
 
@@ -543,8 +542,14 @@ static int si_dma_sw_fini(struct amdgpu_ip_block *ip_block)
 static int si_dma_hw_init(struct amdgpu_ip_block *ip_block)
 {
 	struct amdgpu_device *adev = ip_block->adev;
+	int r;
 
-	return si_dma_start(adev);
+	r = si_dma_start(adev);
+	if (r)
+		return r;
+	si_dma_set_buffer_funcs(adev);
+
+	return 0;
 }
 
 static int si_dma_hw_fini(struct amdgpu_ip_block *ip_block)
-- 
2.43.0


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

* [PATCH v5 3/7] drm/amdgpu: create multiple clear/move ttm entities
  2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
  2026-04-03  8:35 ` [PATCH v5 2/7] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
@ 2026-04-03  8:35 ` Pierre-Eric Pelloux-Prayer
  2026-04-07 10:01   ` Christian König
  2026-04-03  8:35 ` [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds Pierre-Eric Pelloux-Prayer
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-03  8:35 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter
  Cc: Pierre-Eric Pelloux-Prayer, amd-gfx, dri-devel, linux-kernel

This enables parallelism of operations.

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index bd32113292ec..83f6d00dc3a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -2356,8 +2356,8 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 			return;
 		}
 
-		num_clear_entities = 1;
-		num_move_entities = 1;
+		num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
+		num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
 		sched = adev->mman.buffer_funcs_scheds[0];
 		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
 						  &adev->mman.default_entity,
-- 
2.43.0


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

* [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds
  2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
  2026-04-03  8:35 ` [PATCH v5 2/7] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
  2026-04-03  8:35 ` [PATCH v5 3/7] drm/amdgpu: create multiple clear/move ttm entities Pierre-Eric Pelloux-Prayer
@ 2026-04-03  8:35 ` Pierre-Eric Pelloux-Prayer
  2026-04-07 10:05   ` Christian König
  2026-04-03  8:35 ` [PATCH v5 5/7] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-03  8:35 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter
  Cc: Pierre-Eric Pelloux-Prayer, amd-gfx, dri-devel, linux-kernel

With this change we now have as many clear and move entities as we
have sdma engines (limited to TTM_NUM_MOVE_FENCES).

To enable load-balancing this patch gives access to all sdma
schedulers to all entities.

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 83f6d00dc3a0..648ad344e89c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -2349,8 +2349,6 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 		return;
 
 	if (enable) {
-		struct drm_gpu_scheduler *sched;
-
 		if (!adev->mman.num_buffer_funcs_scheds) {
 			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
 			return;
@@ -2358,11 +2356,10 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 
 		num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
 		num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
-		sched = adev->mman.buffer_funcs_scheds[0];
 		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
 						  &adev->mman.default_entity,
 						  DRM_SCHED_PRIORITY_KERNEL,
-						  &sched, 1, 0);
+						  adev->mman.buffer_funcs_scheds, 1, 0);
 		if (r < 0) {
 			dev_err(adev->dev,
 				"Failed setting up TTM entity (%d)\n", r);
@@ -2380,8 +2377,11 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 
 		for (i = 0; i < num_clear_entities; i++) {
 			r = amdgpu_ttm_buffer_entity_init(
-				&adev->mman.gtt_mgr, &adev->mman.clear_entities[i],
-				DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 1);
+				&adev->mman.gtt_mgr,
+				&adev->mman.clear_entities[i],
+				DRM_SCHED_PRIORITY_NORMAL,
+				adev->mman.buffer_funcs_scheds,
+				adev->mman.num_buffer_funcs_scheds, 1);
 
 			if (r < 0) {
 				for (j = 0; j < i; j++)
@@ -2400,7 +2400,9 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 			r = amdgpu_ttm_buffer_entity_init(
 				&adev->mman.gtt_mgr,
 				&adev->mman.move_entities[i],
-				DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 2);
+				DRM_SCHED_PRIORITY_NORMAL,
+				adev->mman.buffer_funcs_scheds,
+				adev->mman.num_buffer_funcs_scheds, 2);
 
 			if (r < 0) {
 				for (j = 0; j < i; j++)
-- 
2.43.0


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

* [PATCH v5 5/7] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer
  2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
                   ` (2 preceding siblings ...)
  2026-04-03  8:35 ` [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds Pierre-Eric Pelloux-Prayer
@ 2026-04-03  8:35 ` Pierre-Eric Pelloux-Prayer
  2026-04-07 10:09   ` Christian König
  2026-04-03  8:35 ` [PATCH v5 6/7] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-03  8:35 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Sumit Semwal
  Cc: Pierre-Eric Pelloux-Prayer, amd-gfx, dri-devel, linux-kernel,
	linux-media, linaro-mm-sig

It's doing the same thing as amdgpu_fill_buffer(src_data=0), so drop it.

The only caveat is that amdgpu_res_cleared() return value is only valid
right after allocation.

---
v2: introduce new "bool consider_clear_status" arg
---

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 16 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 88 +++++-----------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  6 +-
 3 files changed, 32 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 66c20dd46d12..d0884bbffa75 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -717,13 +717,17 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
 	    bo->tbo.resource->mem_type == TTM_PL_VRAM) {
 		struct dma_fence *fence;
 
-		r = amdgpu_ttm_clear_buffer(bo, bo->tbo.base.resv, &fence);
+		r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
+				       bo, 0, NULL, &fence,
+				       true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
 		if (unlikely(r))
 			goto fail_unreserve;
 
-		dma_resv_add_fence(bo->tbo.base.resv, fence,
-				   DMA_RESV_USAGE_KERNEL);
-		dma_fence_put(fence);
+		if (fence) {
+			dma_resv_add_fence(bo->tbo.base.resv, fence,
+					   DMA_RESV_USAGE_KERNEL);
+			dma_fence_put(fence);
+		}
 	}
 	if (!bp->resv)
 		amdgpu_bo_unreserve(bo);
@@ -1326,8 +1330,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
 		goto out;
 
 	r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
-			       abo, 0, &bo->base._resv,
-			       &fence, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
+			       abo, 0, &bo->base._resv, &fence,
+			       false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
 	if (WARN_ON(r))
 		goto out;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 648ad344e89c..a3d0998b8cec 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -418,7 +418,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
 	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
 		struct dma_fence *wipe_fence = NULL;
 		r = amdgpu_fill_buffer(entity, abo, 0, NULL, &wipe_fence,
-				       AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
+				       false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
 		if (r) {
 			goto error;
 		} else if (wipe_fence) {
@@ -2572,76 +2572,25 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
 }
 
 /**
- * amdgpu_ttm_clear_buffer - clear memory buffers
- * @bo: amdgpu buffer object
- * @resv: reservation object
- * @fence: dma_fence associated with the operation
+ * amdgpu_fill_buffer - fill a buffer with a given value
+ * @entity: entity to use
+ * @bo: the bo to fill
+ * @src_data: the value to set
+ * @resv: fences contained in this reservation will be used as dependencies.
+ * @out_fence: the fence from the last clear will be stored here. It might be
+ *             NULL if no job was run.
+ * @dependency: optional input dependency fence.
+ * @consider_clear_status: true if region reported as cleared by amdgpu_res_cleared()
+ *                         are skipped.
+ * @k_job_id: trace id
  *
- * Clear the memory buffer resource.
- *
- * Returns:
- * 0 for success or a negative error code on failure.
  */
-int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
-			    struct dma_resv *resv,
-			    struct dma_fence **fence)
-{
-	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-	struct amdgpu_ttm_buffer_entity *entity;
-	struct amdgpu_res_cursor cursor;
-	u64 addr;
-	int r = 0;
-
-	if (!adev->mman.buffer_funcs_enabled)
-		return -EINVAL;
-
-	if (!fence)
-		return -EINVAL;
-	entity = &adev->mman.clear_entities[0];
-	*fence = dma_fence_get_stub();
-
-	amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
-
-	mutex_lock(&entity->lock);
-	while (cursor.remaining) {
-		struct dma_fence *next = NULL;
-		u64 size;
-
-		if (amdgpu_res_cleared(&cursor)) {
-			amdgpu_res_next(&cursor, cursor.size);
-			continue;
-		}
-
-		/* Never clear more than 256MiB at once to avoid timeouts */
-		size = min(cursor.size, 256ULL << 20);
-
-		r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &cursor,
-					  0, false, &size, &addr);
-		if (r)
-			goto err;
-
-		r = amdgpu_ttm_fill_mem(adev, entity, 0, addr, size, resv,
-					&next, true,
-					AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
-		if (r)
-			goto err;
-
-		dma_fence_put(*fence);
-		*fence = next;
-
-		amdgpu_res_next(&cursor, size);
-	}
-err:
-	mutex_unlock(&entity->lock);
-
-	return r;
-}
-
 int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
 		       struct amdgpu_bo *bo,
 		       uint32_t src_data,
 		       struct dma_resv *resv,
-		       struct dma_fence **f,
+		       struct dma_fence **out_fence,
+		       bool consider_clear_status,
 		       u64 k_job_id)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
@@ -2659,6 +2608,11 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
 		struct dma_fence *next;
 		uint64_t cur_size, to;
 
+		if (consider_clear_status && amdgpu_res_cleared(&dst)) {
+			amdgpu_res_next(&dst, dst.size);
+			continue;
+		}
+
 		/* Never fill more than 256MiB at once to avoid timeouts */
 		cur_size = min(dst.size, 256ULL << 20);
 
@@ -2680,9 +2634,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
 	}
 error:
 	mutex_unlock(&entity->lock);
-	if (f)
-		*f = dma_fence_get(fence);
-	dma_fence_put(fence);
+	*out_fence = fence;
 	return r;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index a6249252948b..436a3e09a178 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -187,14 +187,12 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
 		       struct dma_resv *resv,
 		       struct dma_fence **fence,
 		       bool vm_needs_flush, uint32_t copy_flags);
-int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
-			    struct dma_resv *resv,
-			    struct dma_fence **fence);
 int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
 		       struct amdgpu_bo *bo,
 		       uint32_t src_data,
 		       struct dma_resv *resv,
-		       struct dma_fence **f,
+		       struct dma_fence **out_fence,
+		       bool consider_clear_status,
 		       u64 k_job_id);
 struct amdgpu_ttm_buffer_entity *amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev);
 
-- 
2.43.0


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

* [PATCH v5 6/7] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer
  2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
                   ` (3 preceding siblings ...)
  2026-04-03  8:35 ` [PATCH v5 5/7] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
@ 2026-04-03  8:35 ` Pierre-Eric Pelloux-Prayer
  2026-04-07 10:16   ` Christian König
  2026-04-03  8:35 ` [PATCH v5 7/7] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs Pierre-Eric Pelloux-Prayer
  2026-04-03 15:08 ` [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Alex Deucher
  6 siblings, 1 reply; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-03  8:35 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Sumit Semwal
  Cc: Pierre-Eric Pelloux-Prayer, amd-gfx, dri-devel, linux-kernel,
	linux-media, linaro-mm-sig

This is the only use case for this function.

---
v2: amdgpu_ttm_clear_buffer instead of amdgpu_clear_buffer
---

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 +++++------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 23 ++++++++++------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    | 13 ++++++------
 3 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index d0884bbffa75..195cb1c814d1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -717,9 +717,9 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
 	    bo->tbo.resource->mem_type == TTM_PL_VRAM) {
 		struct dma_fence *fence;
 
-		r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
-				       bo, 0, NULL, &fence,
-				       true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
+		r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
+					    bo, NULL, &fence,
+					    true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
 		if (unlikely(r))
 			goto fail_unreserve;
 
@@ -1329,9 +1329,9 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
 	if (r)
 		goto out;
 
-	r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
-			       abo, 0, &bo->base._resv, &fence,
-			       false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
+	r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
+				    abo, &bo->base._resv, &fence,
+				    false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
 	if (WARN_ON(r))
 		goto out;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index a3d0998b8cec..e74f9f8a88dc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -417,8 +417,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
 	if (old_mem->mem_type == TTM_PL_VRAM &&
 	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
 		struct dma_fence *wipe_fence = NULL;
-		r = amdgpu_fill_buffer(entity, abo, 0, NULL, &wipe_fence,
-				       false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
+		r = amdgpu_ttm_clear_buffer(entity, abo, NULL, &wipe_fence,
+					    false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
 		if (r) {
 			goto error;
 		} else if (wipe_fence) {
@@ -2572,26 +2572,23 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
 }
 
 /**
- * amdgpu_fill_buffer - fill a buffer with a given value
+ * amdgpu_ttm_clear_buffer - fill a buffer with 0
  * @entity: entity to use
  * @bo: the bo to fill
- * @src_data: the value to set
  * @resv: fences contained in this reservation will be used as dependencies.
  * @out_fence: the fence from the last clear will be stored here. It might be
  *             NULL if no job was run.
- * @dependency: optional input dependency fence.
  * @consider_clear_status: true if region reported as cleared by amdgpu_res_cleared()
  *                         are skipped.
  * @k_job_id: trace id
  *
  */
-int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
-		       struct amdgpu_bo *bo,
-		       uint32_t src_data,
-		       struct dma_resv *resv,
-		       struct dma_fence **out_fence,
-		       bool consider_clear_status,
-		       u64 k_job_id)
+int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
+			    struct amdgpu_bo *bo,
+			    struct dma_resv *resv,
+			    struct dma_fence **out_fence,
+			    bool consider_clear_status,
+			    u64 k_job_id)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 	struct dma_fence *fence = NULL;
@@ -2622,7 +2619,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
 			goto error;
 
 		r = amdgpu_ttm_fill_mem(adev, entity,
-					src_data, to, cur_size, resv,
+					0, to, cur_size, resv,
 					&next, true, k_job_id);
 		if (r)
 			goto error;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 436a3e09a178..d7b14d5cac77 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -187,13 +187,12 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
 		       struct dma_resv *resv,
 		       struct dma_fence **fence,
 		       bool vm_needs_flush, uint32_t copy_flags);
-int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
-		       struct amdgpu_bo *bo,
-		       uint32_t src_data,
-		       struct dma_resv *resv,
-		       struct dma_fence **out_fence,
-		       bool consider_clear_status,
-		       u64 k_job_id);
+int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
+			    struct amdgpu_bo *bo,
+			    struct dma_resv *resv,
+			    struct dma_fence **out_fence,
+			    bool consider_clear_status,
+			    u64 k_job_id);
 struct amdgpu_ttm_buffer_entity *amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev);
 
 int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
-- 
2.43.0


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

* [PATCH v5 7/7] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs
  2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
                   ` (4 preceding siblings ...)
  2026-04-03  8:35 ` [PATCH v5 6/7] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
@ 2026-04-03  8:35 ` Pierre-Eric Pelloux-Prayer
  2026-04-07 10:24   ` Christian König
  2026-04-03 15:08 ` [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Alex Deucher
  6 siblings, 1 reply; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-03  8:35 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter
  Cc: Pierre-Eric Pelloux-Prayer, amd-gfx, dri-devel, linux-kernel

Makes a code slightly clearer and reduces indentation.

---
v5: use amdgpu_in_reset in amdgpu_ttm_disable_buffer_funcs
---

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Suggested-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 186 +++++++++++----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |   4 +-
 3 files changed, 108 insertions(+), 96 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 4da8de34be3d..a24f52e71850 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2463,7 +2463,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
 	if (r)
 		goto init_failed;
 
-	amdgpu_ttm_set_buffer_funcs_status(adev, true);
+	amdgpu_ttm_enable_buffer_funcs(adev);
 
 	/* Don't init kfd if whole hive need to be reset during init */
 	if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
@@ -3147,7 +3147,7 @@ static int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
 		amdgpu_virt_request_full_gpu(adev, false);
 	}
 
-	amdgpu_ttm_set_buffer_funcs_status(adev, false);
+	amdgpu_ttm_disable_buffer_funcs(adev);
 
 	r = amdgpu_device_ip_suspend_phase1(adev);
 	if (r)
@@ -3362,7 +3362,7 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
 
 	r = amdgpu_device_ip_resume_phase2(adev);
 
-	amdgpu_ttm_set_buffer_funcs_status(adev, true);
+	amdgpu_ttm_enable_buffer_funcs(adev);
 
 	if (r)
 		return r;
@@ -4215,7 +4215,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
 	/* disable ras feature must before hw fini */
 	amdgpu_ras_pre_fini(adev);
 
-	amdgpu_ttm_set_buffer_funcs_status(adev, false);
+	amdgpu_ttm_disable_buffer_funcs(adev);
 
 	/*
 	 * device went through surprise hotplug; we need to destroy topology
@@ -4482,7 +4482,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
 	if (r)
 		goto unwind_userq;
 
-	amdgpu_ttm_set_buffer_funcs_status(adev, false);
+	amdgpu_ttm_disable_buffer_funcs(adev);
 
 	amdgpu_fence_driver_hw_fini(adev);
 
@@ -4496,7 +4496,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
 	return 0;
 
 unwind_evict:
-	amdgpu_ttm_set_buffer_funcs_status(adev, true);
+	amdgpu_ttm_enable_buffer_funcs(adev);
 	amdgpu_fence_driver_hw_init(adev);
 
 unwind_userq:
@@ -5230,7 +5230,7 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context)
 				if (r)
 					goto out;
 
-				amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
+				amdgpu_ttm_enable_buffer_funcs(tmp_adev);
 
 				r = amdgpu_device_ip_resume_phase3(tmp_adev);
 				if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index e74f9f8a88dc..9bbd8149ffd2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -2100,7 +2100,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
 	}
 
 	/* Change the size here instead of the init above so only lpfn is affected */
-	amdgpu_ttm_set_buffer_funcs_status(adev, false);
+	amdgpu_ttm_disable_buffer_funcs(adev);
 #ifdef CONFIG_64BIT
 #ifdef CONFIG_X86
 	if (adev->gmc.xgmi.connected_to_cpu)
@@ -2329,115 +2329,91 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
 }
 
 /**
- * amdgpu_ttm_set_buffer_funcs_status - enable/disable use of buffer functions
+ * amdgpu_ttm_enable_buffer_funcs - enable use of buffer functions
  *
  * @adev: amdgpu_device pointer
- * @enable: true when we can use buffer functions.
  *
- * Enable/disable use of buffer functions during suspend/resume. This should
+ * Enable use of buffer functions during suspend/resume. This should
  * only be called at bootup or when userspace isn't running.
  */
-void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
+void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
 {
 	struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
 	u32 num_clear_entities, num_move_entities;
-	uint64_t size;
 	int r, i, j;
 
 	if (!adev->mman.initialized || amdgpu_in_reset(adev) ||
-	    adev->mman.buffer_funcs_enabled == enable || adev->gmc.is_app_apu)
+	    adev->mman.buffer_funcs_enabled || adev->gmc.is_app_apu)
 		return;
 
-	if (enable) {
-		if (!adev->mman.num_buffer_funcs_scheds) {
-			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
-			return;
-		}
+	if (!adev->mman.num_buffer_funcs_scheds) {
+		dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
+		return;
+	}
+
+	r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
+						&adev->mman.default_entity,
+						DRM_SCHED_PRIORITY_KERNEL,
+						adev->mman.buffer_funcs_scheds, 1, 0);
+	if (r < 0) {
+		dev_err(adev->dev,
+			"Failed setting up TTM entity (%d)\n", r);
+		return;
+	}
+
+	num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
+	num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
+
+	adev->mman.clear_entities = kcalloc(num_clear_entities,
+						sizeof(struct amdgpu_ttm_buffer_entity),
+						GFP_KERNEL);
+	atomic_set(&adev->mman.next_clear_entity, 0);
+	if (!adev->mman.clear_entities)
+		goto error_free_default_entity;
+
+	adev->mman.num_clear_entities = num_clear_entities;
+
+	for (i = 0; i < num_clear_entities; i++) {
+		r = amdgpu_ttm_buffer_entity_init(
+			&adev->mman.gtt_mgr,
+			&adev->mman.clear_entities[i],
+			DRM_SCHED_PRIORITY_NORMAL,
+			adev->mman.buffer_funcs_scheds,
+			adev->mman.num_buffer_funcs_scheds, 1);
 
-		num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
-		num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
-		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
-						  &adev->mman.default_entity,
-						  DRM_SCHED_PRIORITY_KERNEL,
-						  adev->mman.buffer_funcs_scheds, 1, 0);
 		if (r < 0) {
-			dev_err(adev->dev,
-				"Failed setting up TTM entity (%d)\n", r);
-			return;
-		}
-
-		adev->mman.clear_entities = kcalloc(num_clear_entities,
-						    sizeof(struct amdgpu_ttm_buffer_entity),
-						    GFP_KERNEL);
-		atomic_set(&adev->mman.next_clear_entity, 0);
-		if (!adev->mman.clear_entities)
+			for (j = 0; j < i; j++)
+				amdgpu_ttm_buffer_entity_fini(
+					&adev->mman.gtt_mgr, &adev->mman.clear_entities[j]);
+			adev->mman.num_clear_entities = 0;
+			kfree(adev->mman.clear_entities);
 			goto error_free_default_entity;
-
-		adev->mman.num_clear_entities = num_clear_entities;
-
-		for (i = 0; i < num_clear_entities; i++) {
-			r = amdgpu_ttm_buffer_entity_init(
-				&adev->mman.gtt_mgr,
-				&adev->mman.clear_entities[i],
-				DRM_SCHED_PRIORITY_NORMAL,
-				adev->mman.buffer_funcs_scheds,
-				adev->mman.num_buffer_funcs_scheds, 1);
-
-			if (r < 0) {
-				for (j = 0; j < i; j++)
-					amdgpu_ttm_buffer_entity_fini(
-						&adev->mman.gtt_mgr, &adev->mman.clear_entities[j]);
-				kfree(adev->mman.clear_entities);
-				adev->mman.num_clear_entities = 0;
-				adev->mman.clear_entities = NULL;
-				goto error_free_default_entity;
-			}
 		}
+	}
 
-		adev->mman.num_move_entities = num_move_entities;
-		atomic_set(&adev->mman.next_move_entity, 0);
-		for (i = 0; i < num_move_entities; i++) {
-			r = amdgpu_ttm_buffer_entity_init(
-				&adev->mman.gtt_mgr,
-				&adev->mman.move_entities[i],
-				DRM_SCHED_PRIORITY_NORMAL,
-				adev->mman.buffer_funcs_scheds,
-				adev->mman.num_buffer_funcs_scheds, 2);
+	adev->mman.num_move_entities = num_move_entities;
+	atomic_set(&adev->mman.next_move_entity, 0);
+	for (i = 0; i < num_move_entities; i++) {
+		r = amdgpu_ttm_buffer_entity_init(
+			&adev->mman.gtt_mgr,
+			&adev->mman.move_entities[i],
+			DRM_SCHED_PRIORITY_NORMAL,
+			adev->mman.buffer_funcs_scheds,
+			adev->mman.num_buffer_funcs_scheds, 2);
 
-			if (r < 0) {
-				for (j = 0; j < i; j++)
-					amdgpu_ttm_buffer_entity_fini(
-						&adev->mman.gtt_mgr, &adev->mman.move_entities[j]);
-				adev->mman.num_move_entities = 0;
-				goto error_free_clear_entities;
-			}
+		if (r < 0) {
+			for (j = 0; j < i; j++)
+				amdgpu_ttm_buffer_entity_fini(
+					&adev->mman.gtt_mgr,
+					&adev->mman.move_entities[j]);
+			adev->mman.num_move_entities = 0;
+			goto error_free_clear_entities;
 		}
-	} else {
-		amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
-					      &adev->mman.default_entity);
-		for (i = 0; i < adev->mman.num_clear_entities; i++)
-			amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
-						      &adev->mman.clear_entities[i]);
-		for (i = 0; i < adev->mman.num_move_entities; i++)
-			amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
-						      &adev->mman.move_entities[i]);
-		/* Drop all the old fences since re-creating the scheduler entities
-		 * will allocate new contexts.
-		 */
-		ttm_resource_manager_cleanup(man);
-		kfree(adev->mman.clear_entities);
-		adev->mman.clear_entities = NULL;
-		adev->mman.num_clear_entities = 0;
-		adev->mman.num_move_entities = 0;
 	}
 
 	/* this just adjusts TTM size idea, which sets lpfn to the correct value */
-	if (enable)
-		size = adev->gmc.real_vram_size;
-	else
-		size = adev->gmc.visible_vram_size;
-	man->size = size;
-	adev->mman.buffer_funcs_enabled = enable;
+	man->size = adev->gmc.real_vram_size;
+	adev->mman.buffer_funcs_enabled = true;
 
 	return;
 
@@ -2453,6 +2429,42 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
 				      &adev->mman.default_entity);
 }
 
+/**
+ * amdgpu_ttm_disable_buffer_funcs - disable use of buffer functions
+ *
+ * @adev: amdgpu_device pointer
+ */
+void amdgpu_ttm_disable_buffer_funcs(struct amdgpu_device *adev)
+{
+	struct ttm_resource_manager *man =
+		ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
+	int i;
+
+	if (!adev->mman.buffer_funcs_enabled || amdgpu_in_reset(adev))
+		return;
+
+	amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
+				      &adev->mman.default_entity);
+	for (i = 0; i < adev->mman.num_move_entities; i++)
+		amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
+					      &adev->mman.move_entities[i]);
+	for (i = 0; i < adev->mman.num_clear_entities; i++)
+		amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
+					      &adev->mman.clear_entities[i]);
+	/* Drop all the old fences since re-creating the scheduler entities
+	 * will allocate new contexts.
+	 */
+	ttm_resource_manager_cleanup(man);
+
+	kfree(adev->mman.clear_entities);
+	adev->mman.clear_entities = NULL;
+	adev->mman.num_clear_entities = 0;
+	adev->mman.num_move_entities = 0;
+
+	man->size = adev->gmc.visible_vram_size;
+	adev->mman.buffer_funcs_enabled = false;
+}
+
 static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
 				  struct amdgpu_ttm_buffer_entity *entity,
 				  unsigned int num_dw,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index d7b14d5cac77..8a5f34aaabac 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -178,8 +178,8 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
 
 int amdgpu_ttm_init(struct amdgpu_device *adev);
 void amdgpu_ttm_fini(struct amdgpu_device *adev);
-void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
-					bool enable);
+void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev);
+void amdgpu_ttm_disable_buffer_funcs(struct amdgpu_device *adev);
 int amdgpu_copy_buffer(struct amdgpu_device *adev,
 		       struct amdgpu_ttm_buffer_entity *entity,
 		       uint64_t src_offset,
-- 
2.43.0


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

* Re: [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman
  2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
                   ` (5 preceding siblings ...)
  2026-04-03  8:35 ` [PATCH v5 7/7] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs Pierre-Eric Pelloux-Prayer
@ 2026-04-03 15:08 ` Alex Deucher
  2026-04-07  8:07   ` Christian König
  6 siblings, 1 reply; 20+ messages in thread
From: Alex Deucher @ 2026-04-03 15:08 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer
  Cc: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Felix Kuehling, amd-gfx, dri-devel, linux-kernel

On Fri, Apr 3, 2026 at 4:36 AM Pierre-Eric Pelloux-Prayer
<pierre-eric.pelloux-prayer@amd.com> wrote:
>
> This will allow the use of all of them for clear/fill buffer
> operations.
> Since drm_sched_entity_init requires a scheduler array, we
> store schedulers rather than rings. For the few places that need
> access to a ring, we can get it from the sched using container_of.
>
> Since the code is the same for all sdma versions, add a new
> helper amdgpu_sdma_set_buffer_funcs_scheds to set buffer_funcs_scheds
> based on the number of sdma instances.
>
> Note: the new sched array is identical to the amdgpu_vm_manager one.
> These 2 could be merged.
>
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
> Acked-by: Felix Kuehling <felix.kuehling@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 ++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c    |  4 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 32 ++++++++++++++++++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  3 +-
>  drivers/gpu/drm/amd/amdgpu/cik_sdma.c      |  3 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c     |  3 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c     |  3 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c     |  8 ++----
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c   |  6 +---
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c     |  5 +---
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c     |  5 +---
>  drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c     |  3 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c     |  3 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c     |  3 +-
>  drivers/gpu/drm/amd/amdgpu/si_dma.c        |  3 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_migrate.c   |  3 +-
>  17 files changed, 48 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 49e7881750fa..e3a8701f0b27 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1467,6 +1467,8 @@ ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring);
>  ssize_t amdgpu_show_reset_mask(char *buf, uint32_t supported_reset);
>  void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev,
>                                    const struct amdgpu_vm_pte_funcs *vm_pte_funcs);
> +void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
> +                                        const struct amdgpu_buffer_funcs *buffer_funcs);
>
>  /* atpx handler */
>  #if defined(CONFIG_VGA_SWITCHEROO)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 0c0489395edf..4da8de34be3d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -3700,7 +3700,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>         adev->num_rings = 0;
>         RCU_INIT_POINTER(adev->gang_submit, dma_fence_get_stub());
>         adev->mman.buffer_funcs = NULL;
> -       adev->mman.buffer_funcs_ring = NULL;
> +       adev->mman.num_buffer_funcs_scheds = 0;
>         adev->vm_manager.vm_pte_funcs = NULL;
>         adev->vm_manager.vm_pte_num_scheds = 0;
>         adev->gmc.gmc_funcs = NULL;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index e9e53c7c37d0..1a253e4257ff 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -708,12 +708,14 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
>  void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
>                               uint32_t vmhub, uint32_t flush_type)
>  {
> -       struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
> +       struct amdgpu_ring *ring;
>         struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
>         struct dma_fence *fence;
>         struct amdgpu_job *job;
>         int r;
>
> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
> +
>         if (!hub->sdma_invalidation_workaround || vmid ||
>             !adev->mman.buffer_funcs_enabled || !adev->ib_pool_ready ||
>             !ring->sched.ready) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 3c63f87832e4..4ba7321b75e3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -168,7 +168,7 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entit
>  {
>         struct amdgpu_ring *ring;
>
> -       ring = adev->mman.buffer_funcs_ring;
> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>         amdgpu_ring_pad_ib(ring, &job->ibs[0]);
>         WARN_ON(job->ibs[0].length_dw > num_dw);
>
> @@ -2349,18 +2349,17 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>                 return;
>
>         if (enable) {
> -               struct amdgpu_ring *ring;
>                 struct drm_gpu_scheduler *sched;
>
> -               if (!adev->mman.buffer_funcs_ring || !adev->mman.buffer_funcs_ring->sched.ready) {
> +               if (!adev->mman.num_buffer_funcs_scheds ||
> +                   !adev->mman.buffer_funcs_scheds[0]->ready) {
>                         dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
>                         return;
>                 }
>
>                 num_clear_entities = 1;
>                 num_move_entities = 1;
> -               ring = adev->mman.buffer_funcs_ring;
> -               sched = &ring->sched;
> +               sched = adev->mman.buffer_funcs_scheds[0];
>                 r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
>                                                   &adev->mman.default_entity,
>                                                   DRM_SCHED_PRIORITY_KERNEL,
> @@ -2497,7 +2496,7 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
>         unsigned int i;
>         int r;
>
> -       ring = adev->mman.buffer_funcs_ring;
> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>
>         if (!ring->sched.ready) {
>                 dev_err(adev->dev,
> @@ -2730,6 +2729,27 @@ int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type)
>         return ttm_resource_manager_evict_all(&adev->mman.bdev, man);
>  }
>
> +void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
> +                                        const struct amdgpu_buffer_funcs *buffer_funcs)
> +{
> +       struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];

Only gfx9 and newer have multiple hubs.  Additionally, sdma 4.x is
attached to mmhub.  sdma 5.x is attached to gfxhub.  Might be worth a
comment here that this is just for the sdma_invalidation_workaround
check so it's only relevant for specific chips that have that set in
case someone attempts to do something else here in the future.

Alex

> +       struct drm_gpu_scheduler *sched;
> +       int i;
> +
> +       adev->mman.buffer_funcs = buffer_funcs;
> +
> +       for (i = 0; i < adev->sdma.num_instances; i++) {
> +               if (adev->sdma.has_page_queue)
> +                       sched = &adev->sdma.instance[i].page.sched;
> +               else
> +                       sched = &adev->sdma.instance[i].ring.sched;
> +               adev->mman.buffer_funcs_scheds[i] = sched;
> +       }
> +
> +       adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
> +               1 : adev->sdma.num_instances;
> +}
> +
>  #if defined(CONFIG_DEBUG_FS)
>
>  static int amdgpu_ttm_page_pool_show(struct seq_file *m, void *unused)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index 3b1973611446..a6249252948b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -67,7 +67,8 @@ struct amdgpu_mman {
>
>         /* buffer handling */
>         const struct amdgpu_buffer_funcs        *buffer_funcs;
> -       struct amdgpu_ring                      *buffer_funcs_ring;
> +       struct drm_gpu_scheduler                *buffer_funcs_scheds[AMDGPU_MAX_RINGS];
> +       u32                                     num_buffer_funcs_scheds;
>         bool                                    buffer_funcs_enabled;
>
>         /* @default_entity: for workarounds, has no gart windows */
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
> index 22780c09177d..26276dcfd458 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
> @@ -1340,8 +1340,7 @@ static const struct amdgpu_buffer_funcs cik_sdma_buffer_funcs = {
>
>  static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &cik_sdma_buffer_funcs;
> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &cik_sdma_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version cik_sdma_ip_block =
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
> index 0090ace49024..c6a059ca59e5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
> @@ -1235,8 +1235,7 @@ static const struct amdgpu_buffer_funcs sdma_v2_4_buffer_funcs = {
>
>  static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &sdma_v2_4_buffer_funcs;
> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v2_4_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version sdma_v2_4_ip_block = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
> index 2526d393162a..cb516a25210d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
> @@ -1677,8 +1677,7 @@ static const struct amdgpu_buffer_funcs sdma_v3_0_buffer_funcs = {
>
>  static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &sdma_v3_0_buffer_funcs;
> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v3_0_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version sdma_v3_0_ip_block =
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> index 44f0f23e1148..d56be26f216b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> @@ -2626,13 +2626,9 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_buffer_funcs = {
>  static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
>  {
>         if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) >= IP_VERSION(4, 4, 0))
> -               adev->mman.buffer_funcs = &sdma_v4_4_buffer_funcs;
> +               amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_buffer_funcs);
>         else
> -               adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
> -       if (adev->sdma.has_page_queue)
> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
> -       else
> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +               amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_0_buffer_funcs);
>  }
>
>  static void sdma_v4_0_get_ras_error_count(uint32_t value,
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> index 78bdfed0a7fd..67e9697301b4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> @@ -2316,11 +2316,7 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_2_buffer_funcs = {
>
>  static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &sdma_v4_4_2_buffer_funcs;
> -       if (adev->sdma.has_page_queue)
> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
> -       else
> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_2_buffer_funcs);
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> index 52f4e9e099cb..86f5eb784d57 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> @@ -2052,10 +2052,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_0_buffer_funcs = {
>
>  static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       if (adev->mman.buffer_funcs == NULL) {
> -               adev->mman.buffer_funcs = &sdma_v5_0_buffer_funcs;
> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> -       }
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_0_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version sdma_v5_0_ip_block = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> index b4fb90cc8f7d..3fec838374b2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> @@ -2056,10 +2056,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_2_buffer_funcs = {
>
>  static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       if (adev->mman.buffer_funcs == NULL) {
> -               adev->mman.buffer_funcs = &sdma_v5_2_buffer_funcs;
> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> -       }
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_2_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version sdma_v5_2_ip_block = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> index b005672f2f96..064508cecd11 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> @@ -1895,8 +1895,7 @@ static const struct amdgpu_buffer_funcs sdma_v6_0_buffer_funcs = {
>
>  static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &sdma_v6_0_buffer_funcs;
> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v6_0_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version sdma_v6_0_ip_block = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> index 5679a94d0815..60447729271e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> @@ -1845,8 +1845,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_0_buffer_funcs = {
>
>  static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &sdma_v7_0_buffer_funcs;
> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_0_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version sdma_v7_0_ip_block = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
> index f20e0fc3fc74..c3428d2731dc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
> @@ -1764,8 +1764,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_1_buffer_funcs = {
>
>  static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &sdma_v7_1_buffer_funcs;
> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_1_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version sdma_v7_1_ip_block = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
> index 3e58feb2d5e4..155067c20a0e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
> @@ -833,8 +833,7 @@ static const struct amdgpu_buffer_funcs si_dma_buffer_funcs = {
>
>  static void si_dma_set_buffer_funcs(struct amdgpu_device *adev)
>  {
> -       adev->mman.buffer_funcs = &si_dma_buffer_funcs;
> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &si_dma_buffer_funcs);
>  }
>
>  const struct amdgpu_ip_block_version si_dma_ip_block =
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
> index 964efa325908..28dc6886c1ff 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
> @@ -129,13 +129,14 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys,
>                              struct dma_fence **mfence)
>  {
>         const u64 GTT_MAX_PAGES = AMDGPU_GTT_MAX_TRANSFER_SIZE;
> -       struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
> +       struct amdgpu_ring *ring;
>         struct amdgpu_ttm_buffer_entity *entity;
>         u64 gart_s, gart_d;
>         struct dma_fence *next;
>         u64 size;
>         int r;
>
> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>         entity = &adev->mman.move_entities[0];
>
>         mutex_lock(&entity->lock);
> --
> 2.43.0
>

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

* Re: [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman
  2026-04-03 15:08 ` [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Alex Deucher
@ 2026-04-07  8:07   ` Christian König
  2026-04-08  8:29     ` Pierre-Eric Pelloux-Prayer
  0 siblings, 1 reply; 20+ messages in thread
From: Christian König @ 2026-04-07  8:07 UTC (permalink / raw)
  To: Alex Deucher, Pierre-Eric Pelloux-Prayer
  Cc: Alex Deucher, David Airlie, Simona Vetter, Felix Kuehling,
	amd-gfx, dri-devel, linux-kernel

On 4/3/26 17:08, Alex Deucher wrote:
> On Fri, Apr 3, 2026 at 4:36 AM Pierre-Eric Pelloux-Prayer
> <pierre-eric.pelloux-prayer@amd.com> wrote:
>>
>> This will allow the use of all of them for clear/fill buffer
>> operations.
>> Since drm_sched_entity_init requires a scheduler array, we
>> store schedulers rather than rings. For the few places that need
>> access to a ring, we can get it from the sched using container_of.
>>
>> Since the code is the same for all sdma versions, add a new
>> helper amdgpu_sdma_set_buffer_funcs_scheds to set buffer_funcs_scheds
>> based on the number of sdma instances.
>>
>> Note: the new sched array is identical to the amdgpu_vm_manager one.
>> These 2 could be merged.
>>
>> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
>> Acked-by: Felix Kuehling <felix.kuehling@amd.com>
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 ++
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +-
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c    |  4 ++-
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 32 ++++++++++++++++++----
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  3 +-
>>  drivers/gpu/drm/amd/amdgpu/cik_sdma.c      |  3 +-
>>  drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c     |  3 +-
>>  drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c     |  3 +-
>>  drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c     |  8 ++----
>>  drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c   |  6 +---
>>  drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c     |  5 +---
>>  drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c     |  5 +---
>>  drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c     |  3 +-
>>  drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c     |  3 +-
>>  drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c     |  3 +-
>>  drivers/gpu/drm/amd/amdgpu/si_dma.c        |  3 +-
>>  drivers/gpu/drm/amd/amdkfd/kfd_migrate.c   |  3 +-
>>  17 files changed, 48 insertions(+), 43 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> index 49e7881750fa..e3a8701f0b27 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> @@ -1467,6 +1467,8 @@ ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring);
>>  ssize_t amdgpu_show_reset_mask(char *buf, uint32_t supported_reset);
>>  void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev,
>>                                    const struct amdgpu_vm_pte_funcs *vm_pte_funcs);
>> +void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
>> +                                        const struct amdgpu_buffer_funcs *buffer_funcs);
>>
>>  /* atpx handler */
>>  #if defined(CONFIG_VGA_SWITCHEROO)
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index 0c0489395edf..4da8de34be3d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -3700,7 +3700,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>>         adev->num_rings = 0;
>>         RCU_INIT_POINTER(adev->gang_submit, dma_fence_get_stub());
>>         adev->mman.buffer_funcs = NULL;
>> -       adev->mman.buffer_funcs_ring = NULL;
>> +       adev->mman.num_buffer_funcs_scheds = 0;
>>         adev->vm_manager.vm_pte_funcs = NULL;
>>         adev->vm_manager.vm_pte_num_scheds = 0;
>>         adev->gmc.gmc_funcs = NULL;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
>> index e9e53c7c37d0..1a253e4257ff 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
>> @@ -708,12 +708,14 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
>>  void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
>>                               uint32_t vmhub, uint32_t flush_type)
>>  {
>> -       struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
>> +       struct amdgpu_ring *ring;
>>         struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
>>         struct dma_fence *fence;
>>         struct amdgpu_job *job;
>>         int r;
>>
>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>> +
>>         if (!hub->sdma_invalidation_workaround || vmid ||
>>             !adev->mman.buffer_funcs_enabled || !adev->ib_pool_ready ||
>>             !ring->sched.ready) {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 3c63f87832e4..4ba7321b75e3 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -168,7 +168,7 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entit
>>  {
>>         struct amdgpu_ring *ring;
>>
>> -       ring = adev->mman.buffer_funcs_ring;
>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>>         amdgpu_ring_pad_ib(ring, &job->ibs[0]);
>>         WARN_ON(job->ibs[0].length_dw > num_dw);
>>
>> @@ -2349,18 +2349,17 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>                 return;
>>
>>         if (enable) {
>> -               struct amdgpu_ring *ring;
>>                 struct drm_gpu_scheduler *sched;
>>
>> -               if (!adev->mman.buffer_funcs_ring || !adev->mman.buffer_funcs_ring->sched.ready) {
>> +               if (!adev->mman.num_buffer_funcs_scheds ||
>> +                   !adev->mman.buffer_funcs_scheds[0]->ready) {
>>                         dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
>>                         return;
>>                 }
>>
>>                 num_clear_entities = 1;
>>                 num_move_entities = 1;
>> -               ring = adev->mman.buffer_funcs_ring;
>> -               sched = &ring->sched;
>> +               sched = adev->mman.buffer_funcs_scheds[0];
>>                 r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
>>                                                   &adev->mman.default_entity,
>>                                                   DRM_SCHED_PRIORITY_KERNEL,
>> @@ -2497,7 +2496,7 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
>>         unsigned int i;
>>         int r;
>>
>> -       ring = adev->mman.buffer_funcs_ring;
>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>>
>>         if (!ring->sched.ready) {
>>                 dev_err(adev->dev,
>> @@ -2730,6 +2729,27 @@ int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type)
>>         return ttm_resource_manager_evict_all(&adev->mman.bdev, man);
>>  }
>>
>> +void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
>> +                                        const struct amdgpu_buffer_funcs *buffer_funcs)
>> +{
>> +       struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
> 
> Only gfx9 and newer have multiple hubs.  Additionally, sdma 4.x is
> attached to mmhub.  sdma 5.x is attached to gfxhub.  Might be worth a
> comment here that this is just for the sdma_invalidation_workaround
> check so it's only relevant for specific chips that have that set in
> case someone attempts to do something else here in the future.

IIRC this workaround only applies to Navi 1x and there the SDMA is connected to the gfxhub.

But I agree that this really needs at least a comment explaining why we do this.

Christian.

> 
> Alex
> 
>> +       struct drm_gpu_scheduler *sched;
>> +       int i;
>> +
>> +       adev->mman.buffer_funcs = buffer_funcs;
>> +
>> +       for (i = 0; i < adev->sdma.num_instances; i++) {
>> +               if (adev->sdma.has_page_queue)
>> +                       sched = &adev->sdma.instance[i].page.sched;
>> +               else
>> +                       sched = &adev->sdma.instance[i].ring.sched;
>> +               adev->mman.buffer_funcs_scheds[i] = sched;
>> +       }
>> +
>> +       adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
>> +               1 : adev->sdma.num_instances;
>> +}
>> +
>>  #if defined(CONFIG_DEBUG_FS)
>>
>>  static int amdgpu_ttm_page_pool_show(struct seq_file *m, void *unused)
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> index 3b1973611446..a6249252948b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> @@ -67,7 +67,8 @@ struct amdgpu_mman {
>>
>>         /* buffer handling */
>>         const struct amdgpu_buffer_funcs        *buffer_funcs;
>> -       struct amdgpu_ring                      *buffer_funcs_ring;
>> +       struct drm_gpu_scheduler                *buffer_funcs_scheds[AMDGPU_MAX_RINGS];
>> +       u32                                     num_buffer_funcs_scheds;
>>         bool                                    buffer_funcs_enabled;
>>
>>         /* @default_entity: for workarounds, has no gart windows */
>> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
>> index 22780c09177d..26276dcfd458 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
>> @@ -1340,8 +1340,7 @@ static const struct amdgpu_buffer_funcs cik_sdma_buffer_funcs = {
>>
>>  static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &cik_sdma_buffer_funcs;
>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &cik_sdma_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version cik_sdma_ip_block =
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
>> index 0090ace49024..c6a059ca59e5 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
>> @@ -1235,8 +1235,7 @@ static const struct amdgpu_buffer_funcs sdma_v2_4_buffer_funcs = {
>>
>>  static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &sdma_v2_4_buffer_funcs;
>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v2_4_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version sdma_v2_4_ip_block = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
>> index 2526d393162a..cb516a25210d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
>> @@ -1677,8 +1677,7 @@ static const struct amdgpu_buffer_funcs sdma_v3_0_buffer_funcs = {
>>
>>  static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &sdma_v3_0_buffer_funcs;
>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v3_0_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version sdma_v3_0_ip_block =
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
>> index 44f0f23e1148..d56be26f216b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
>> @@ -2626,13 +2626,9 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_buffer_funcs = {
>>  static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>>         if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) >= IP_VERSION(4, 4, 0))
>> -               adev->mman.buffer_funcs = &sdma_v4_4_buffer_funcs;
>> +               amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_buffer_funcs);
>>         else
>> -               adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
>> -       if (adev->sdma.has_page_queue)
>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
>> -       else
>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +               amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_0_buffer_funcs);
>>  }
>>
>>  static void sdma_v4_0_get_ras_error_count(uint32_t value,
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
>> index 78bdfed0a7fd..67e9697301b4 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
>> @@ -2316,11 +2316,7 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_2_buffer_funcs = {
>>
>>  static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &sdma_v4_4_2_buffer_funcs;
>> -       if (adev->sdma.has_page_queue)
>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
>> -       else
>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_2_buffer_funcs);
>>  }
>>
>>  /**
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
>> index 52f4e9e099cb..86f5eb784d57 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
>> @@ -2052,10 +2052,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_0_buffer_funcs = {
>>
>>  static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       if (adev->mman.buffer_funcs == NULL) {
>> -               adev->mman.buffer_funcs = &sdma_v5_0_buffer_funcs;
>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> -       }
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_0_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version sdma_v5_0_ip_block = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
>> index b4fb90cc8f7d..3fec838374b2 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
>> @@ -2056,10 +2056,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_2_buffer_funcs = {
>>
>>  static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       if (adev->mman.buffer_funcs == NULL) {
>> -               adev->mman.buffer_funcs = &sdma_v5_2_buffer_funcs;
>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> -       }
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_2_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version sdma_v5_2_ip_block = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
>> index b005672f2f96..064508cecd11 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
>> @@ -1895,8 +1895,7 @@ static const struct amdgpu_buffer_funcs sdma_v6_0_buffer_funcs = {
>>
>>  static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &sdma_v6_0_buffer_funcs;
>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v6_0_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version sdma_v6_0_ip_block = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
>> index 5679a94d0815..60447729271e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
>> @@ -1845,8 +1845,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_0_buffer_funcs = {
>>
>>  static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &sdma_v7_0_buffer_funcs;
>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_0_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version sdma_v7_0_ip_block = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
>> index f20e0fc3fc74..c3428d2731dc 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
>> @@ -1764,8 +1764,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_1_buffer_funcs = {
>>
>>  static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &sdma_v7_1_buffer_funcs;
>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_1_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version sdma_v7_1_ip_block = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
>> index 3e58feb2d5e4..155067c20a0e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
>> @@ -833,8 +833,7 @@ static const struct amdgpu_buffer_funcs si_dma_buffer_funcs = {
>>
>>  static void si_dma_set_buffer_funcs(struct amdgpu_device *adev)
>>  {
>> -       adev->mman.buffer_funcs = &si_dma_buffer_funcs;
>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &si_dma_buffer_funcs);
>>  }
>>
>>  const struct amdgpu_ip_block_version si_dma_ip_block =
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
>> index 964efa325908..28dc6886c1ff 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
>> @@ -129,13 +129,14 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys,
>>                              struct dma_fence **mfence)
>>  {
>>         const u64 GTT_MAX_PAGES = AMDGPU_GTT_MAX_TRANSFER_SIZE;
>> -       struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
>> +       struct amdgpu_ring *ring;
>>         struct amdgpu_ttm_buffer_entity *entity;
>>         u64 gart_s, gart_d;
>>         struct dma_fence *next;
>>         u64 size;
>>         int r;
>>
>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>>         entity = &adev->mman.move_entities[0];
>>
>>         mutex_lock(&entity->lock);
>> --
>> 2.43.0
>>


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

* Re: [PATCH v5 2/7] drm/amdgpu: only use working sdma schedulers for ttm
  2026-04-03  8:35 ` [PATCH v5 2/7] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
@ 2026-04-07  8:11   ` Christian König
  0 siblings, 0 replies; 20+ messages in thread
From: Christian König @ 2026-04-07  8:11 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
	Simona Vetter
  Cc: amd-gfx, dri-devel, linux-kernel

On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
> It's possible that some sdma instances aren't working so we shouldn't try
> to use them from TTM. To achieve this, delay the call to
> amdgpu_sdma_set_buffer_funcs_scheds after the rings have been tested, and
> then use the 'ready' property to decide if a sched should be used or not.
> 
> Note that currently it's not doing much, because if the ring helper fails
> for any ring, the whole sdma block init fails.
> 
> ---
> v5: check buffer_funcs_enabled from amdgpu_ttm_access_memory_sdma
> ---
> 
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c  | 23 ++++++++++++++++-------
>  drivers/gpu/drm/amd/amdgpu/cik_sdma.c    | 10 ++++++++--
>  drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c   |  5 +++--
>  drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c   |  5 +++--
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c   |  9 +++++++--
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c |  6 ++++--
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c   |  6 ++++--
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c   |  9 +++++++--
>  drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c   |  2 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c   |  2 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c   |  9 +++++++--
>  drivers/gpu/drm/amd/amdgpu/si_dma.c      |  9 +++++++--
>  12 files changed, 68 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 4ba7321b75e3..bd32113292ec 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1560,7 +1560,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo,
>  	if (!adev->mman.sdma_access_ptr)
>  		return -EACCES;
>  
> -	if (!drm_dev_enter(adev_to_drm(adev), &idx))
> +	if (!adev->mman.buffer_funcs_enabled || !drm_dev_enter(adev_to_drm(adev), &idx))
>  		return -ENODEV;
>  
>  	if (write)
> @@ -2351,8 +2351,7 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>  	if (enable) {
>  		struct drm_gpu_scheduler *sched;
>  
> -		if (!adev->mman.num_buffer_funcs_scheds ||
> -		    !adev->mman.buffer_funcs_scheds[0]->ready) {
> +		if (!adev->mman.num_buffer_funcs_scheds) {
>  			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
>  			return;
>  		}
> @@ -2734,20 +2733,30 @@ void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
>  {
>  	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
>  	struct drm_gpu_scheduler *sched;
> -	int i;
> +	int i, n;
>  
>  	adev->mman.buffer_funcs = buffer_funcs;
>  
> -	for (i = 0; i < adev->sdma.num_instances; i++) {
> +	for (i = 0, n = 0; i < adev->sdma.num_instances; i++) {
>  		if (adev->sdma.has_page_queue)
>  			sched = &adev->sdma.instance[i].page.sched;
>  		else
>  			sched = &adev->sdma.instance[i].ring.sched;
> -		adev->mman.buffer_funcs_scheds[i] = sched;
> +
> +		if (!sched->ready)
> +			continue;
> +
> +		adev->mman.buffer_funcs_scheds[n++] = sched;
> +	}
> +
> +	if (n == 0) {
> +		adev->mman.num_buffer_funcs_scheds = 0;
> +		drm_warn(&adev->ddev, "No working sdma ring available\n");
> +		return;
>  	}
>  
>  	adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
> -		1 : adev->sdma.num_instances;
> +		1 : n;
>  }
>  
>  #if defined(CONFIG_DEBUG_FS)
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
> index 26276dcfd458..120da838ac28 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
> @@ -939,7 +939,6 @@ static int cik_sdma_early_init(struct amdgpu_ip_block *ip_block)
>  
>  	cik_sdma_set_ring_funcs(adev);
>  	cik_sdma_set_irq_funcs(adev);
> -	cik_sdma_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &cik_sdma_vm_pte_funcs);
>  
>  	return 0;
> @@ -1000,8 +999,15 @@ static int cik_sdma_sw_fini(struct amdgpu_ip_block *ip_block)
>  static int cik_sdma_hw_init(struct amdgpu_ip_block *ip_block)
>  {
>  	struct amdgpu_device *adev = ip_block->adev;
> +	int r;
>  
> -	return cik_sdma_start(adev);
> +	r = cik_sdma_start(adev);
> +	if (r)
> +		return r;
> +
> +	cik_sdma_set_buffer_funcs(adev);
> +
> +	return 0;
>  }
>  
>  static int cik_sdma_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
> index c6a059ca59e5..93ec52c1f367 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
> @@ -828,7 +828,6 @@ static int sdma_v2_4_early_init(struct amdgpu_ip_block *ip_block)
>  		return r;
>  
>  	sdma_v2_4_set_ring_funcs(adev);
> -	sdma_v2_4_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v2_4_vm_pte_funcs);
>  	sdma_v2_4_set_irq_funcs(adev);
>  
> @@ -898,7 +897,9 @@ static int sdma_v2_4_hw_init(struct amdgpu_ip_block *ip_block)
>  	if (r)
>  		return r;
>  
> -	return r;
> +	sdma_v2_4_set_buffer_funcs(adev);
> +
> +	return 0;
>  }
>  
>  static int sdma_v2_4_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
> index cb516a25210d..3fde9be74690 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
> @@ -1108,7 +1108,6 @@ static int sdma_v3_0_early_init(struct amdgpu_ip_block *ip_block)
>  		return r;
>  
>  	sdma_v3_0_set_ring_funcs(adev);
> -	sdma_v3_0_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v3_0_vm_pte_funcs);
>  	sdma_v3_0_set_irq_funcs(adev);
>  
> @@ -1184,7 +1183,9 @@ static int sdma_v3_0_hw_init(struct amdgpu_ip_block *ip_block)
>  	if (r)
>  		return r;
>  
> -	return r;
> +	sdma_v3_0_set_buffer_funcs(adev);
> +
> +	return 0;
>  }
>  
>  static int sdma_v3_0_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> index d56be26f216b..8a2a4e61867e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> @@ -1775,7 +1775,6 @@ static int sdma_v4_0_early_init(struct amdgpu_ip_block *ip_block)
>  		adev->sdma.has_page_queue = true;
>  
>  	sdma_v4_0_set_ring_funcs(adev);
> -	sdma_v4_0_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_0_vm_pte_funcs);
>  	sdma_v4_0_set_irq_funcs(adev);
>  	sdma_v4_0_set_ras_funcs(adev);
> @@ -1961,6 +1960,7 @@ static int sdma_v4_0_sw_fini(struct amdgpu_ip_block *ip_block)
>  static int sdma_v4_0_hw_init(struct amdgpu_ip_block *ip_block)
>  {
>  	struct amdgpu_device *adev = ip_block->adev;
> +	int r;
>  
>  	if (adev->flags & AMD_IS_APU)
>  		amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false, 0);
> @@ -1968,7 +1968,12 @@ static int sdma_v4_0_hw_init(struct amdgpu_ip_block *ip_block)
>  	if (!amdgpu_sriov_vf(adev))
>  		sdma_v4_0_init_golden_registers(adev);
>  
> -	return sdma_v4_0_start(adev);
> +	r = sdma_v4_0_start(adev);
> +	if (r)
> +		return r;
> +	sdma_v4_0_set_buffer_funcs(adev);
> +
> +	return 0;
>  }
>  
>  static int sdma_v4_0_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> index 67e9697301b4..88428b88e00f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> @@ -1368,7 +1368,6 @@ static int sdma_v4_4_2_early_init(struct amdgpu_ip_block *ip_block)
>  		adev->sdma.has_page_queue = true;
>  
>  	sdma_v4_4_2_set_ring_funcs(adev);
> -	sdma_v4_4_2_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_4_2_vm_pte_funcs);
>  	sdma_v4_4_2_set_irq_funcs(adev);
>  	sdma_v4_4_2_set_ras_funcs(adev);
> @@ -1568,8 +1567,11 @@ static int sdma_v4_4_2_hw_init(struct amdgpu_ip_block *ip_block)
>  		sdma_v4_4_2_inst_init_golden_registers(adev, inst_mask);
>  
>  	r = sdma_v4_4_2_inst_start(adev, inst_mask, false);
> +	if (r)
> +		return r;
> +	sdma_v4_4_2_set_buffer_funcs(adev);
>  
> -	return r;
> +	return 0;
>  }
>  
>  static int sdma_v4_4_2_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> index 86f5eb784d57..fa02907217e0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> @@ -1373,7 +1373,6 @@ static int sdma_v5_0_early_init(struct amdgpu_ip_block *ip_block)
>  		return r;
>  
>  	sdma_v5_0_set_ring_funcs(adev);
> -	sdma_v5_0_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_0_vm_pte_funcs);
>  	sdma_v5_0_set_irq_funcs(adev);
>  	sdma_v5_0_set_mqd_funcs(adev);
> @@ -1472,8 +1471,11 @@ static int sdma_v5_0_hw_init(struct amdgpu_ip_block *ip_block)
>  	sdma_v5_0_init_golden_registers(adev);
>  
>  	r = sdma_v5_0_start(adev);
> +	if (r)
> +		return r;
> +	sdma_v5_0_set_buffer_funcs(adev);
>  
> -	return r;
> +	return 0;
>  }
>  
>  static int sdma_v5_0_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> index 3fec838374b2..f6ecbc524c9b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> @@ -1264,7 +1264,6 @@ static int sdma_v5_2_early_init(struct amdgpu_ip_block *ip_block)
>  		return r;
>  
>  	sdma_v5_2_set_ring_funcs(adev);
> -	sdma_v5_2_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_2_vm_pte_funcs);
>  	sdma_v5_2_set_irq_funcs(adev);
>  	sdma_v5_2_set_mqd_funcs(adev);
> @@ -1385,8 +1384,14 @@ static int sdma_v5_2_sw_fini(struct amdgpu_ip_block *ip_block)
>  static int sdma_v5_2_hw_init(struct amdgpu_ip_block *ip_block)
>  {
>  	struct amdgpu_device *adev = ip_block->adev;
> +	int r;
>  
> -	return sdma_v5_2_start(adev);
> +	r = sdma_v5_2_start(adev);
> +	if (r)
> +		return r;
> +	sdma_v5_2_set_buffer_funcs(adev);
> +
> +	return 0;
>  }
>  
>  static int sdma_v5_2_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> index 064508cecd11..ee83d3e5978e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> @@ -1313,7 +1313,6 @@ static int sdma_v6_0_early_init(struct amdgpu_ip_block *ip_block)
>  		return r;
>  
>  	sdma_v6_0_set_ring_funcs(adev);
> -	sdma_v6_0_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v6_0_vm_pte_funcs);
>  	sdma_v6_0_set_irq_funcs(adev);
>  	sdma_v6_0_set_mqd_funcs(adev);
> @@ -1477,6 +1476,7 @@ static int sdma_v6_0_hw_init(struct amdgpu_ip_block *ip_block)
>  	r = sdma_v6_0_start(adev);
>  	if (r)
>  		return r;
> +	sdma_v6_0_set_buffer_funcs(adev);
>  
>  	return sdma_v6_0_set_userq_trap_interrupts(adev, true);
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> index 60447729271e..c8343981c596 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> @@ -1299,7 +1299,6 @@ static int sdma_v7_0_early_init(struct amdgpu_ip_block *ip_block)
>  	}
>  
>  	sdma_v7_0_set_ring_funcs(adev);
> -	sdma_v7_0_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_0_vm_pte_funcs);
>  	sdma_v7_0_set_irq_funcs(adev);
>  	sdma_v7_0_set_mqd_funcs(adev);
> @@ -1432,6 +1431,7 @@ static int sdma_v7_0_hw_init(struct amdgpu_ip_block *ip_block)
>  	r = sdma_v7_0_start(adev);
>  	if (r)
>  		return r;
> +	sdma_v7_0_set_buffer_funcs(adev);
>  
>  	return sdma_v7_0_set_userq_trap_interrupts(adev, true);
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
> index c3428d2731dc..b1ca95c2623b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
> @@ -1275,7 +1275,6 @@ static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block)
>  	}
>  
>  	sdma_v7_1_set_ring_funcs(adev);
> -	sdma_v7_1_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_1_vm_pte_funcs);
>  	sdma_v7_1_set_irq_funcs(adev);
>  	sdma_v7_1_set_mqd_funcs(adev);
> @@ -1374,10 +1373,16 @@ static int sdma_v7_1_hw_init(struct amdgpu_ip_block *ip_block)
>  {
>  	struct amdgpu_device *adev = ip_block->adev;
>  	uint32_t inst_mask;
> +	int r;
>  
>  	inst_mask = GENMASK(adev->sdma.num_instances - 1, 0);
>  
> -	return sdma_v7_1_inst_start(adev, inst_mask);
> +	r = sdma_v7_1_inst_start(adev, inst_mask);
> +	if (r)
> +		return r;
> +	sdma_v7_1_set_buffer_funcs(adev);
> +
> +	return 0;
>  }
>  
>  static int sdma_v7_1_hw_fini(struct amdgpu_ip_block *ip_block)
> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
> index 155067c20a0e..549708075eb4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
> @@ -487,7 +487,6 @@ static int si_dma_early_init(struct amdgpu_ip_block *ip_block)
>  	adev->sdma.num_instances = SDMA_MAX_INSTANCE;
>  
>  	si_dma_set_ring_funcs(adev);
> -	si_dma_set_buffer_funcs(adev);
>  	amdgpu_sdma_set_vm_pte_scheds(adev, &si_dma_vm_pte_funcs);
>  	si_dma_set_irq_funcs(adev);
>  
> @@ -543,8 +542,14 @@ static int si_dma_sw_fini(struct amdgpu_ip_block *ip_block)
>  static int si_dma_hw_init(struct amdgpu_ip_block *ip_block)
>  {
>  	struct amdgpu_device *adev = ip_block->adev;
> +	int r;
>  
> -	return si_dma_start(adev);
> +	r = si_dma_start(adev);
> +	if (r)
> +		return r;
> +	si_dma_set_buffer_funcs(adev);
> +
> +	return 0;
>  }
>  
>  static int si_dma_hw_fini(struct amdgpu_ip_block *ip_block)


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

* Re: [PATCH v5 3/7] drm/amdgpu: create multiple clear/move ttm entities
  2026-04-03  8:35 ` [PATCH v5 3/7] drm/amdgpu: create multiple clear/move ttm entities Pierre-Eric Pelloux-Prayer
@ 2026-04-07 10:01   ` Christian König
  0 siblings, 0 replies; 20+ messages in thread
From: Christian König @ 2026-04-07 10:01 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
	Simona Vetter
  Cc: amd-gfx, dri-devel, linux-kernel

On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
> This enables parallelism of operations.
> 
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index bd32113292ec..83f6d00dc3a0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -2356,8 +2356,8 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>  			return;
>  		}
>  
> -		num_clear_entities = 1;
> -		num_move_entities = 1;
> +		num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
> +		num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
>  		sched = adev->mman.buffer_funcs_scheds[0];
>  		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
>  						  &adev->mman.default_entity,


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

* Re: [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds
  2026-04-03  8:35 ` [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds Pierre-Eric Pelloux-Prayer
@ 2026-04-07 10:05   ` Christian König
  2026-04-08  8:26     ` Pierre-Eric Pelloux-Prayer
  0 siblings, 1 reply; 20+ messages in thread
From: Christian König @ 2026-04-07 10:05 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
	Simona Vetter
  Cc: amd-gfx, dri-devel, linux-kernel

On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
> With this change we now have as many clear and move entities as we
> have sdma engines (limited to TTM_NUM_MOVE_FENCES).
> 
> To enable load-balancing this patch gives access to all sdma
> schedulers to all entities.
> 
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
> Reviewed-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 83f6d00dc3a0..648ad344e89c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -2349,8 +2349,6 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>  		return;
>  
>  	if (enable) {
> -		struct drm_gpu_scheduler *sched;
> -
>  		if (!adev->mman.num_buffer_funcs_scheds) {
>  			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
>  			return;
> @@ -2358,11 +2356,10 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>  
>  		num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
>  		num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
> -		sched = adev->mman.buffer_funcs_scheds[0];
>  		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
>  						  &adev->mman.default_entity,
>  						  DRM_SCHED_PRIORITY_KERNEL,
> -						  &sched, 1, 0);
> +						  adev->mman.buffer_funcs_scheds, 1, 0);

Why still giving num_schedulers as 1 here???

>  		if (r < 0) {
>  			dev_err(adev->dev,
>  				"Failed setting up TTM entity (%d)\n", r);
> @@ -2380,8 +2377,11 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>  
>  		for (i = 0; i < num_clear_entities; i++) {
>  			r = amdgpu_ttm_buffer_entity_init(
> -				&adev->mman.gtt_mgr, &adev->mman.clear_entities[i],
> -				DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 1);
> +				&adev->mman.gtt_mgr,
> +				&adev->mman.clear_entities[i],
> +				DRM_SCHED_PRIORITY_NORMAL,

That should be DRM_SCHED_PRIORITY_KERNEL, same below.

Regards,
Christian.

> +				adev->mman.buffer_funcs_scheds,
> +				adev->mman.num_buffer_funcs_scheds, 1);
>  
>  			if (r < 0) {
>  				for (j = 0; j < i; j++)
> @@ -2400,7 +2400,9 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>  			r = amdgpu_ttm_buffer_entity_init(
>  				&adev->mman.gtt_mgr,
>  				&adev->mman.move_entities[i],
> -				DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 2);
> +				DRM_SCHED_PRIORITY_NORMAL,
> +				adev->mman.buffer_funcs_scheds,
> +				adev->mman.num_buffer_funcs_scheds, 2);
>  
>  			if (r < 0) {
>  				for (j = 0; j < i; j++)


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

* Re: [PATCH v5 5/7] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer
  2026-04-03  8:35 ` [PATCH v5 5/7] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
@ 2026-04-07 10:09   ` Christian König
  2026-04-07 10:11     ` Christian König
  0 siblings, 1 reply; 20+ messages in thread
From: Christian König @ 2026-04-07 10:09 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
	Simona Vetter, Sumit Semwal
  Cc: amd-gfx, dri-devel, linux-kernel, linux-media, linaro-mm-sig



On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
> It's doing the same thing as amdgpu_fill_buffer(src_data=0), so drop it.
> 
> The only caveat is that amdgpu_res_cleared() return value is only valid
> right after allocation.
> 
> ---
> v2: introduce new "bool consider_clear_status" arg
> ---
> 
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 16 ++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 88 +++++-----------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  6 +-
>  3 files changed, 32 insertions(+), 78 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index 66c20dd46d12..d0884bbffa75 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -717,13 +717,17 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
>  	    bo->tbo.resource->mem_type == TTM_PL_VRAM) {
>  		struct dma_fence *fence;
>  
> -		r = amdgpu_ttm_clear_buffer(bo, bo->tbo.base.resv, &fence);
> +		r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
> +				       bo, 0, NULL, &fence,
> +				       true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
>  		if (unlikely(r))
>  			goto fail_unreserve;
>  
> -		dma_resv_add_fence(bo->tbo.base.resv, fence,
> -				   DMA_RESV_USAGE_KERNEL);
> -		dma_fence_put(fence);
> +		if (fence) {
> +			dma_resv_add_fence(bo->tbo.base.resv, fence,
> +					   DMA_RESV_USAGE_KERNEL);
> +			dma_fence_put(fence);
> +		}
>  	}
>  	if (!bp->resv)
>  		amdgpu_bo_unreserve(bo);
> @@ -1326,8 +1330,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
>  		goto out;
>  
>  	r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
> -			       abo, 0, &bo->base._resv,
> -			       &fence, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
> +			       abo, 0, &bo->base._resv, &fence,
> +			       false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
>  	if (WARN_ON(r))
>  		goto out;
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 648ad344e89c..a3d0998b8cec 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -418,7 +418,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
>  	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
>  		struct dma_fence *wipe_fence = NULL;
>  		r = amdgpu_fill_buffer(entity, abo, 0, NULL, &wipe_fence,
> -				       AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
> +				       false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
>  		if (r) {
>  			goto error;
>  		} else if (wipe_fence) {
> @@ -2572,76 +2572,25 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
>  }
>  
>  /**
> - * amdgpu_ttm_clear_buffer - clear memory buffers
> - * @bo: amdgpu buffer object
> - * @resv: reservation object
> - * @fence: dma_fence associated with the operation
> + * amdgpu_fill_buffer - fill a buffer with a given value
> + * @entity: entity to use
> + * @bo: the bo to fill
> + * @src_data: the value to set
> + * @resv: fences contained in this reservation will be used as dependencies.
> + * @out_fence: the fence from the last clear will be stored here. It might be
> + *             NULL if no job was run.
> + * @dependency: optional input dependency fence.
> + * @consider_clear_status: true if region reported as cleared by amdgpu_res_cleared()
> + *                         are skipped.
> + * @k_job_id: trace id
>   *
> - * Clear the memory buffer resource.
> - *
> - * Returns:
> - * 0 for success or a negative error code on failure.
>   */
> -int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
> -			    struct dma_resv *resv,
> -			    struct dma_fence **fence)
> -{
> -	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
> -	struct amdgpu_ttm_buffer_entity *entity;
> -	struct amdgpu_res_cursor cursor;
> -	u64 addr;
> -	int r = 0;
> -
> -	if (!adev->mman.buffer_funcs_enabled)
> -		return -EINVAL;
> -
> -	if (!fence)
> -		return -EINVAL;
> -	entity = &adev->mman.clear_entities[0];
> -	*fence = dma_fence_get_stub();
> -
> -	amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
> -
> -	mutex_lock(&entity->lock);
> -	while (cursor.remaining) {
> -		struct dma_fence *next = NULL;
> -		u64 size;
> -
> -		if (amdgpu_res_cleared(&cursor)) {
> -			amdgpu_res_next(&cursor, cursor.size);
> -			continue;
> -		}
> -
> -		/* Never clear more than 256MiB at once to avoid timeouts */
> -		size = min(cursor.size, 256ULL << 20);
> -
> -		r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &cursor,
> -					  0, false, &size, &addr);
> -		if (r)
> -			goto err;
> -
> -		r = amdgpu_ttm_fill_mem(adev, entity, 0, addr, size, resv,
> -					&next, true,
> -					AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
> -		if (r)
> -			goto err;
> -
> -		dma_fence_put(*fence);
> -		*fence = next;
> -
> -		amdgpu_res_next(&cursor, size);
> -	}
> -err:
> -	mutex_unlock(&entity->lock);
> -
> -	return r;
> -}
> -
>  int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,

We should probably rename the function to amdgpu_ttm_clear_buffer() while doing this.

Apart from that looks good to me.

Regards,
Christian.

>  		       struct amdgpu_bo *bo,
>  		       uint32_t src_data,
>  		       struct dma_resv *resv,
> -		       struct dma_fence **f,
> +		       struct dma_fence **out_fence,
> +		       bool consider_clear_status,
>  		       u64 k_job_id)
>  {
>  	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
> @@ -2659,6 +2608,11 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>  		struct dma_fence *next;
>  		uint64_t cur_size, to;
>  
> +		if (consider_clear_status && amdgpu_res_cleared(&dst)) {
> +			amdgpu_res_next(&dst, dst.size);
> +			continue;
> +		}
> +
>  		/* Never fill more than 256MiB at once to avoid timeouts */
>  		cur_size = min(dst.size, 256ULL << 20);
>  
> @@ -2680,9 +2634,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>  	}
>  error:
>  	mutex_unlock(&entity->lock);
> -	if (f)
> -		*f = dma_fence_get(fence);
> -	dma_fence_put(fence);
> +	*out_fence = fence;
>  	return r;
>  }
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index a6249252948b..436a3e09a178 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -187,14 +187,12 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
>  		       struct dma_resv *resv,
>  		       struct dma_fence **fence,
>  		       bool vm_needs_flush, uint32_t copy_flags);
> -int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
> -			    struct dma_resv *resv,
> -			    struct dma_fence **fence);
>  int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>  		       struct amdgpu_bo *bo,
>  		       uint32_t src_data,
>  		       struct dma_resv *resv,
> -		       struct dma_fence **f,
> +		       struct dma_fence **out_fence,
> +		       bool consider_clear_status,
>  		       u64 k_job_id);
>  struct amdgpu_ttm_buffer_entity *amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev);
>  


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

* Re: [PATCH v5 5/7] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer
  2026-04-07 10:09   ` Christian König
@ 2026-04-07 10:11     ` Christian König
  0 siblings, 0 replies; 20+ messages in thread
From: Christian König @ 2026-04-07 10:11 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
	Simona Vetter, Sumit Semwal
  Cc: amd-gfx, dri-devel, linux-kernel, linux-media, linaro-mm-sig



On 4/7/26 12:09, Christian König wrote:
> 
> 
> On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
>> It's doing the same thing as amdgpu_fill_buffer(src_data=0), so drop it.
>>
>> The only caveat is that amdgpu_res_cleared() return value is only valid
>> right after allocation.
>>
>> ---
>> v2: introduce new "bool consider_clear_status" arg
>> ---
>>
>> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 16 ++--
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 88 +++++-----------------
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  6 +-
>>  3 files changed, 32 insertions(+), 78 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> index 66c20dd46d12..d0884bbffa75 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> @@ -717,13 +717,17 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
>>  	    bo->tbo.resource->mem_type == TTM_PL_VRAM) {
>>  		struct dma_fence *fence;
>>  
>> -		r = amdgpu_ttm_clear_buffer(bo, bo->tbo.base.resv, &fence);
>> +		r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
>> +				       bo, 0, NULL, &fence,
>> +				       true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
>>  		if (unlikely(r))
>>  			goto fail_unreserve;
>>  
>> -		dma_resv_add_fence(bo->tbo.base.resv, fence,
>> -				   DMA_RESV_USAGE_KERNEL);
>> -		dma_fence_put(fence);
>> +		if (fence) {
>> +			dma_resv_add_fence(bo->tbo.base.resv, fence,
>> +					   DMA_RESV_USAGE_KERNEL);
>> +			dma_fence_put(fence);
>> +		}
>>  	}
>>  	if (!bp->resv)
>>  		amdgpu_bo_unreserve(bo);
>> @@ -1326,8 +1330,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
>>  		goto out;
>>  
>>  	r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
>> -			       abo, 0, &bo->base._resv,
>> -			       &fence, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
>> +			       abo, 0, &bo->base._resv, &fence,
>> +			       false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
>>  	if (WARN_ON(r))
>>  		goto out;
>>  
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 648ad344e89c..a3d0998b8cec 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -418,7 +418,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
>>  	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
>>  		struct dma_fence *wipe_fence = NULL;
>>  		r = amdgpu_fill_buffer(entity, abo, 0, NULL, &wipe_fence,
>> -				       AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
>> +				       false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
>>  		if (r) {
>>  			goto error;
>>  		} else if (wipe_fence) {
>> @@ -2572,76 +2572,25 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
>>  }
>>  
>>  /**
>> - * amdgpu_ttm_clear_buffer - clear memory buffers
>> - * @bo: amdgpu buffer object
>> - * @resv: reservation object
>> - * @fence: dma_fence associated with the operation
>> + * amdgpu_fill_buffer - fill a buffer with a given value
>> + * @entity: entity to use
>> + * @bo: the bo to fill
>> + * @src_data: the value to set
>> + * @resv: fences contained in this reservation will be used as dependencies.
>> + * @out_fence: the fence from the last clear will be stored here. It might be
>> + *             NULL if no job was run.
>> + * @dependency: optional input dependency fence.
>> + * @consider_clear_status: true if region reported as cleared by amdgpu_res_cleared()
>> + *                         are skipped.
>> + * @k_job_id: trace id
>>   *
>> - * Clear the memory buffer resource.
>> - *
>> - * Returns:
>> - * 0 for success or a negative error code on failure.
>>   */
>> -int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
>> -			    struct dma_resv *resv,
>> -			    struct dma_fence **fence)
>> -{
>> -	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>> -	struct amdgpu_ttm_buffer_entity *entity;
>> -	struct amdgpu_res_cursor cursor;
>> -	u64 addr;
>> -	int r = 0;
>> -
>> -	if (!adev->mman.buffer_funcs_enabled)
>> -		return -EINVAL;
>> -
>> -	if (!fence)
>> -		return -EINVAL;
>> -	entity = &adev->mman.clear_entities[0];
>> -	*fence = dma_fence_get_stub();
>> -
>> -	amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
>> -
>> -	mutex_lock(&entity->lock);
>> -	while (cursor.remaining) {
>> -		struct dma_fence *next = NULL;
>> -		u64 size;
>> -
>> -		if (amdgpu_res_cleared(&cursor)) {
>> -			amdgpu_res_next(&cursor, cursor.size);
>> -			continue;
>> -		}
>> -
>> -		/* Never clear more than 256MiB at once to avoid timeouts */
>> -		size = min(cursor.size, 256ULL << 20);
>> -
>> -		r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &cursor,
>> -					  0, false, &size, &addr);
>> -		if (r)
>> -			goto err;
>> -
>> -		r = amdgpu_ttm_fill_mem(adev, entity, 0, addr, size, resv,
>> -					&next, true,
>> -					AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
>> -		if (r)
>> -			goto err;
>> -
>> -		dma_fence_put(*fence);
>> -		*fence = next;
>> -
>> -		amdgpu_res_next(&cursor, size);
>> -	}
>> -err:
>> -	mutex_unlock(&entity->lock);
>> -
>> -	return r;
>> -}
>> -
>>  int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
> 
> We should probably rename the function to amdgpu_ttm_clear_buffer() while doing this.

Forget that, I've just seen that patch #6 does exactly that.

Feel free to add Reviewed-by: Christian König <christian.koenig@amd.com>.

Regards,
Christian.

> 
> Apart from that looks good to me.
> 
> Regards,
> Christian.
> 
>>  		       struct amdgpu_bo *bo,
>>  		       uint32_t src_data,
>>  		       struct dma_resv *resv,
>> -		       struct dma_fence **f,
>> +		       struct dma_fence **out_fence,
>> +		       bool consider_clear_status,
>>  		       u64 k_job_id)
>>  {
>>  	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>> @@ -2659,6 +2608,11 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>>  		struct dma_fence *next;
>>  		uint64_t cur_size, to;
>>  
>> +		if (consider_clear_status && amdgpu_res_cleared(&dst)) {
>> +			amdgpu_res_next(&dst, dst.size);
>> +			continue;
>> +		}
>> +
>>  		/* Never fill more than 256MiB at once to avoid timeouts */
>>  		cur_size = min(dst.size, 256ULL << 20);
>>  
>> @@ -2680,9 +2634,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>>  	}
>>  error:
>>  	mutex_unlock(&entity->lock);
>> -	if (f)
>> -		*f = dma_fence_get(fence);
>> -	dma_fence_put(fence);
>> +	*out_fence = fence;
>>  	return r;
>>  }
>>  
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> index a6249252948b..436a3e09a178 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> @@ -187,14 +187,12 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
>>  		       struct dma_resv *resv,
>>  		       struct dma_fence **fence,
>>  		       bool vm_needs_flush, uint32_t copy_flags);
>> -int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
>> -			    struct dma_resv *resv,
>> -			    struct dma_fence **fence);
>>  int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>>  		       struct amdgpu_bo *bo,
>>  		       uint32_t src_data,
>>  		       struct dma_resv *resv,
>> -		       struct dma_fence **f,
>> +		       struct dma_fence **out_fence,
>> +		       bool consider_clear_status,
>>  		       u64 k_job_id);
>>  struct amdgpu_ttm_buffer_entity *amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev);
>>  
> 


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

* Re: [PATCH v5 6/7] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer
  2026-04-03  8:35 ` [PATCH v5 6/7] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
@ 2026-04-07 10:16   ` Christian König
  2026-04-08  8:28     ` Pierre-Eric Pelloux-Prayer
  0 siblings, 1 reply; 20+ messages in thread
From: Christian König @ 2026-04-07 10:16 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
	Simona Vetter, Sumit Semwal
  Cc: amd-gfx, dri-devel, linux-kernel, linux-media, linaro-mm-sig



On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
> This is the only use case for this function.
> 
> ---
> v2: amdgpu_ttm_clear_buffer instead of amdgpu_clear_buffer
> ---
> 
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
> Reviewed-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 +++++------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 23 ++++++++++------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    | 13 ++++++------
>  3 files changed, 22 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index d0884bbffa75..195cb1c814d1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -717,9 +717,9 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
>  	    bo->tbo.resource->mem_type == TTM_PL_VRAM) {
>  		struct dma_fence *fence;
>  
> -		r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
> -				       bo, 0, NULL, &fence,
> -				       true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
> +		r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
> +					    bo, NULL, &fence,

Wait a second. Why is the dependency NULL here?

Could it be that we relied on the fact that clears and moves were serialized in the past?

Regards,
Christian.

> +					    true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
>  		if (unlikely(r))
>  			goto fail_unreserve;
>  
> @@ -1329,9 +1329,9 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
>  	if (r)
>  		goto out;
>  
> -	r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
> -			       abo, 0, &bo->base._resv, &fence,
> -			       false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
> +	r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
> +				    abo, &bo->base._resv, &fence,
> +				    false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
>  	if (WARN_ON(r))
>  		goto out;
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index a3d0998b8cec..e74f9f8a88dc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -417,8 +417,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
>  	if (old_mem->mem_type == TTM_PL_VRAM &&
>  	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
>  		struct dma_fence *wipe_fence = NULL;
> -		r = amdgpu_fill_buffer(entity, abo, 0, NULL, &wipe_fence,
> -				       false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
> +		r = amdgpu_ttm_clear_buffer(entity, abo, NULL, &wipe_fence,
> +					    false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
>  		if (r) {
>  			goto error;
>  		} else if (wipe_fence) {
> @@ -2572,26 +2572,23 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
>  }
>  
>  /**
> - * amdgpu_fill_buffer - fill a buffer with a given value
> + * amdgpu_ttm_clear_buffer - fill a buffer with 0
>   * @entity: entity to use
>   * @bo: the bo to fill
> - * @src_data: the value to set
>   * @resv: fences contained in this reservation will be used as dependencies.
>   * @out_fence: the fence from the last clear will be stored here. It might be
>   *             NULL if no job was run.
> - * @dependency: optional input dependency fence.
>   * @consider_clear_status: true if region reported as cleared by amdgpu_res_cleared()
>   *                         are skipped.
>   * @k_job_id: trace id
>   *
>   */
> -int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
> -		       struct amdgpu_bo *bo,
> -		       uint32_t src_data,
> -		       struct dma_resv *resv,
> -		       struct dma_fence **out_fence,
> -		       bool consider_clear_status,
> -		       u64 k_job_id)
> +int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
> +			    struct amdgpu_bo *bo,
> +			    struct dma_resv *resv,
> +			    struct dma_fence **out_fence,
> +			    bool consider_clear_status,
> +			    u64 k_job_id)
>  {
>  	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>  	struct dma_fence *fence = NULL;
> @@ -2622,7 +2619,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>  			goto error;
>  
>  		r = amdgpu_ttm_fill_mem(adev, entity,
> -					src_data, to, cur_size, resv,
> +					0, to, cur_size, resv,
>  					&next, true, k_job_id);
>  		if (r)
>  			goto error;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index 436a3e09a178..d7b14d5cac77 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -187,13 +187,12 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
>  		       struct dma_resv *resv,
>  		       struct dma_fence **fence,
>  		       bool vm_needs_flush, uint32_t copy_flags);
> -int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
> -		       struct amdgpu_bo *bo,
> -		       uint32_t src_data,
> -		       struct dma_resv *resv,
> -		       struct dma_fence **out_fence,
> -		       bool consider_clear_status,
> -		       u64 k_job_id);
> +int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
> +			    struct amdgpu_bo *bo,
> +			    struct dma_resv *resv,
> +			    struct dma_fence **out_fence,
> +			    bool consider_clear_status,
> +			    u64 k_job_id);
>  struct amdgpu_ttm_buffer_entity *amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev);
>  
>  int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);


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

* Re: [PATCH v5 7/7] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs
  2026-04-03  8:35 ` [PATCH v5 7/7] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs Pierre-Eric Pelloux-Prayer
@ 2026-04-07 10:24   ` Christian König
  0 siblings, 0 replies; 20+ messages in thread
From: Christian König @ 2026-04-07 10:24 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
	Simona Vetter
  Cc: amd-gfx, dri-devel, linux-kernel

On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
> Makes a code slightly clearer and reduces indentation.
> 
> ---
> v5: use amdgpu_in_reset in amdgpu_ttm_disable_buffer_funcs
> ---
> 
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
> Suggested-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  14 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 186 +++++++++++----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |   4 +-
>  3 files changed, 108 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 4da8de34be3d..a24f52e71850 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -2463,7 +2463,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
>  	if (r)
>  		goto init_failed;
>  
> -	amdgpu_ttm_set_buffer_funcs_status(adev, true);
> +	amdgpu_ttm_enable_buffer_funcs(adev);
>  
>  	/* Don't init kfd if whole hive need to be reset during init */
>  	if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
> @@ -3147,7 +3147,7 @@ static int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
>  		amdgpu_virt_request_full_gpu(adev, false);
>  	}
>  
> -	amdgpu_ttm_set_buffer_funcs_status(adev, false);
> +	amdgpu_ttm_disable_buffer_funcs(adev);
>  
>  	r = amdgpu_device_ip_suspend_phase1(adev);
>  	if (r)
> @@ -3362,7 +3362,7 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
>  
>  	r = amdgpu_device_ip_resume_phase2(adev);
>  
> -	amdgpu_ttm_set_buffer_funcs_status(adev, true);
> +	amdgpu_ttm_enable_buffer_funcs(adev);
>  
>  	if (r)
>  		return r;
> @@ -4215,7 +4215,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
>  	/* disable ras feature must before hw fini */
>  	amdgpu_ras_pre_fini(adev);
>  
> -	amdgpu_ttm_set_buffer_funcs_status(adev, false);
> +	amdgpu_ttm_disable_buffer_funcs(adev);
>  
>  	/*
>  	 * device went through surprise hotplug; we need to destroy topology
> @@ -4482,7 +4482,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
>  	if (r)
>  		goto unwind_userq;
>  
> -	amdgpu_ttm_set_buffer_funcs_status(adev, false);
> +	amdgpu_ttm_disable_buffer_funcs(adev);
>  
>  	amdgpu_fence_driver_hw_fini(adev);
>  
> @@ -4496,7 +4496,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
>  	return 0;
>  
>  unwind_evict:
> -	amdgpu_ttm_set_buffer_funcs_status(adev, true);
> +	amdgpu_ttm_enable_buffer_funcs(adev);
>  	amdgpu_fence_driver_hw_init(adev);
>  
>  unwind_userq:
> @@ -5230,7 +5230,7 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context)
>  				if (r)
>  					goto out;
>  
> -				amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
> +				amdgpu_ttm_enable_buffer_funcs(tmp_adev);
>  
>  				r = amdgpu_device_ip_resume_phase3(tmp_adev);
>  				if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index e74f9f8a88dc..9bbd8149ffd2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -2100,7 +2100,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>  	}
>  
>  	/* Change the size here instead of the init above so only lpfn is affected */
> -	amdgpu_ttm_set_buffer_funcs_status(adev, false);
> +	amdgpu_ttm_disable_buffer_funcs(adev);
>  #ifdef CONFIG_64BIT
>  #ifdef CONFIG_X86
>  	if (adev->gmc.xgmi.connected_to_cpu)
> @@ -2329,115 +2329,91 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
>  }
>  
>  /**
> - * amdgpu_ttm_set_buffer_funcs_status - enable/disable use of buffer functions
> + * amdgpu_ttm_enable_buffer_funcs - enable use of buffer functions
>   *
>   * @adev: amdgpu_device pointer
> - * @enable: true when we can use buffer functions.
>   *
> - * Enable/disable use of buffer functions during suspend/resume. This should
> + * Enable use of buffer functions during suspend/resume. This should
>   * only be called at bootup or when userspace isn't running.
>   */
> -void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
> +void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
>  {
>  	struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
>  	u32 num_clear_entities, num_move_entities;
> -	uint64_t size;
>  	int r, i, j;
>  
>  	if (!adev->mman.initialized || amdgpu_in_reset(adev) ||
> -	    adev->mman.buffer_funcs_enabled == enable || adev->gmc.is_app_apu)
> +	    adev->mman.buffer_funcs_enabled || adev->gmc.is_app_apu)
>  		return;
>  
> -	if (enable) {
> -		if (!adev->mman.num_buffer_funcs_scheds) {
> -			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
> -			return;
> -		}
> +	if (!adev->mman.num_buffer_funcs_scheds) {
> +		dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
> +		return;
> +	}
> +
> +	r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
> +						&adev->mman.default_entity,
> +						DRM_SCHED_PRIORITY_KERNEL,
> +						adev->mman.buffer_funcs_scheds, 1, 0);
> +	if (r < 0) {
> +		dev_err(adev->dev,
> +			"Failed setting up TTM entity (%d)\n", r);
> +		return;
> +	}
> +
> +	num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
> +	num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
> +
> +	adev->mman.clear_entities = kcalloc(num_clear_entities,
> +						sizeof(struct amdgpu_ttm_buffer_entity),
> +						GFP_KERNEL);
> +	atomic_set(&adev->mman.next_clear_entity, 0);
> +	if (!adev->mman.clear_entities)
> +		goto error_free_default_entity;
> +
> +	adev->mman.num_clear_entities = num_clear_entities;
> +
> +	for (i = 0; i < num_clear_entities; i++) {
> +		r = amdgpu_ttm_buffer_entity_init(
> +			&adev->mman.gtt_mgr,
> +			&adev->mman.clear_entities[i],
> +			DRM_SCHED_PRIORITY_NORMAL,
> +			adev->mman.buffer_funcs_scheds,
> +			adev->mman.num_buffer_funcs_scheds, 1);
>  
> -		num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
> -		num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
> -		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
> -						  &adev->mman.default_entity,
> -						  DRM_SCHED_PRIORITY_KERNEL,
> -						  adev->mman.buffer_funcs_scheds, 1, 0);
>  		if (r < 0) {
> -			dev_err(adev->dev,
> -				"Failed setting up TTM entity (%d)\n", r);
> -			return;
> -		}
> -
> -		adev->mman.clear_entities = kcalloc(num_clear_entities,
> -						    sizeof(struct amdgpu_ttm_buffer_entity),
> -						    GFP_KERNEL);
> -		atomic_set(&adev->mman.next_clear_entity, 0);
> -		if (!adev->mman.clear_entities)
> +			for (j = 0; j < i; j++)
> +				amdgpu_ttm_buffer_entity_fini(
> +					&adev->mman.gtt_mgr, &adev->mman.clear_entities[j]);
> +			adev->mman.num_clear_entities = 0;
> +			kfree(adev->mman.clear_entities);
>  			goto error_free_default_entity;
> -
> -		adev->mman.num_clear_entities = num_clear_entities;
> -
> -		for (i = 0; i < num_clear_entities; i++) {
> -			r = amdgpu_ttm_buffer_entity_init(
> -				&adev->mman.gtt_mgr,
> -				&adev->mman.clear_entities[i],
> -				DRM_SCHED_PRIORITY_NORMAL,
> -				adev->mman.buffer_funcs_scheds,
> -				adev->mman.num_buffer_funcs_scheds, 1);
> -
> -			if (r < 0) {
> -				for (j = 0; j < i; j++)
> -					amdgpu_ttm_buffer_entity_fini(
> -						&adev->mman.gtt_mgr, &adev->mman.clear_entities[j]);
> -				kfree(adev->mman.clear_entities);
> -				adev->mman.num_clear_entities = 0;
> -				adev->mman.clear_entities = NULL;
> -				goto error_free_default_entity;
> -			}
>  		}
> +	}
>  
> -		adev->mman.num_move_entities = num_move_entities;
> -		atomic_set(&adev->mman.next_move_entity, 0);
> -		for (i = 0; i < num_move_entities; i++) {
> -			r = amdgpu_ttm_buffer_entity_init(
> -				&adev->mman.gtt_mgr,
> -				&adev->mman.move_entities[i],
> -				DRM_SCHED_PRIORITY_NORMAL,
> -				adev->mman.buffer_funcs_scheds,
> -				adev->mman.num_buffer_funcs_scheds, 2);
> +	adev->mman.num_move_entities = num_move_entities;
> +	atomic_set(&adev->mman.next_move_entity, 0);
> +	for (i = 0; i < num_move_entities; i++) {
> +		r = amdgpu_ttm_buffer_entity_init(
> +			&adev->mman.gtt_mgr,
> +			&adev->mman.move_entities[i],
> +			DRM_SCHED_PRIORITY_NORMAL,
> +			adev->mman.buffer_funcs_scheds,
> +			adev->mman.num_buffer_funcs_scheds, 2);
>  
> -			if (r < 0) {
> -				for (j = 0; j < i; j++)
> -					amdgpu_ttm_buffer_entity_fini(
> -						&adev->mman.gtt_mgr, &adev->mman.move_entities[j]);
> -				adev->mman.num_move_entities = 0;
> -				goto error_free_clear_entities;
> -			}
> +		if (r < 0) {
> +			for (j = 0; j < i; j++)
> +				amdgpu_ttm_buffer_entity_fini(
> +					&adev->mman.gtt_mgr,
> +					&adev->mman.move_entities[j]);
> +			adev->mman.num_move_entities = 0;
> +			goto error_free_clear_entities;
>  		}
> -	} else {
> -		amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
> -					      &adev->mman.default_entity);
> -		for (i = 0; i < adev->mman.num_clear_entities; i++)
> -			amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
> -						      &adev->mman.clear_entities[i]);
> -		for (i = 0; i < adev->mman.num_move_entities; i++)
> -			amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
> -						      &adev->mman.move_entities[i]);
> -		/* Drop all the old fences since re-creating the scheduler entities
> -		 * will allocate new contexts.
> -		 */
> -		ttm_resource_manager_cleanup(man);
> -		kfree(adev->mman.clear_entities);
> -		adev->mman.clear_entities = NULL;
> -		adev->mman.num_clear_entities = 0;
> -		adev->mman.num_move_entities = 0;
>  	}
>  
>  	/* this just adjusts TTM size idea, which sets lpfn to the correct value */
> -	if (enable)
> -		size = adev->gmc.real_vram_size;
> -	else
> -		size = adev->gmc.visible_vram_size;
> -	man->size = size;
> -	adev->mman.buffer_funcs_enabled = enable;
> +	man->size = adev->gmc.real_vram_size;
> +	adev->mman.buffer_funcs_enabled = true;
>  
>  	return;
>  
> @@ -2453,6 +2429,42 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>  				      &adev->mman.default_entity);
>  }
>  
> +/**
> + * amdgpu_ttm_disable_buffer_funcs - disable use of buffer functions
> + *
> + * @adev: amdgpu_device pointer
> + */
> +void amdgpu_ttm_disable_buffer_funcs(struct amdgpu_device *adev)
> +{
> +	struct ttm_resource_manager *man =
> +		ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
> +	int i;
> +
> +	if (!adev->mman.buffer_funcs_enabled || amdgpu_in_reset(adev))
> +		return;
> +
> +	amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
> +				      &adev->mman.default_entity);
> +	for (i = 0; i < adev->mman.num_move_entities; i++)
> +		amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
> +					      &adev->mman.move_entities[i]);
> +	for (i = 0; i < adev->mman.num_clear_entities; i++)
> +		amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
> +					      &adev->mman.clear_entities[i]);
> +	/* Drop all the old fences since re-creating the scheduler entities
> +	 * will allocate new contexts.
> +	 */
> +	ttm_resource_manager_cleanup(man);
> +
> +	kfree(adev->mman.clear_entities);
> +	adev->mman.clear_entities = NULL;
> +	adev->mman.num_clear_entities = 0;
> +	adev->mman.num_move_entities = 0;
> +
> +	man->size = adev->gmc.visible_vram_size;
> +	adev->mman.buffer_funcs_enabled = false;
> +}
> +
>  static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
>  				  struct amdgpu_ttm_buffer_entity *entity,
>  				  unsigned int num_dw,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index d7b14d5cac77..8a5f34aaabac 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -178,8 +178,8 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
>  
>  int amdgpu_ttm_init(struct amdgpu_device *adev);
>  void amdgpu_ttm_fini(struct amdgpu_device *adev);
> -void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
> -					bool enable);
> +void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev);
> +void amdgpu_ttm_disable_buffer_funcs(struct amdgpu_device *adev);
>  int amdgpu_copy_buffer(struct amdgpu_device *adev,
>  		       struct amdgpu_ttm_buffer_entity *entity,
>  		       uint64_t src_offset,


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

* Re: [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds
  2026-04-07 10:05   ` Christian König
@ 2026-04-08  8:26     ` Pierre-Eric Pelloux-Prayer
  2026-04-08  8:28       ` Christian König
  0 siblings, 1 reply; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08  8:26 UTC (permalink / raw)
  To: Christian König, Pierre-Eric Pelloux-Prayer, Alex Deucher,
	David Airlie, Simona Vetter
  Cc: amd-gfx, dri-devel



Le 07/04/2026 à 12:05, Christian König a écrit :
> On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
>> With this change we now have as many clear and move entities as we
>> have sdma engines (limited to TTM_NUM_MOVE_FENCES).
>>
>> To enable load-balancing this patch gives access to all sdma
>> schedulers to all entities.
>>
>> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
>> Reviewed-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 16 +++++++++-------
>>   1 file changed, 9 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 83f6d00dc3a0..648ad344e89c 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -2349,8 +2349,6 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>   		return;
>>   
>>   	if (enable) {
>> -		struct drm_gpu_scheduler *sched;
>> -
>>   		if (!adev->mman.num_buffer_funcs_scheds) {
>>   			dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
>>   			return;
>> @@ -2358,11 +2356,10 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>   
>>   		num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
>>   		num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
>> -		sched = adev->mman.buffer_funcs_scheds[0];
>>   		r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
>>   						  &adev->mman.default_entity,
>>   						  DRM_SCHED_PRIORITY_KERNEL,
>> -						  &sched, 1, 0);
>> +						  adev->mman.buffer_funcs_scheds, 1, 0);
> 
> Why still giving num_schedulers as 1 here???
> 

Because I think multiple schedulers aren't useful for this entity. But if you prefer I can pass all 
available schedulers to all ttm entities (in which case I'd remove the parameters from 
amdgpu_ttm_buffer_entity_init).

>>   		if (r < 0) {
>>   			dev_err(adev->dev,
>>   				"Failed setting up TTM entity (%d)\n", r);
>> @@ -2380,8 +2377,11 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>   
>>   		for (i = 0; i < num_clear_entities; i++) {
>>   			r = amdgpu_ttm_buffer_entity_init(
>> -				&adev->mman.gtt_mgr, &adev->mman.clear_entities[i],
>> -				DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 1);
>> +				&adev->mman.gtt_mgr,
>> +				&adev->mman.clear_entities[i],
>> +				DRM_SCHED_PRIORITY_NORMAL,
> 
> That should be DRM_SCHED_PRIORITY_KERNEL, same below.

OK, will update in v6.

Thanks,
Pierre-Eric


> 
> Regards,
> Christian.
> 
>> +				adev->mman.buffer_funcs_scheds,
>> +				adev->mman.num_buffer_funcs_scheds, 1);
>>   
>>   			if (r < 0) {
>>   				for (j = 0; j < i; j++)
>> @@ -2400,7 +2400,9 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>   			r = amdgpu_ttm_buffer_entity_init(
>>   				&adev->mman.gtt_mgr,
>>   				&adev->mman.move_entities[i],
>> -				DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 2);
>> +				DRM_SCHED_PRIORITY_NORMAL,
>> +				adev->mman.buffer_funcs_scheds,
>> +				adev->mman.num_buffer_funcs_scheds, 2);
>>   
>>   			if (r < 0) {
>>   				for (j = 0; j < i; j++)

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

* Re: [PATCH v5 6/7] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer
  2026-04-07 10:16   ` Christian König
@ 2026-04-08  8:28     ` Pierre-Eric Pelloux-Prayer
  0 siblings, 0 replies; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08  8:28 UTC (permalink / raw)
  To: Christian König, Pierre-Eric Pelloux-Prayer, Alex Deucher,
	David Airlie, Simona Vetter, Sumit Semwal
  Cc: amd-gfx, dri-devel



Le 07/04/2026 à 12:16, Christian König a écrit :
> 
> 
> On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
>> This is the only use case for this function.
>>
>> ---
>> v2: amdgpu_ttm_clear_buffer instead of amdgpu_clear_buffer
>> ---
>>
>> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
>> Reviewed-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 +++++------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 23 ++++++++++------------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    | 13 ++++++------
>>   3 files changed, 22 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> index d0884bbffa75..195cb1c814d1 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> @@ -717,9 +717,9 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
>>   	    bo->tbo.resource->mem_type == TTM_PL_VRAM) {
>>   		struct dma_fence *fence;
>>   
>> -		r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
>> -				       bo, 0, NULL, &fence,
>> -				       true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
>> +		r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
>> +					    bo, NULL, &fence,
> 
> Wait a second. Why is the dependency NULL here?
> 

Good catch.

> Could it be that we relied on the fact that clears and moves were serialized in the past?
> 

No it's a mistake in the previous patch where the resv param was dropped. I've fixed it in v6.

Thanks,
PE


> Regards,
> Christian.
> 
>> +					    true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
>>   		if (unlikely(r))
>>   			goto fail_unreserve;
>>   
>> @@ -1329,9 +1329,9 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
>>   	if (r)
>>   		goto out;
>>   
>> -	r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev),
>> -			       abo, 0, &bo->base._resv, &fence,
>> -			       false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
>> +	r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
>> +				    abo, &bo->base._resv, &fence,
>> +				    false, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
>>   	if (WARN_ON(r))
>>   		goto out;
>>   
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index a3d0998b8cec..e74f9f8a88dc 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -417,8 +417,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
>>   	if (old_mem->mem_type == TTM_PL_VRAM &&
>>   	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
>>   		struct dma_fence *wipe_fence = NULL;
>> -		r = amdgpu_fill_buffer(entity, abo, 0, NULL, &wipe_fence,
>> -				       false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
>> +		r = amdgpu_ttm_clear_buffer(entity, abo, NULL, &wipe_fence,
>> +					    false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
>>   		if (r) {
>>   			goto error;
>>   		} else if (wipe_fence) {
>> @@ -2572,26 +2572,23 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
>>   }
>>   
>>   /**
>> - * amdgpu_fill_buffer - fill a buffer with a given value
>> + * amdgpu_ttm_clear_buffer - fill a buffer with 0
>>    * @entity: entity to use
>>    * @bo: the bo to fill
>> - * @src_data: the value to set
>>    * @resv: fences contained in this reservation will be used as dependencies.
>>    * @out_fence: the fence from the last clear will be stored here. It might be
>>    *             NULL if no job was run.
>> - * @dependency: optional input dependency fence.
>>    * @consider_clear_status: true if region reported as cleared by amdgpu_res_cleared()
>>    *                         are skipped.
>>    * @k_job_id: trace id
>>    *
>>    */
>> -int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>> -		       struct amdgpu_bo *bo,
>> -		       uint32_t src_data,
>> -		       struct dma_resv *resv,
>> -		       struct dma_fence **out_fence,
>> -		       bool consider_clear_status,
>> -		       u64 k_job_id)
>> +int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
>> +			    struct amdgpu_bo *bo,
>> +			    struct dma_resv *resv,
>> +			    struct dma_fence **out_fence,
>> +			    bool consider_clear_status,
>> +			    u64 k_job_id)
>>   {
>>   	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>>   	struct dma_fence *fence = NULL;
>> @@ -2622,7 +2619,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>>   			goto error;
>>   
>>   		r = amdgpu_ttm_fill_mem(adev, entity,
>> -					src_data, to, cur_size, resv,
>> +					0, to, cur_size, resv,
>>   					&next, true, k_job_id);
>>   		if (r)
>>   			goto error;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> index 436a3e09a178..d7b14d5cac77 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> @@ -187,13 +187,12 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
>>   		       struct dma_resv *resv,
>>   		       struct dma_fence **fence,
>>   		       bool vm_needs_flush, uint32_t copy_flags);
>> -int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
>> -		       struct amdgpu_bo *bo,
>> -		       uint32_t src_data,
>> -		       struct dma_resv *resv,
>> -		       struct dma_fence **out_fence,
>> -		       bool consider_clear_status,
>> -		       u64 k_job_id);
>> +int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
>> +			    struct amdgpu_bo *bo,
>> +			    struct dma_resv *resv,
>> +			    struct dma_fence **out_fence,
>> +			    bool consider_clear_status,
>> +			    u64 k_job_id);
>>   struct amdgpu_ttm_buffer_entity *amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev);
>>   
>>   int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);

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

* Re: [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds
  2026-04-08  8:26     ` Pierre-Eric Pelloux-Prayer
@ 2026-04-08  8:28       ` Christian König
  0 siblings, 0 replies; 20+ messages in thread
From: Christian König @ 2026-04-08  8:28 UTC (permalink / raw)
  To: Pierre-Eric Pelloux-Prayer, Pierre-Eric Pelloux-Prayer,
	Alex Deucher, David Airlie, Simona Vetter
  Cc: amd-gfx, dri-devel

On 4/8/26 10:26, Pierre-Eric Pelloux-Prayer wrote:
> 
> 
> Le 07/04/2026 à 12:05, Christian König a écrit :
>> On 4/3/26 10:35, Pierre-Eric Pelloux-Prayer wrote:
>>> With this change we now have as many clear and move entities as we
>>> have sdma engines (limited to TTM_NUM_MOVE_FENCES).
>>>
>>> To enable load-balancing this patch gives access to all sdma
>>> schedulers to all entities.
>>>
>>> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
>>> Reviewed-by: Christian König <christian.koenig@amd.com>
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 16 +++++++++-------
>>>   1 file changed, 9 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> index 83f6d00dc3a0..648ad344e89c 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> @@ -2349,8 +2349,6 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>>           return;
>>>         if (enable) {
>>> -        struct drm_gpu_scheduler *sched;
>>> -
>>>           if (!adev->mman.num_buffer_funcs_scheds) {
>>>               dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
>>>               return;
>>> @@ -2358,11 +2356,10 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>>             num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
>>>           num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
>>> -        sched = adev->mman.buffer_funcs_scheds[0];
>>>           r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
>>>                             &adev->mman.default_entity,
>>>                             DRM_SCHED_PRIORITY_KERNEL,
>>> -                          &sched, 1, 0);
>>> +                          adev->mman.buffer_funcs_scheds, 1, 0);
>>
>> Why still giving num_schedulers as 1 here???
>>
> 
> Because I think multiple schedulers aren't useful for this entity. But if you prefer I can pass all available schedulers to all ttm entities (in which case I'd remove the parameters from amdgpu_ttm_buffer_entity_init).

Ah! Yeah that makes sense, but please add a comment why we do that.

I completely missed that this is for the default_entity.

Regards,
Christian.

> 
>>>           if (r < 0) {
>>>               dev_err(adev->dev,
>>>                   "Failed setting up TTM entity (%d)\n", r);
>>> @@ -2380,8 +2377,11 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>>             for (i = 0; i < num_clear_entities; i++) {
>>>               r = amdgpu_ttm_buffer_entity_init(
>>> -                &adev->mman.gtt_mgr, &adev->mman.clear_entities[i],
>>> -                DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 1);
>>> +                &adev->mman.gtt_mgr,
>>> +                &adev->mman.clear_entities[i],
>>> +                DRM_SCHED_PRIORITY_NORMAL,
>>
>> That should be DRM_SCHED_PRIORITY_KERNEL, same below.
> 
> OK, will update in v6.
> 
> Thanks,
> Pierre-Eric
> 
> 
>>
>> Regards,
>> Christian.
>>
>>> +                adev->mman.buffer_funcs_scheds,
>>> +                adev->mman.num_buffer_funcs_scheds, 1);
>>>                 if (r < 0) {
>>>                   for (j = 0; j < i; j++)
>>> @@ -2400,7 +2400,9 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>>               r = amdgpu_ttm_buffer_entity_init(
>>>                   &adev->mman.gtt_mgr,
>>>                   &adev->mman.move_entities[i],
>>> -                DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 2);
>>> +                DRM_SCHED_PRIORITY_NORMAL,
>>> +                adev->mman.buffer_funcs_scheds,
>>> +                adev->mman.num_buffer_funcs_scheds, 2);
>>>                 if (r < 0) {
>>>                   for (j = 0; j < i; j++)


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

* Re: [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman
  2026-04-07  8:07   ` Christian König
@ 2026-04-08  8:29     ` Pierre-Eric Pelloux-Prayer
  0 siblings, 0 replies; 20+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08  8:29 UTC (permalink / raw)
  To: Christian König, Alex Deucher, Pierre-Eric Pelloux-Prayer
  Cc: Alex Deucher, David Airlie, Simona Vetter, Felix Kuehling,
	amd-gfx, dri-devel



Le 07/04/2026 à 10:07, Christian König a écrit :
> On 4/3/26 17:08, Alex Deucher wrote:
>> On Fri, Apr 3, 2026 at 4:36 AM Pierre-Eric Pelloux-Prayer
>> <pierre-eric.pelloux-prayer@amd.com> wrote:
>>>
>>> This will allow the use of all of them for clear/fill buffer
>>> operations.
>>> Since drm_sched_entity_init requires a scheduler array, we
>>> store schedulers rather than rings. For the few places that need
>>> access to a ring, we can get it from the sched using container_of.
>>>
>>> Since the code is the same for all sdma versions, add a new
>>> helper amdgpu_sdma_set_buffer_funcs_scheds to set buffer_funcs_scheds
>>> based on the number of sdma instances.
>>>
>>> Note: the new sched array is identical to the amdgpu_vm_manager one.
>>> These 2 could be merged.
>>>
>>> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
>>> Acked-by: Felix Kuehling <felix.kuehling@amd.com>
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 ++
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +-
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c    |  4 ++-
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 32 ++++++++++++++++++----
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  3 +-
>>>   drivers/gpu/drm/amd/amdgpu/cik_sdma.c      |  3 +-
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c     |  3 +-
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c     |  3 +-
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c     |  8 ++----
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c   |  6 +---
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c     |  5 +---
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c     |  5 +---
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c     |  3 +-
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c     |  3 +-
>>>   drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c     |  3 +-
>>>   drivers/gpu/drm/amd/amdgpu/si_dma.c        |  3 +-
>>>   drivers/gpu/drm/amd/amdkfd/kfd_migrate.c   |  3 +-
>>>   17 files changed, 48 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>>> index 49e7881750fa..e3a8701f0b27 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>>> @@ -1467,6 +1467,8 @@ ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring);
>>>   ssize_t amdgpu_show_reset_mask(char *buf, uint32_t supported_reset);
>>>   void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev,
>>>                                     const struct amdgpu_vm_pte_funcs *vm_pte_funcs);
>>> +void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
>>> +                                        const struct amdgpu_buffer_funcs *buffer_funcs);
>>>
>>>   /* atpx handler */
>>>   #if defined(CONFIG_VGA_SWITCHEROO)
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> index 0c0489395edf..4da8de34be3d 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> @@ -3700,7 +3700,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>>>          adev->num_rings = 0;
>>>          RCU_INIT_POINTER(adev->gang_submit, dma_fence_get_stub());
>>>          adev->mman.buffer_funcs = NULL;
>>> -       adev->mman.buffer_funcs_ring = NULL;
>>> +       adev->mman.num_buffer_funcs_scheds = 0;
>>>          adev->vm_manager.vm_pte_funcs = NULL;
>>>          adev->vm_manager.vm_pte_num_scheds = 0;
>>>          adev->gmc.gmc_funcs = NULL;
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
>>> index e9e53c7c37d0..1a253e4257ff 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
>>> @@ -708,12 +708,14 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
>>>   void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
>>>                                uint32_t vmhub, uint32_t flush_type)
>>>   {
>>> -       struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
>>> +       struct amdgpu_ring *ring;
>>>          struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
>>>          struct dma_fence *fence;
>>>          struct amdgpu_job *job;
>>>          int r;
>>>
>>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>>> +
>>>          if (!hub->sdma_invalidation_workaround || vmid ||
>>>              !adev->mman.buffer_funcs_enabled || !adev->ib_pool_ready ||
>>>              !ring->sched.ready) {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> index 3c63f87832e4..4ba7321b75e3 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> @@ -168,7 +168,7 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entit
>>>   {
>>>          struct amdgpu_ring *ring;
>>>
>>> -       ring = adev->mman.buffer_funcs_ring;
>>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>>>          amdgpu_ring_pad_ib(ring, &job->ibs[0]);
>>>          WARN_ON(job->ibs[0].length_dw > num_dw);
>>>
>>> @@ -2349,18 +2349,17 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
>>>                  return;
>>>
>>>          if (enable) {
>>> -               struct amdgpu_ring *ring;
>>>                  struct drm_gpu_scheduler *sched;
>>>
>>> -               if (!adev->mman.buffer_funcs_ring || !adev->mman.buffer_funcs_ring->sched.ready) {
>>> +               if (!adev->mman.num_buffer_funcs_scheds ||
>>> +                   !adev->mman.buffer_funcs_scheds[0]->ready) {
>>>                          dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
>>>                          return;
>>>                  }
>>>
>>>                  num_clear_entities = 1;
>>>                  num_move_entities = 1;
>>> -               ring = adev->mman.buffer_funcs_ring;
>>> -               sched = &ring->sched;
>>> +               sched = adev->mman.buffer_funcs_scheds[0];
>>>                  r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
>>>                                                    &adev->mman.default_entity,
>>>                                                    DRM_SCHED_PRIORITY_KERNEL,
>>> @@ -2497,7 +2496,7 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev,
>>>          unsigned int i;
>>>          int r;
>>>
>>> -       ring = adev->mman.buffer_funcs_ring;
>>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>>>
>>>          if (!ring->sched.ready) {
>>>                  dev_err(adev->dev,
>>> @@ -2730,6 +2729,27 @@ int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type)
>>>          return ttm_resource_manager_evict_all(&adev->mman.bdev, man);
>>>   }
>>>
>>> +void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
>>> +                                        const struct amdgpu_buffer_funcs *buffer_funcs)
>>> +{
>>> +       struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
>>
>> Only gfx9 and newer have multiple hubs.  Additionally, sdma 4.x is
>> attached to mmhub.  sdma 5.x is attached to gfxhub.  Might be worth a
>> comment here that this is just for the sdma_invalidation_workaround
>> check so it's only relevant for specific chips that have that set in
>> case someone attempts to do something else here in the future.
> 
> IIRC this workaround only applies to Navi 1x and there the SDMA is connected to the gfxhub.
> 
> But I agree that this really needs at least a comment explaining why we do this.

I added a comment to v6 of this patch, thanks.

Pierre-Eric


> 
> Christian.
> 
>>
>> Alex
>>
>>> +       struct drm_gpu_scheduler *sched;
>>> +       int i;
>>> +
>>> +       adev->mman.buffer_funcs = buffer_funcs;
>>> +
>>> +       for (i = 0; i < adev->sdma.num_instances; i++) {
>>> +               if (adev->sdma.has_page_queue)
>>> +                       sched = &adev->sdma.instance[i].page.sched;
>>> +               else
>>> +                       sched = &adev->sdma.instance[i].ring.sched;
>>> +               adev->mman.buffer_funcs_scheds[i] = sched;
>>> +       }
>>> +
>>> +       adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
>>> +               1 : adev->sdma.num_instances;
>>> +}
>>> +
>>>   #if defined(CONFIG_DEBUG_FS)
>>>
>>>   static int amdgpu_ttm_page_pool_show(struct seq_file *m, void *unused)
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>> index 3b1973611446..a6249252948b 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>> @@ -67,7 +67,8 @@ struct amdgpu_mman {
>>>
>>>          /* buffer handling */
>>>          const struct amdgpu_buffer_funcs        *buffer_funcs;
>>> -       struct amdgpu_ring                      *buffer_funcs_ring;
>>> +       struct drm_gpu_scheduler                *buffer_funcs_scheds[AMDGPU_MAX_RINGS];
>>> +       u32                                     num_buffer_funcs_scheds;
>>>          bool                                    buffer_funcs_enabled;
>>>
>>>          /* @default_entity: for workarounds, has no gart windows */
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
>>> index 22780c09177d..26276dcfd458 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
>>> @@ -1340,8 +1340,7 @@ static const struct amdgpu_buffer_funcs cik_sdma_buffer_funcs = {
>>>
>>>   static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &cik_sdma_buffer_funcs;
>>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &cik_sdma_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version cik_sdma_ip_block =
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
>>> index 0090ace49024..c6a059ca59e5 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
>>> @@ -1235,8 +1235,7 @@ static const struct amdgpu_buffer_funcs sdma_v2_4_buffer_funcs = {
>>>
>>>   static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &sdma_v2_4_buffer_funcs;
>>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v2_4_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version sdma_v2_4_ip_block = {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
>>> index 2526d393162a..cb516a25210d 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
>>> @@ -1677,8 +1677,7 @@ static const struct amdgpu_buffer_funcs sdma_v3_0_buffer_funcs = {
>>>
>>>   static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &sdma_v3_0_buffer_funcs;
>>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v3_0_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version sdma_v3_0_ip_block =
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
>>> index 44f0f23e1148..d56be26f216b 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
>>> @@ -2626,13 +2626,9 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_buffer_funcs = {
>>>   static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>>          if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) >= IP_VERSION(4, 4, 0))
>>> -               adev->mman.buffer_funcs = &sdma_v4_4_buffer_funcs;
>>> +               amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_buffer_funcs);
>>>          else
>>> -               adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
>>> -       if (adev->sdma.has_page_queue)
>>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
>>> -       else
>>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +               amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_0_buffer_funcs);
>>>   }
>>>
>>>   static void sdma_v4_0_get_ras_error_count(uint32_t value,
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
>>> index 78bdfed0a7fd..67e9697301b4 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
>>> @@ -2316,11 +2316,7 @@ static const struct amdgpu_buffer_funcs sdma_v4_4_2_buffer_funcs = {
>>>
>>>   static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &sdma_v4_4_2_buffer_funcs;
>>> -       if (adev->sdma.has_page_queue)
>>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
>>> -       else
>>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v4_4_2_buffer_funcs);
>>>   }
>>>
>>>   /**
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
>>> index 52f4e9e099cb..86f5eb784d57 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
>>> @@ -2052,10 +2052,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_0_buffer_funcs = {
>>>
>>>   static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       if (adev->mman.buffer_funcs == NULL) {
>>> -               adev->mman.buffer_funcs = &sdma_v5_0_buffer_funcs;
>>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> -       }
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_0_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version sdma_v5_0_ip_block = {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
>>> index b4fb90cc8f7d..3fec838374b2 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
>>> @@ -2056,10 +2056,7 @@ static const struct amdgpu_buffer_funcs sdma_v5_2_buffer_funcs = {
>>>
>>>   static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       if (adev->mman.buffer_funcs == NULL) {
>>> -               adev->mman.buffer_funcs = &sdma_v5_2_buffer_funcs;
>>> -               adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> -       }
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v5_2_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version sdma_v5_2_ip_block = {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
>>> index b005672f2f96..064508cecd11 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
>>> @@ -1895,8 +1895,7 @@ static const struct amdgpu_buffer_funcs sdma_v6_0_buffer_funcs = {
>>>
>>>   static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &sdma_v6_0_buffer_funcs;
>>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v6_0_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version sdma_v6_0_ip_block = {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
>>> index 5679a94d0815..60447729271e 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
>>> @@ -1845,8 +1845,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_0_buffer_funcs = {
>>>
>>>   static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &sdma_v7_0_buffer_funcs;
>>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_0_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version sdma_v7_0_ip_block = {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
>>> index f20e0fc3fc74..c3428d2731dc 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
>>> @@ -1764,8 +1764,7 @@ static const struct amdgpu_buffer_funcs sdma_v7_1_buffer_funcs = {
>>>
>>>   static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &sdma_v7_1_buffer_funcs;
>>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &sdma_v7_1_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version sdma_v7_1_ip_block = {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
>>> index 3e58feb2d5e4..155067c20a0e 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
>>> @@ -833,8 +833,7 @@ static const struct amdgpu_buffer_funcs si_dma_buffer_funcs = {
>>>
>>>   static void si_dma_set_buffer_funcs(struct amdgpu_device *adev)
>>>   {
>>> -       adev->mman.buffer_funcs = &si_dma_buffer_funcs;
>>> -       adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
>>> +       amdgpu_sdma_set_buffer_funcs_scheds(adev, &si_dma_buffer_funcs);
>>>   }
>>>
>>>   const struct amdgpu_ip_block_version si_dma_ip_block =
>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
>>> index 964efa325908..28dc6886c1ff 100644
>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
>>> @@ -129,13 +129,14 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys,
>>>                               struct dma_fence **mfence)
>>>   {
>>>          const u64 GTT_MAX_PAGES = AMDGPU_GTT_MAX_TRANSFER_SIZE;
>>> -       struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
>>> +       struct amdgpu_ring *ring;
>>>          struct amdgpu_ttm_buffer_entity *entity;
>>>          u64 gart_s, gart_d;
>>>          struct dma_fence *next;
>>>          u64 size;
>>>          int r;
>>>
>>> +       ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);
>>>          entity = &adev->mman.move_entities[0];
>>>
>>>          mutex_lock(&entity->lock);
>>> --
>>> 2.43.0
>>>

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

end of thread, other threads:[~2026-04-08  8:29 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-03  8:35 [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
2026-04-03  8:35 ` [PATCH v5 2/7] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
2026-04-07  8:11   ` Christian König
2026-04-03  8:35 ` [PATCH v5 3/7] drm/amdgpu: create multiple clear/move ttm entities Pierre-Eric Pelloux-Prayer
2026-04-07 10:01   ` Christian König
2026-04-03  8:35 ` [PATCH v5 4/7] drm/amdgpu: give ttm entities access to all the sdma scheds Pierre-Eric Pelloux-Prayer
2026-04-07 10:05   ` Christian König
2026-04-08  8:26     ` Pierre-Eric Pelloux-Prayer
2026-04-08  8:28       ` Christian König
2026-04-03  8:35 ` [PATCH v5 5/7] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
2026-04-07 10:09   ` Christian König
2026-04-07 10:11     ` Christian König
2026-04-03  8:35 ` [PATCH v5 6/7] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
2026-04-07 10:16   ` Christian König
2026-04-08  8:28     ` Pierre-Eric Pelloux-Prayer
2026-04-03  8:35 ` [PATCH v5 7/7] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs Pierre-Eric Pelloux-Prayer
2026-04-07 10:24   ` Christian König
2026-04-03 15:08 ` [PATCH v5 1/7] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Alex Deucher
2026-04-07  8:07   ` Christian König
2026-04-08  8:29     ` Pierre-Eric Pelloux-Prayer

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.