summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeonardo Cesar <leonardocesar@usp.br>2026-04-29 02:19:44 +0300
committerAlex Deucher <alexander.deucher@amd.com>2026-05-05 16:56:29 +0300
commitdc0d6fdfa5b6ab36ddaa774265261336c3e7dbae (patch)
tree97128fe97a8bfa1596f76c407b7297a577478ef5
parentc1a3ff1d327820cd9a52bc1056b98681fc088949 (diff)
downloadlinux-dc0d6fdfa5b6ab36ddaa774265261336c3e7dbae.tar.xz
drm/amdgpu: deduplicate ring preempt ib function
The ring preemption function is identical for both gfx_v11_0 and gfx_v12_0. This patch refactors the code by moving the core logic into a generic function inside amdgpu_gfx.c to reduce code duplication and simplify future maintenance. Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Leonardo Cesar <leonardocesar@usp.br> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c51
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c52
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c52
4 files changed, 55 insertions, 102 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index b8ca876694ff..515cc4a2aeb4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -2686,3 +2686,54 @@ void amdgpu_debugfs_compute_sched_mask_init(struct amdgpu_device *adev)
#endif
}
+int amdgpu_gfx_ring_preempt_ib(struct amdgpu_ring *ring)
+{
+ struct amdgpu_device *adev = ring->adev;
+ struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
+ struct amdgpu_ring *kiq_ring = &kiq->ring;
+ unsigned long flags;
+ int i;
+
+ if (adev->enable_mes)
+ return -EINVAL;
+
+ if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
+ return -EINVAL;
+
+ spin_lock_irqsave(&kiq->ring_lock, flags);
+
+ if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) {
+ spin_unlock_irqrestore(&kiq->ring_lock, flags);
+ return -ENOMEM;
+ }
+
+ /* assert preemption condition */
+ amdgpu_ring_set_preempt_cond_exec(ring, false);
+
+ /* assert IB preemption, emit the trailing fence */
+ kiq->pmf->kiq_unmap_queues(kiq_ring, ring, PREEMPT_QUEUES_NO_UNMAP,
+ ring->trail_fence_gpu_addr,
+ ++ring->trail_seq);
+ amdgpu_ring_commit(kiq_ring);
+
+ spin_unlock_irqrestore(&kiq->ring_lock, flags);
+
+ /* poll the trailing fence */
+ for (i = 0; i < adev->usec_timeout; i++) {
+ if (ring->trail_seq ==
+ le32_to_cpu(*(ring->trail_fence_cpu_addr)))
+ break;
+ udelay(1);
+ }
+
+ /* deassert preemption condition */
+ amdgpu_ring_set_preempt_cond_exec(ring, true);
+
+ if (i >= adev->usec_timeout) {
+ DRM_ERROR("ring %d failed to preempt ib\n", ring->idx);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
index a0cf0a3b41da..77050f9884f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
@@ -664,6 +664,8 @@ void amdgpu_gfx_csb_preamble_end(u32 *buffer, u32 count);
void amdgpu_debugfs_gfx_sched_mask_init(struct amdgpu_device *adev);
void amdgpu_debugfs_compute_sched_mask_init(struct amdgpu_device *adev);
+int amdgpu_gfx_ring_preempt_ib(struct amdgpu_ring *ring);
+
static inline const char *amdgpu_gfx_compute_mode_desc(int mode)
{
switch (mode) {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 2c6f1e25ca14..fabdbbd0abb7 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -6232,56 +6232,6 @@ static void gfx_v11_0_ring_emit_gfx_shadow(struct amdgpu_ring *ring,
ring->set_q_mode_offs = offs;
}
-static int gfx_v11_0_ring_preempt_ib(struct amdgpu_ring *ring)
-{
- int i, r = 0;
- struct amdgpu_device *adev = ring->adev;
- struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
- struct amdgpu_ring *kiq_ring = &kiq->ring;
- unsigned long flags;
-
- if (adev->enable_mes)
- return -EINVAL;
-
- if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
- return -EINVAL;
-
- spin_lock_irqsave(&kiq->ring_lock, flags);
-
- if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) {
- spin_unlock_irqrestore(&kiq->ring_lock, flags);
- return -ENOMEM;
- }
-
- /* assert preemption condition */
- amdgpu_ring_set_preempt_cond_exec(ring, false);
-
- /* assert IB preemption, emit the trailing fence */
- kiq->pmf->kiq_unmap_queues(kiq_ring, ring, PREEMPT_QUEUES_NO_UNMAP,
- ring->trail_fence_gpu_addr,
- ++ring->trail_seq);
- amdgpu_ring_commit(kiq_ring);
-
- spin_unlock_irqrestore(&kiq->ring_lock, flags);
-
- /* poll the trailing fence */
- for (i = 0; i < adev->usec_timeout; i++) {
- if (ring->trail_seq ==
- le32_to_cpu(*(ring->trail_fence_cpu_addr)))
- break;
- udelay(1);
- }
-
- if (i >= adev->usec_timeout) {
- r = -EINVAL;
- DRM_ERROR("ring %d failed to preempt ib\n", ring->idx);
- }
-
- /* deassert preemption condition */
- amdgpu_ring_set_preempt_cond_exec(ring, true);
- return r;
-}
-
static void gfx_v11_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume)
{
struct amdgpu_device *adev = ring->adev;
@@ -7313,7 +7263,7 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
.emit_cntxcntl = gfx_v11_0_ring_emit_cntxcntl,
.emit_gfx_shadow = gfx_v11_0_ring_emit_gfx_shadow,
.init_cond_exec = gfx_v11_0_ring_emit_init_cond_exec,
- .preempt_ib = gfx_v11_0_ring_preempt_ib,
+ .preempt_ib = amdgpu_gfx_ring_preempt_ib,
.emit_frame_cntl = gfx_v11_0_ring_emit_frame_cntl,
.emit_wreg = gfx_v11_0_ring_emit_wreg,
.emit_reg_wait = gfx_v11_0_ring_emit_reg_wait,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index 6baac533a2e6..b866a944f878 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -4616,56 +4616,6 @@ static unsigned gfx_v12_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring,
return ret;
}
-static int gfx_v12_0_ring_preempt_ib(struct amdgpu_ring *ring)
-{
- int i, r = 0;
- struct amdgpu_device *adev = ring->adev;
- struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
- struct amdgpu_ring *kiq_ring = &kiq->ring;
- unsigned long flags;
-
- if (adev->enable_mes)
- return -EINVAL;
-
- if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
- return -EINVAL;
-
- spin_lock_irqsave(&kiq->ring_lock, flags);
-
- if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) {
- spin_unlock_irqrestore(&kiq->ring_lock, flags);
- return -ENOMEM;
- }
-
- /* assert preemption condition */
- amdgpu_ring_set_preempt_cond_exec(ring, false);
-
- /* assert IB preemption, emit the trailing fence */
- kiq->pmf->kiq_unmap_queues(kiq_ring, ring, PREEMPT_QUEUES_NO_UNMAP,
- ring->trail_fence_gpu_addr,
- ++ring->trail_seq);
- amdgpu_ring_commit(kiq_ring);
-
- spin_unlock_irqrestore(&kiq->ring_lock, flags);
-
- /* poll the trailing fence */
- for (i = 0; i < adev->usec_timeout; i++) {
- if (ring->trail_seq ==
- le32_to_cpu(*(ring->trail_fence_cpu_addr)))
- break;
- udelay(1);
- }
-
- if (i >= adev->usec_timeout) {
- r = -EINVAL;
- DRM_ERROR("ring %d failed to preempt ib\n", ring->idx);
- }
-
- /* deassert preemption condition */
- amdgpu_ring_set_preempt_cond_exec(ring, true);
- return r;
-}
-
static void gfx_v12_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg,
uint32_t reg_val_offs)
{
@@ -5536,7 +5486,7 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_gfx = {
.pad_ib = amdgpu_ring_generic_pad_ib,
.emit_cntxcntl = gfx_v12_0_ring_emit_cntxcntl,
.init_cond_exec = gfx_v12_0_ring_emit_init_cond_exec,
- .preempt_ib = gfx_v12_0_ring_preempt_ib,
+ .preempt_ib = amdgpu_gfx_ring_preempt_ib,
.emit_wreg = gfx_v12_0_ring_emit_wreg,
.emit_reg_wait = gfx_v12_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v12_0_ring_emit_reg_write_reg_wait,