All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Timur Kristóf" <timur.kristof@gmail.com>
To: amd-gfx@lists.freedesktop.org,
	Alex Deucher <alexander.deucher@amd.com>,
	christian.koenig@amd.com, pierre-eric.pelloux-prayer@amd.com,
	Natalie Vock <natalie.vock@gmx.de>,
	Tvrtko Ursulin <tursulin@ursulin.net>
Subject: Re: [PATCH 5/9] drm/amdgpu/gfx7: Fixup emitting SWITCH_BUFFER packets
Date: Wed, 15 Jul 2026 12:36:45 +0200	[thread overview]
Message-ID: <7296917.jJDZkT8p0M@timur-max> (raw)
In-Reply-To: <fb4f5735-2ccb-4a75-8d69-d776b3f3bb84@ursulin.net>

On 2026. július 15., szerda 10:56:38 közép-európai nyári idő Tvrtko Ursulin 
wrote:
> On 13/07/2026 13:58, Timur Kristóf wrote:
> > Implement the emit_switch_buffer() function instead of emitting
> > them duing emit_ib, emit_pipeline_sync and emit_vm_flush.
> 
> during
> 
> > Note that it isn't necessary to emit these in both
> > emit_pipeline_sync() and emit_vm_flush() because
> > amdgpu_vm_flush() already calls these when calling
> > either of those functions.
> 
> The amdgpu_vm_flush indeed does emit two switch buffers:
> 
> 	/* the double SWITCH_BUFFER here *cannot* be skipped by COND_EXEC 
*/
> 	if (ring->funcs->emit_switch_buffer) {
> 		amdgpu_ring_emit_switch_buffer(ring);
> 		amdgpu_ring_emit_switch_buffer(ring);
> 	}
> 
> Comments are different though:
> 
> /* sync CE with ME to prevent CE fetch CEIB before context switch done */
> 
> Are you confident the two emissions are about the same thing?

Yes, I'm confident. One of the comments explains why the SWITCH_BUFFER packet 
is emitted, the other one explains why it is emitted outside COND_EXEC.

This packet is interpreted by the CE (constant engine). The reason why this 
packet is emitted is basically to make sure the CE can't start executing 
packets from the next submission until the current one is finished.

(Note that CE is not utilized by any maintained userspace driver and is 
discontinued in new GPUs. As far as I remember there were experiments to try 
to use the CE in Mesa but it didn't yield any noteworthy perf improvement so 
we just never used it. The old proprietary driver may have used it. It is now 
also deprecated in the kernel.)


> 
> > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > ---
> > 
> >   drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 32 +++++++++------------------
> >   1 file changed, 10 insertions(+), 22 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> > b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 0ceadb107d26..a93cc02c3400
> > 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> > @@ -2201,12 +2201,6 @@ static void gfx_v7_0_ring_emit_ib_gfx(struct
> > amdgpu_ring *ring,> 
> >   	unsigned vmid = AMDGPU_JOB_GET_VMID(job);
> >   	u32 header, control = 0;
> > 
> > -	/* insert SWITCH_BUFFER packet before first IB in the ring frame */
> > -	if (flags & AMDGPU_HAVE_CTX_SWITCH) {
> > -		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 
0));
> > -		amdgpu_ring_write(ring, 0);
> > -	}
> 
> Commit message does not explain why the change of ring buffer command
> this creates is okay. Current flow is:
> 
> amdgpu_ib_schedule()
> {
> ...
>    amdgpu_ring_emit_ib
>      amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
> 
> 
> New flow is:
> 
> ...
>    amdgpu_ring_emit_ib
> ... other ring commands ...
>    amdgpu_ring_emit_switch_buffer
>      amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));

No, that's not what the new flow is. If you check the callers of 
emit_switch_buffer() you can see that it's called from two places:

- amdgpu_vm_flush() emits it before the first IB when necessary
- amdgpu_ib_schedule() emits it after the last IB when necessary

> Is this okay? Specifically due the above comment saying "insert
> SWITCH_BUFFER packet before first IB in the ring frame" - is the "first"
> part not important?

amdgpu_vm_flush() emits it before the first IB.

> Also, amdgpu_ib_schedule only emits amdgpu_ring_emit_switch_buffer if
> there is a job. Currently it is always emitted.

I trust that the GFX8+ implementations are more precise and that it's sufficient 
to emit this packet in the cases where the emit_switch_buffer() function is 
called.

When there is "no job" that's a special case that is only used during 
initialization (specifically the IB ring tests). In that case we are not 
executing commands submitted by userspace but rather commands generated by the 
kernel. So we can be sure the CE is not used in those cases.

> 
> Final interesting part is how amdgpu_ib_schedule clears
> AMDGPU_HAVE_CTX_SWITCH after having called amdgpu_ring_emit_ib.
> 
> After this change only gfx6 remains the user of that flag in
> gfx_v6_0_ring_emit_ib. Everyone else only use it in emit_cntxcntl. If
> gfx6 was adjusted too (later), amdgpu_ib_schedule could reduce the scope
> of that flag to just the scope where it calls amdgpu_ring_emit_frame_cntl.

I also adjusted the same thing for GFX6 in the next series.
Can clean up the flag later once both series are accepted.


> 
> > -
> > 
> >   	if (ib->flags & AMDGPU_IB_FLAG_CE)
> >   	
> >   		header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
> >   	
> >   	else
> > 
> > @@ -2258,6 +2252,12 @@ static void gfx_v7_0_ring_emit_ib_compute(struct
> > amdgpu_ring *ring,> 
> >   	amdgpu_ring_write(ring, control);
> >   
> >   }
> > 
> > +static void gfx_v7_0_ring_emit_sb(struct amdgpu_ring *ring)
> > +{
> > +	amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
> > +	amdgpu_ring_write(ring, 0);
> > +}
> > +
> > 
> >   static void gfx_v7_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t
> >   flags) {
> >   
> >   	uint32_t dw2 = 0;
> > 
> > @@ -3111,14 +3111,6 @@ static void gfx_v7_0_ring_emit_pipeline_sync(struct
> > amdgpu_ring *ring)> 
> >   	amdgpu_ring_write(ring, seq);
> >   	amdgpu_ring_write(ring, 0xffffffff);
> >   	amdgpu_ring_write(ring, 4); /* poll interval */
> > 
> > -
> > -	if (usepfp) {
> > -		/* sync CE with ME to prevent CE fetch CEIB before 
context switch done
> > */ -		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 
0));
> > -		amdgpu_ring_write(ring, 0);
> > -		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 
0));
> > -		amdgpu_ring_write(ring, 0);
> > -	}
> > 
> >   }
> >   
> >   /*
> > 
> > @@ -3160,12 +3152,6 @@ static void gfx_v7_0_ring_emit_vm_flush(struct
> > amdgpu_ring *ring,> 
> >   		/* sync PFP to ME, otherwise we might get invalid PFP 
reads */
> >   		amdgpu_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 
0));
> >   		amdgpu_ring_write(ring, 0x0);
> > 
> > -
> > -		/* synce CE with ME to prevent CE fetch CEIB before 
context switch done
> > */ -		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 
0));
> > -		amdgpu_ring_write(ring, 0);
> > -		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 
0));
> > -		amdgpu_ring_write(ring, 0);
> > 
> >   	}
> >   
> >   }
> > 
> > @@ -4954,8 +4940,9 @@ static const struct amdgpu_ring_funcs
> > gfx_v7_0_ring_funcs_gfx = {> 
> >   		7 + /* gfx_v7_0_ring_emit_hdp_flush */
> >   		5 + /* hdp invalidate */
> >   		12 + 12 + 12 + /* gfx_v7_0_ring_emit_fence_gfx x3 for 
user fence, vm
> >   		fence */> 
> > -		7 + 4 + /* gfx_v7_0_ring_emit_pipeline_sync */
> > -		CIK_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + 6 + /* 
gfx_v7_0_ring_emit_vm_flush
> > */ +		7 + /* gfx_v7_0_ring_emit_pipeline_sync */
> > +		CIK_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + 2 + /* 
gfx_v7_0_ring_emit_vm_flush
> > */ +		3 * 2 + /* gfx_v7_0_ring_emit_sb x3 (from 
amdgpu_vm_flush,
> > amdgpu_ib_schedule) */> 
> >   		3 + 4 + /* gfx_v7_ring_emit_cntxcntl including vgt 
flush*/
> >   		5, /* SURFACE_SYNC */
> >   	
> >   	.emit_ib_size = 4, /* gfx_v7_0_ring_emit_ib_gfx */
> > 
> > @@ -4969,6 +4956,7 @@ static const struct amdgpu_ring_funcs
> > gfx_v7_0_ring_funcs_gfx = {> 
> >   	.test_ib = gfx_v7_0_ring_test_ib,
> >   	.insert_nop = amdgpu_ring_insert_nop,
> >   	.pad_ib = amdgpu_ring_generic_pad_ib,
> > 
> > +	.emit_switch_buffer = gfx_v7_0_ring_emit_sb,
> > 
> >   	.emit_cntxcntl = gfx_v7_ring_emit_cntxcntl,
> >   	.emit_wreg = gfx_v7_0_ring_emit_wreg,
> >   	.soft_recovery = gfx_v7_0_ring_soft_recovery,





  reply	other threads:[~2026-07-15 10:36 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-13 12:58 [PATCH 0/9] drm/amdgpu/gfx7: Use GFX IP block soft reset on GFX7 Timur Kristóf
2026-07-13 12:58 ` [PATCH 1/9] drm/amdgpu/gfx7: Make amdgpu_gfx_mqd_sw_init() usable " Timur Kristóf
2026-07-14 14:59   ` Tvrtko Ursulin
2026-07-14 15:05     ` Alex Deucher
2026-07-14 15:19       ` Tvrtko Ursulin
2026-07-14 15:39         ` Timur Kristóf
2026-07-14 18:23           ` Tvrtko Ursulin
2026-07-13 12:58 ` [PATCH 2/9] drm/amdgpu/gfx7: Refactor MQD initialization and finalization Timur Kristóf
2026-07-14 18:47   ` Tvrtko Ursulin
2026-07-15  8:08     ` Timur Kristóf
2026-07-15  8:26       ` Tvrtko Ursulin
2026-07-13 12:58 ` [PATCH 3/9] drm/amdgpu/gfx7: Return error code when compute ring tests fail Timur Kristóf
2026-07-14 18:55   ` Tvrtko Ursulin
2026-07-14 20:41     ` Alex Deucher
2026-07-15  8:02       ` Timur Kristóf
2026-07-15  9:50         ` Christian König
2026-07-15 10:50           ` Timur Kristóf
2026-07-13 12:58 ` [PATCH 4/9] drm/amdgpu/gfx7: Return error code when failing to start GFX ring Timur Kristóf
2026-07-14 18:58   ` Tvrtko Ursulin
2026-07-13 12:58 ` [PATCH 5/9] drm/amdgpu/gfx7: Fixup emitting SWITCH_BUFFER packets Timur Kristóf
2026-07-15  8:56   ` Tvrtko Ursulin
2026-07-15 10:36     ` Timur Kristóf [this message]
2026-07-15 11:20       ` Tvrtko Ursulin
2026-07-15 11:50       ` Christian König
2026-07-13 12:58 ` [PATCH 6/9] drm/amdgpu/gfx7: Clean up gfx ring during reset Timur Kristóf
2026-07-15  9:18   ` Tvrtko Ursulin
2026-07-15 10:16     ` Timur Kristóf
2026-07-15 11:07       ` Tvrtko Ursulin
2026-07-13 12:58 ` [PATCH 7/9] drm/amdgpu/gfx7: Use COND_EXEC Timur Kristóf
2026-07-15  9:38   ` Tvrtko Ursulin
2026-07-15 10:45     ` Timur Kristóf
2026-07-13 12:58 ` [PATCH 8/9] drm/amdgpu/gfx7: Fixup IP block soft reset Timur Kristóf
2026-07-15  9:53   ` Tvrtko Ursulin
2026-07-13 12:58 ` [PATCH 9/9] drm/amdgpu/gfx7: Enable IP block soft reset as a GPU recovery method Timur Kristóf
2026-07-15  9:55   ` Tvrtko Ursulin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7296917.jJDZkT8p0M@timur-max \
    --to=timur.kristof@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=christian.koenig@amd.com \
    --cc=natalie.vock@gmx.de \
    --cc=pierre-eric.pelloux-prayer@amd.com \
    --cc=tursulin@ursulin.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.