* [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.