* [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman
@ 2026-04-08 10:03 Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 2/8] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 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 | 36 ++++++++++++++++++----
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, 52 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..63ec3938cd41 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,31 @@ 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 drm_gpu_scheduler *sched;
+ struct amdgpu_vmhub *hub;
+ 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;
+ }
+
+ /* Navi1x's workaround requires us to limit to a single SDMA sched
+ * for ttm.
+ */
+ hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
+ 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] 10+ messages in thread
* [PATCH v6 2/8] drm/amdgpu: only use working sdma schedulers for ttm
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
@ 2026-04-08 10:03 ` Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 3/8] drm/amdgpu: create multiple clear/move ttm entities Pierre-Eric Pelloux-Prayer
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 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>
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 63ec3938cd41..0e9620df91b7 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,16 +2733,26 @@ void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
{
struct drm_gpu_scheduler *sched;
struct amdgpu_vmhub *hub;
- 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;
}
/* Navi1x's workaround requires us to limit to a single SDMA sched
@@ -2751,7 +2760,7 @@ void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
*/
hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
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 [flat|nested] 10+ messages in thread
* [PATCH v6 3/8] drm/amdgpu: create multiple clear/move ttm entities
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 2/8] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
@ 2026-04-08 10:03 ` Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 4/8] drm/amdgpu: give ttm entities access to all the sdma scheds Pierre-Eric Pelloux-Prayer
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 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>
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 0e9620df91b7..5d10c08fd989 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 [flat|nested] 10+ messages in thread
* [PATCH v6 4/8] drm/amdgpu: give ttm entities access to all the sdma scheds
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 2/8] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 3/8] drm/amdgpu: create multiple clear/move ttm entities Pierre-Eric Pelloux-Prayer
@ 2026-04-08 10:03 ` Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 5/8] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 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, except default_entity which has no
use for multiple schedulers.
---
v6: add comment
---
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 | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 5d10c08fd989..7b92f240eea7 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,11 @@ 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];
+ /* default_entity doesn't need multiple schedulers so pass only 1. */
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 +2378,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 +2401,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 [flat|nested] 10+ messages in thread
* [PATCH v6 5/8] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
` (2 preceding siblings ...)
2026-04-08 10:03 ` [PATCH v6 4/8] drm/amdgpu: give ttm entities access to all the sdma scheds Pierre-Eric Pelloux-Prayer
@ 2026-04-08 10:03 ` Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 6/8] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 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
v6: dont pass a NULL resv when calling amdgpu_fill_buffer from
amdgpu_bo_create
---
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 | 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..bdeca80cd77d 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, bo->tbo.base.resv, &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 7b92f240eea7..7af11623263d 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) {
@@ -2573,76 +2573,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);
@@ -2660,6 +2609,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);
@@ -2681,9 +2635,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 [flat|nested] 10+ messages in thread
* [PATCH v6 6/8] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
` (3 preceding siblings ...)
2026-04-08 10:03 ` [PATCH v6 5/8] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
@ 2026-04-08 10:03 ` Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 7/8] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs Pierre-Eric Pelloux-Prayer
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 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 bdeca80cd77d..4dd7c712b8c3 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, bo->tbo.base.resv, &fence,
- true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
+ r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
+ bo, bo->tbo.base.resv, &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 7af11623263d..8d778cbce1aa 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) {
@@ -2573,26 +2573,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;
@@ -2623,7 +2620,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 [flat|nested] 10+ messages in thread
* [PATCH v6 7/8] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
` (4 preceding siblings ...)
2026-04-08 10:03 ` [PATCH v6 6/8] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
@ 2026-04-08 10:03 ` Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 8/8] drm/amdgpu: use DRM_SCHED_PRIORITY_KERNEL for all ttm entities Pierre-Eric Pelloux-Prayer
2026-04-08 14:09 ` [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Christian König
7 siblings, 0 replies; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 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>
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 | 188 +++++++++++----------
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 4 +-
3 files changed, 109 insertions(+), 97 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 8d778cbce1aa..000f66452b10 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,116 +2329,92 @@ 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;
+ }
+
+ /* default_entity doesn't need multiple schedulers so pass only 1. */
+ 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);
- /* default_entity doesn't need multiple schedulers so pass only 1. */
- 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;
@@ -2454,6 +2430,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 [flat|nested] 10+ messages in thread
* [PATCH v6 8/8] drm/amdgpu: use DRM_SCHED_PRIORITY_KERNEL for all ttm entities
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
` (5 preceding siblings ...)
2026-04-08 10:03 ` [PATCH v6 7/8] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs Pierre-Eric Pelloux-Prayer
@ 2026-04-08 10:03 ` Pierre-Eric Pelloux-Prayer
2026-04-08 14:11 ` Christian König
2026-04-08 14:09 ` [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Christian König
7 siblings, 1 reply; 10+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2026-04-08 10:03 UTC (permalink / raw)
To: Alex Deucher, Christian König, David Airlie, Simona Vetter
Cc: Pierre-Eric Pelloux-Prayer, amd-gfx, dri-devel, linux-kernel
ttm jobs must have higher priority than any userspace jobs.
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 000f66452b10..1f9423556ab3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -2378,7 +2378,7 @@ void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
r = amdgpu_ttm_buffer_entity_init(
&adev->mman.gtt_mgr,
&adev->mman.clear_entities[i],
- DRM_SCHED_PRIORITY_NORMAL,
+ DRM_SCHED_PRIORITY_KERNEL,
adev->mman.buffer_funcs_scheds,
adev->mman.num_buffer_funcs_scheds, 1);
@@ -2398,7 +2398,7 @@ void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
r = amdgpu_ttm_buffer_entity_init(
&adev->mman.gtt_mgr,
&adev->mman.move_entities[i],
- DRM_SCHED_PRIORITY_NORMAL,
+ DRM_SCHED_PRIORITY_KERNEL,
adev->mman.buffer_funcs_scheds,
adev->mman.num_buffer_funcs_scheds, 2);
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
` (6 preceding siblings ...)
2026-04-08 10:03 ` [PATCH v6 8/8] drm/amdgpu: use DRM_SCHED_PRIORITY_KERNEL for all ttm entities Pierre-Eric Pelloux-Prayer
@ 2026-04-08 14:09 ` Christian König
7 siblings, 0 replies; 10+ messages in thread
From: Christian König @ 2026-04-08 14:09 UTC (permalink / raw)
To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie,
Simona Vetter, Felix Kuehling
Cc: amd-gfx, dri-devel, linux-kernel
On 4/8/26 12:03, Pierre-Eric Pelloux-Prayer 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 | 36 ++++++++++++++++++----
> 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, 52 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..63ec3938cd41 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,31 @@ 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 drm_gpu_scheduler *sched;
> + struct amdgpu_vmhub *hub;
> + 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;
> + }
> +
> + /* Navi1x's workaround requires us to limit to a single SDMA sched
> + * for ttm.
> + */
> + hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
> + 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);
> }
I think all those single line SDMA functions can now be dropped as well.
But that's not a must have for this patch here, so Reviewed-by: Christian König <christian.koenig@amd.com>.
Regards,
Christian.
>
> 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);
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6 8/8] drm/amdgpu: use DRM_SCHED_PRIORITY_KERNEL for all ttm entities
2026-04-08 10:03 ` [PATCH v6 8/8] drm/amdgpu: use DRM_SCHED_PRIORITY_KERNEL for all ttm entities Pierre-Eric Pelloux-Prayer
@ 2026-04-08 14:11 ` Christian König
0 siblings, 0 replies; 10+ messages in thread
From: Christian König @ 2026-04-08 14:11 UTC (permalink / raw)
To: Pierre-Eric Pelloux-Prayer, Alex Deucher, David Airlie, Simona Vetter
Cc: amd-gfx, dri-devel, linux-kernel
On 4/8/26 12:03, Pierre-Eric Pelloux-Prayer wrote:
> ttm jobs must have higher priority than any userspace jobs.
>
> 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 000f66452b10..1f9423556ab3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -2378,7 +2378,7 @@ void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
> r = amdgpu_ttm_buffer_entity_init(
> &adev->mman.gtt_mgr,
> &adev->mman.clear_entities[i],
> - DRM_SCHED_PRIORITY_NORMAL,
> + DRM_SCHED_PRIORITY_KERNEL,
> adev->mman.buffer_funcs_scheds,
> adev->mman.num_buffer_funcs_scheds, 1);
>
> @@ -2398,7 +2398,7 @@ void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
> r = amdgpu_ttm_buffer_entity_init(
> &adev->mman.gtt_mgr,
> &adev->mman.move_entities[i],
> - DRM_SCHED_PRIORITY_NORMAL,
> + DRM_SCHED_PRIORITY_KERNEL,
> adev->mman.buffer_funcs_scheds,
> adev->mman.num_buffer_funcs_scheds, 2);
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-04-08 14:11 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-08 10:03 [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 2/8] drm/amdgpu: only use working sdma schedulers for ttm Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 3/8] drm/amdgpu: create multiple clear/move ttm entities Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 4/8] drm/amdgpu: give ttm entities access to all the sdma scheds Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 5/8] drm/amdgpu: get rid of amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 6/8] drm/amdgpu: rename amdgpu_fill_buffer as amdgpu_ttm_clear_buffer Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 7/8] drm/amdgpu: split amdgpu_ttm_set_buffer_funcs_status in 2 funcs Pierre-Eric Pelloux-Prayer
2026-04-08 10:03 ` [PATCH v6 8/8] drm/amdgpu: use DRM_SCHED_PRIORITY_KERNEL for all ttm entities Pierre-Eric Pelloux-Prayer
2026-04-08 14:11 ` Christian König
2026-04-08 14:09 ` [PATCH v6 1/8] drm/amdgpu: pass all the sdma scheds to amdgpu_mman Christian König
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®