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 <Jiadong.Zhu@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
f2bcc0c7db
commit
8ff865be93
@ -670,3 +670,21 @@ void amdgpu_ring_ib_end(struct amdgpu_ring *ring)
|
|||||||
if (ring->is_sw_ring)
|
if (ring->is_sw_ring)
|
||||||
amdgpu_sw_ring_ib_end(ring);
|
amdgpu_sw_ring_ib_end(ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amdgpu_ring_ib_on_emit_cntl(struct amdgpu_ring *ring)
|
||||||
|
{
|
||||||
|
if (ring->is_sw_ring)
|
||||||
|
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void amdgpu_ring_ib_on_emit_ce(struct amdgpu_ring *ring)
|
||||||
|
{
|
||||||
|
if (ring->is_sw_ring)
|
||||||
|
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_CE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring)
|
||||||
|
{
|
||||||
|
if (ring->is_sw_ring)
|
||||||
|
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_DE);
|
||||||
|
}
|
||||||
|
@ -229,6 +229,9 @@ struct amdgpu_ring_funcs {
|
|||||||
int (*preempt_ib)(struct amdgpu_ring *ring);
|
int (*preempt_ib)(struct amdgpu_ring *ring);
|
||||||
void (*emit_mem_sync)(struct amdgpu_ring *ring);
|
void (*emit_mem_sync)(struct amdgpu_ring *ring);
|
||||||
void (*emit_wave_limit)(struct amdgpu_ring *ring, bool enable);
|
void (*emit_wave_limit)(struct amdgpu_ring *ring, bool enable);
|
||||||
|
void (*patch_cntl)(struct amdgpu_ring *ring, unsigned offset);
|
||||||
|
void (*patch_ce)(struct amdgpu_ring *ring, unsigned offset);
|
||||||
|
void (*patch_de)(struct amdgpu_ring *ring, unsigned offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amdgpu_ring {
|
struct amdgpu_ring {
|
||||||
@ -323,11 +326,17 @@ struct amdgpu_ring {
|
|||||||
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
|
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
|
||||||
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
|
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
|
||||||
#define amdgpu_ring_preempt_ib(r) (r)->funcs->preempt_ib(r)
|
#define amdgpu_ring_preempt_ib(r) (r)->funcs->preempt_ib(r)
|
||||||
|
#define amdgpu_ring_patch_cntl(r, o) ((r)->funcs->patch_cntl((r), (o)))
|
||||||
|
#define amdgpu_ring_patch_ce(r, o) ((r)->funcs->patch_ce((r), (o)))
|
||||||
|
#define amdgpu_ring_patch_de(r, o) ((r)->funcs->patch_de((r), (o)))
|
||||||
|
|
||||||
unsigned int amdgpu_ring_max_ibs(enum amdgpu_ring_type type);
|
unsigned int amdgpu_ring_max_ibs(enum amdgpu_ring_type type);
|
||||||
int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
|
int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
|
||||||
void amdgpu_ring_ib_begin(struct amdgpu_ring *ring);
|
void amdgpu_ring_ib_begin(struct amdgpu_ring *ring);
|
||||||
void amdgpu_ring_ib_end(struct amdgpu_ring *ring);
|
void amdgpu_ring_ib_end(struct amdgpu_ring *ring);
|
||||||
|
void amdgpu_ring_ib_on_emit_cntl(struct amdgpu_ring *ring);
|
||||||
|
void amdgpu_ring_ib_on_emit_ce(struct amdgpu_ring *ring);
|
||||||
|
void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring);
|
||||||
|
|
||||||
void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
|
void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
|
||||||
void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
|
void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
|
||||||
|
@ -105,6 +105,16 @@ static void amdgpu_mux_resubmit_chunks(struct amdgpu_ring_mux *mux)
|
|||||||
amdgpu_fence_update_start_timestamp(e->ring,
|
amdgpu_fence_update_start_timestamp(e->ring,
|
||||||
chunk->sync_seq,
|
chunk->sync_seq,
|
||||||
ktime_get());
|
ktime_get());
|
||||||
|
if (chunk->sync_seq ==
|
||||||
|
le32_to_cpu(*(e->ring->fence_drv.cpu_addr + 2))) {
|
||||||
|
if (chunk->cntl_offset <= e->ring->buf_mask)
|
||||||
|
amdgpu_ring_patch_cntl(e->ring,
|
||||||
|
chunk->cntl_offset);
|
||||||
|
if (chunk->ce_offset <= e->ring->buf_mask)
|
||||||
|
amdgpu_ring_patch_ce(e->ring, chunk->ce_offset);
|
||||||
|
if (chunk->de_offset <= e->ring->buf_mask)
|
||||||
|
amdgpu_ring_patch_de(e->ring, chunk->de_offset);
|
||||||
|
}
|
||||||
amdgpu_ring_mux_copy_pkt_from_sw_ring(mux, e->ring,
|
amdgpu_ring_mux_copy_pkt_from_sw_ring(mux, e->ring,
|
||||||
chunk->start,
|
chunk->start,
|
||||||
chunk->end);
|
chunk->end);
|
||||||
@ -407,6 +417,17 @@ void amdgpu_sw_ring_ib_end(struct amdgpu_ring *ring)
|
|||||||
amdgpu_ring_mux_end_ib(mux, ring);
|
amdgpu_ring_mux_end_ib(mux, ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amdgpu_sw_ring_ib_mark_offset(struct amdgpu_ring *ring, enum amdgpu_ring_mux_offset_type type)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = ring->adev;
|
||||||
|
struct amdgpu_ring_mux *mux = &adev->gfx.muxer;
|
||||||
|
unsigned offset;
|
||||||
|
|
||||||
|
offset = ring->wptr & ring->buf_mask;
|
||||||
|
|
||||||
|
amdgpu_ring_mux_ib_mark_offset(mux, ring, offset, type);
|
||||||
|
}
|
||||||
|
|
||||||
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
|
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
|
||||||
{
|
{
|
||||||
struct amdgpu_mux_entry *e;
|
struct amdgpu_mux_entry *e;
|
||||||
@ -429,6 +450,10 @@ void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *r
|
|||||||
}
|
}
|
||||||
|
|
||||||
chunk->start = ring->wptr;
|
chunk->start = ring->wptr;
|
||||||
|
/* the initialized value used to check if they are set by the ib submission*/
|
||||||
|
chunk->cntl_offset = ring->buf_mask + 1;
|
||||||
|
chunk->de_offset = ring->buf_mask + 1;
|
||||||
|
chunk->ce_offset = ring->buf_mask + 1;
|
||||||
list_add_tail(&chunk->entry, &e->list);
|
list_add_tail(&chunk->entry, &e->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,6 +479,41 @@ static void scan_and_remove_signaled_chunk(struct amdgpu_ring_mux *mux, struct a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amdgpu_ring_mux_ib_mark_offset(struct amdgpu_ring_mux *mux,
|
||||||
|
struct amdgpu_ring *ring, u64 offset,
|
||||||
|
enum amdgpu_ring_mux_offset_type type)
|
||||||
|
{
|
||||||
|
struct amdgpu_mux_entry *e;
|
||||||
|
struct amdgpu_mux_chunk *chunk;
|
||||||
|
|
||||||
|
e = amdgpu_ring_mux_sw_entry(mux, ring);
|
||||||
|
if (!e) {
|
||||||
|
DRM_ERROR("cannot find entry!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = list_last_entry(&e->list, struct amdgpu_mux_chunk, entry);
|
||||||
|
if (!chunk) {
|
||||||
|
DRM_ERROR("cannot find chunk!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AMDGPU_MUX_OFFSET_TYPE_CONTROL:
|
||||||
|
chunk->cntl_offset = offset;
|
||||||
|
break;
|
||||||
|
case AMDGPU_MUX_OFFSET_TYPE_DE:
|
||||||
|
chunk->de_offset = offset;
|
||||||
|
break;
|
||||||
|
case AMDGPU_MUX_OFFSET_TYPE_CE:
|
||||||
|
chunk->ce_offset = offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DRM_ERROR("invalid type (%d)\n", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
|
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
|
||||||
{
|
{
|
||||||
struct amdgpu_mux_entry *e;
|
struct amdgpu_mux_entry *e;
|
||||||
|
@ -50,6 +50,12 @@ struct amdgpu_mux_entry {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum amdgpu_ring_mux_offset_type {
|
||||||
|
AMDGPU_MUX_OFFSET_TYPE_CONTROL,
|
||||||
|
AMDGPU_MUX_OFFSET_TYPE_DE,
|
||||||
|
AMDGPU_MUX_OFFSET_TYPE_CE,
|
||||||
|
};
|
||||||
|
|
||||||
struct amdgpu_ring_mux {
|
struct amdgpu_ring_mux {
|
||||||
struct amdgpu_ring *real_ring;
|
struct amdgpu_ring *real_ring;
|
||||||
|
|
||||||
@ -72,12 +78,18 @@ struct amdgpu_ring_mux {
|
|||||||
* @sync_seq: the fence seqno related with the saved IB.
|
* @sync_seq: the fence seqno related with the saved IB.
|
||||||
* @start:- start location on the software ring.
|
* @start:- start location on the software ring.
|
||||||
* @end:- end location on the software ring.
|
* @end:- end location on the software ring.
|
||||||
|
* @control_offset:- the PRE_RESUME bit position used for resubmission.
|
||||||
|
* @de_offset:- the anchor in write_data for de meta of resubmission.
|
||||||
|
* @ce_offset:- the anchor in write_data for ce meta of resubmission.
|
||||||
*/
|
*/
|
||||||
struct amdgpu_mux_chunk {
|
struct amdgpu_mux_chunk {
|
||||||
struct list_head entry;
|
struct list_head entry;
|
||||||
uint32_t sync_seq;
|
uint32_t sync_seq;
|
||||||
u64 start;
|
u64 start;
|
||||||
u64 end;
|
u64 end;
|
||||||
|
u64 cntl_offset;
|
||||||
|
u64 de_offset;
|
||||||
|
u64 ce_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
int amdgpu_ring_mux_init(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
|
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
|
|||||||
u64 amdgpu_ring_mux_get_rptr(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
u64 amdgpu_ring_mux_get_rptr(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
||||||
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
||||||
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
||||||
|
void amdgpu_ring_mux_ib_mark_offset(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
|
||||||
|
u64 offset, enum amdgpu_ring_mux_offset_type type);
|
||||||
bool amdgpu_mcbp_handle_trailing_fence_irq(struct amdgpu_ring_mux *mux);
|
bool amdgpu_mcbp_handle_trailing_fence_irq(struct amdgpu_ring_mux *mux);
|
||||||
|
|
||||||
u64 amdgpu_sw_ring_get_rptr_gfx(struct amdgpu_ring *ring);
|
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);
|
|||||||
void amdgpu_sw_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
|
void amdgpu_sw_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
|
||||||
void amdgpu_sw_ring_ib_begin(struct amdgpu_ring *ring);
|
void amdgpu_sw_ring_ib_begin(struct amdgpu_ring *ring);
|
||||||
void amdgpu_sw_ring_ib_end(struct amdgpu_ring *ring);
|
void amdgpu_sw_ring_ib_end(struct amdgpu_ring *ring);
|
||||||
|
void amdgpu_sw_ring_ib_mark_offset(struct amdgpu_ring *ring, enum amdgpu_ring_mux_offset_type type);
|
||||||
const char *amdgpu_sw_ring_name(int idx);
|
const char *amdgpu_sw_ring_name(int idx);
|
||||||
unsigned int amdgpu_sw_ring_priority(int idx);
|
unsigned int amdgpu_sw_ring_priority(int idx);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user