Skip to content

Commit 87af86a

Browse files
jiadozhualexdeucher
authored andcommitted
drm/amdgpu: Modify indirect buffer packages for resubmission
When the preempted IB frame resubmitted to cp, we need to modify the frame data including: 1. set PRE_RESUME 1 in CONTEXT_CONTROL. 2. use meta data(DE and CE) read from CSA in WRITE_DATA. Add functions to save the location the first time IBs emitted and callback to patch the package when resubmission happens. Signed-off-by: Jiadong Zhu <[email protected]> Acked-by: Alex Deucher <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Cc: [email protected] # 6.3.x
1 parent 94034b3 commit 87af86a

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,3 +581,21 @@ void amdgpu_ring_ib_end(struct amdgpu_ring *ring)
581581
if (ring->is_sw_ring)
582582
amdgpu_sw_ring_ib_end(ring);
583583
}
584+
585+
void amdgpu_ring_ib_on_emit_cntl(struct amdgpu_ring *ring)
586+
{
587+
if (ring->is_sw_ring)
588+
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_CONTROL);
589+
}
590+
591+
void amdgpu_ring_ib_on_emit_ce(struct amdgpu_ring *ring)
592+
{
593+
if (ring->is_sw_ring)
594+
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_CE);
595+
}
596+
597+
void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring)
598+
{
599+
if (ring->is_sw_ring)
600+
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_DE);
601+
}

drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ struct amdgpu_ring_funcs {
227227
int (*preempt_ib)(struct amdgpu_ring *ring);
228228
void (*emit_mem_sync)(struct amdgpu_ring *ring);
229229
void (*emit_wave_limit)(struct amdgpu_ring *ring, bool enable);
230+
void (*patch_cntl)(struct amdgpu_ring *ring, unsigned offset);
231+
void (*patch_ce)(struct amdgpu_ring *ring, unsigned offset);
232+
void (*patch_de)(struct amdgpu_ring *ring, unsigned offset);
230233
};
231234

232235
struct amdgpu_ring {
@@ -318,10 +321,16 @@ struct amdgpu_ring {
318321
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
319322
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
320323
#define amdgpu_ring_preempt_ib(r) (r)->funcs->preempt_ib(r)
324+
#define amdgpu_ring_patch_cntl(r, o) ((r)->funcs->patch_cntl((r), (o)))
325+
#define amdgpu_ring_patch_ce(r, o) ((r)->funcs->patch_ce((r), (o)))
326+
#define amdgpu_ring_patch_de(r, o) ((r)->funcs->patch_de((r), (o)))
321327

322328
int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
323329
void amdgpu_ring_ib_begin(struct amdgpu_ring *ring);
324330
void amdgpu_ring_ib_end(struct amdgpu_ring *ring);
331+
void amdgpu_ring_ib_on_emit_cntl(struct amdgpu_ring *ring);
332+
void amdgpu_ring_ib_on_emit_ce(struct amdgpu_ring *ring);
333+
void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring);
325334

326335
void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
327336
void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);

drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ static void amdgpu_mux_resubmit_chunks(struct amdgpu_ring_mux *mux)
105105
amdgpu_fence_update_start_timestamp(e->ring,
106106
chunk->sync_seq,
107107
ktime_get());
108+
if (chunk->sync_seq ==
109+
le32_to_cpu(*(e->ring->fence_drv.cpu_addr + 2))) {
110+
if (chunk->cntl_offset <= e->ring->buf_mask)
111+
amdgpu_ring_patch_cntl(e->ring,
112+
chunk->cntl_offset);
113+
if (chunk->ce_offset <= e->ring->buf_mask)
114+
amdgpu_ring_patch_ce(e->ring, chunk->ce_offset);
115+
if (chunk->de_offset <= e->ring->buf_mask)
116+
amdgpu_ring_patch_de(e->ring, chunk->de_offset);
117+
}
108118
amdgpu_ring_mux_copy_pkt_from_sw_ring(mux, e->ring,
109119
chunk->start,
110120
chunk->end);
@@ -407,6 +417,17 @@ void amdgpu_sw_ring_ib_end(struct amdgpu_ring *ring)
407417
amdgpu_ring_mux_end_ib(mux, ring);
408418
}
409419

420+
void amdgpu_sw_ring_ib_mark_offset(struct amdgpu_ring *ring, enum amdgpu_ring_mux_offset_type type)
421+
{
422+
struct amdgpu_device *adev = ring->adev;
423+
struct amdgpu_ring_mux *mux = &adev->gfx.muxer;
424+
unsigned offset;
425+
426+
offset = ring->wptr & ring->buf_mask;
427+
428+
amdgpu_ring_mux_ib_mark_offset(mux, ring, offset, type);
429+
}
430+
410431
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
411432
{
412433
struct amdgpu_mux_entry *e;
@@ -429,6 +450,10 @@ void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *r
429450
}
430451

431452
chunk->start = ring->wptr;
453+
/* the initialized value used to check if they are set by the ib submission*/
454+
chunk->cntl_offset = ring->buf_mask + 1;
455+
chunk->de_offset = ring->buf_mask + 1;
456+
chunk->ce_offset = ring->buf_mask + 1;
432457
list_add_tail(&chunk->entry, &e->list);
433458
}
434459

@@ -454,6 +479,41 @@ static void scan_and_remove_signaled_chunk(struct amdgpu_ring_mux *mux, struct a
454479
}
455480
}
456481

482+
void amdgpu_ring_mux_ib_mark_offset(struct amdgpu_ring_mux *mux,
483+
struct amdgpu_ring *ring, u64 offset,
484+
enum amdgpu_ring_mux_offset_type type)
485+
{
486+
struct amdgpu_mux_entry *e;
487+
struct amdgpu_mux_chunk *chunk;
488+
489+
e = amdgpu_ring_mux_sw_entry(mux, ring);
490+
if (!e) {
491+
DRM_ERROR("cannot find entry!\n");
492+
return;
493+
}
494+
495+
chunk = list_last_entry(&e->list, struct amdgpu_mux_chunk, entry);
496+
if (!chunk) {
497+
DRM_ERROR("cannot find chunk!\n");
498+
return;
499+
}
500+
501+
switch (type) {
502+
case AMDGPU_MUX_OFFSET_TYPE_CONTROL:
503+
chunk->cntl_offset = offset;
504+
break;
505+
case AMDGPU_MUX_OFFSET_TYPE_DE:
506+
chunk->de_offset = offset;
507+
break;
508+
case AMDGPU_MUX_OFFSET_TYPE_CE:
509+
chunk->ce_offset = offset;
510+
break;
511+
default:
512+
DRM_ERROR("invalid type (%d)\n", type);
513+
break;
514+
}
515+
}
516+
457517
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
458518
{
459519
struct amdgpu_mux_entry *e;

drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ struct amdgpu_mux_entry {
5050
struct list_head list;
5151
};
5252

53+
enum amdgpu_ring_mux_offset_type {
54+
AMDGPU_MUX_OFFSET_TYPE_CONTROL,
55+
AMDGPU_MUX_OFFSET_TYPE_DE,
56+
AMDGPU_MUX_OFFSET_TYPE_CE,
57+
};
58+
5359
struct amdgpu_ring_mux {
5460
struct amdgpu_ring *real_ring;
5561

@@ -72,12 +78,18 @@ struct amdgpu_ring_mux {
7278
* @sync_seq: the fence seqno related with the saved IB.
7379
* @start:- start location on the software ring.
7480
* @end:- end location on the software ring.
81+
* @control_offset:- the PRE_RESUME bit position used for resubmission.
82+
* @de_offset:- the anchor in write_data for de meta of resubmission.
83+
* @ce_offset:- the anchor in write_data for ce meta of resubmission.
7584
*/
7685
struct amdgpu_mux_chunk {
7786
struct list_head entry;
7887
uint32_t sync_seq;
7988
u64 start;
8089
u64 end;
90+
u64 cntl_offset;
91+
u64 de_offset;
92+
u64 ce_offset;
8193
};
8294

8395
int amdgpu_ring_mux_init(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
@@ -89,6 +101,8 @@ u64 amdgpu_ring_mux_get_wptr(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ri
89101
u64 amdgpu_ring_mux_get_rptr(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
90102
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
91103
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
104+
void amdgpu_ring_mux_ib_mark_offset(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
105+
u64 offset, enum amdgpu_ring_mux_offset_type type);
92106
bool amdgpu_mcbp_handle_trailing_fence_irq(struct amdgpu_ring_mux *mux);
93107

94108
u64 amdgpu_sw_ring_get_rptr_gfx(struct amdgpu_ring *ring);
@@ -97,6 +111,7 @@ void amdgpu_sw_ring_set_wptr_gfx(struct amdgpu_ring *ring);
97111
void amdgpu_sw_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
98112
void amdgpu_sw_ring_ib_begin(struct amdgpu_ring *ring);
99113
void amdgpu_sw_ring_ib_end(struct amdgpu_ring *ring);
114+
void amdgpu_sw_ring_ib_mark_offset(struct amdgpu_ring *ring, enum amdgpu_ring_mux_offset_type type);
100115
const char *amdgpu_sw_ring_name(int idx);
101116
unsigned int amdgpu_sw_ring_priority(int idx);
102117

0 commit comments

Comments
 (0)