drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c- Extension
.c- Size
- 15983 bytes
- Lines
- 577
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hdrm/drm_print.hamdgpu_ring_mux.hamdgpu_ring.hamdgpu.h
Detected Declarations
function amdgpu_ring_mux_copy_pkt_from_sw_ringfunction amdgpu_mux_resubmit_chunksfunction list_for_each_entryfunction amdgpu_ring_mux_schedule_resubmitfunction amdgpu_mux_resubmit_fallbackfunction amdgpu_ring_mux_initfunction amdgpu_ring_mux_finifunction list_for_each_entry_safefunction amdgpu_ring_mux_add_sw_ringfunction amdgpu_ring_mux_set_wptrfunction amdgpu_ring_mux_get_wptrfunction amdgpu_ring_mux_get_rptrfunction amdgpu_sw_ring_get_rptr_gfxfunction amdgpu_sw_ring_get_wptr_gfxfunction amdgpu_sw_ring_set_wptr_gfxfunction amdgpu_sw_ring_insert_nopfunction amdgpu_sw_ring_priorityfunction amdgpu_mcbp_scanfunction amdgpu_mcbp_trigger_preemptfunction amdgpu_sw_ring_ib_beginfunction amdgpu_sw_ring_ib_endfunction amdgpu_sw_ring_ib_mark_offsetfunction amdgpu_ring_mux_start_ibfunction scan_and_remove_signaled_chunkfunction list_for_each_entry_safefunction amdgpu_ring_mux_ib_mark_offsetfunction amdgpu_ring_mux_end_ibfunction amdgpu_mcbp_handle_trailing_fence_irq
Annotated Snippet
if (mux->ring_entry[i].ring->hw_prio <= AMDGPU_RING_PRIO_DEFAULT) {
e = &mux->ring_entry[i];
break;
}
}
if (!e) {
DRM_ERROR("%s no low priority ring found\n", __func__);
return;
}
last_seq = atomic_read(&e->ring->fence_drv.last_seq);
seq = mux->seqno_to_resubmit;
if (last_seq < seq) {
/*resubmit all the fences between (last_seq, seq]*/
list_for_each_entry(chunk, &e->list, entry) {
if (chunk->sync_seq > last_seq && chunk->sync_seq <= seq) {
amdgpu_fence_update_start_timestamp(e->ring,
chunk->sync_seq,
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,
chunk->start,
chunk->end);
mux->wptr_resubmit = chunk->end;
amdgpu_ring_commit(mux->real_ring);
}
}
}
timer_delete(&mux->resubmit_timer);
mux->s_resubmit = false;
}
static void amdgpu_ring_mux_schedule_resubmit(struct amdgpu_ring_mux *mux)
{
mod_timer(&mux->resubmit_timer, jiffies + AMDGPU_MUX_RESUBMIT_JIFFIES_TIMEOUT);
}
static void amdgpu_mux_resubmit_fallback(struct timer_list *t)
{
struct amdgpu_ring_mux *mux = timer_container_of(mux, t,
resubmit_timer);
if (!spin_trylock(&mux->lock)) {
amdgpu_ring_mux_schedule_resubmit(mux);
DRM_ERROR("reschedule resubmit\n");
return;
}
amdgpu_mux_resubmit_chunks(mux);
spin_unlock(&mux->lock);
}
int amdgpu_ring_mux_init(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
unsigned int entry_size)
{
mux->real_ring = ring;
mux->num_ring_entries = 0;
mux->ring_entry = kzalloc_objs(struct amdgpu_mux_entry, entry_size);
if (!mux->ring_entry)
return -ENOMEM;
mux->ring_entry_size = entry_size;
mux->s_resubmit = false;
amdgpu_mux_chunk_slab = KMEM_CACHE(amdgpu_mux_chunk, SLAB_HWCACHE_ALIGN);
if (!amdgpu_mux_chunk_slab) {
DRM_ERROR("create amdgpu_mux_chunk cache failed\n");
return -ENOMEM;
}
spin_lock_init(&mux->lock);
timer_setup(&mux->resubmit_timer, amdgpu_mux_resubmit_fallback, 0);
return 0;
}
void amdgpu_ring_mux_fini(struct amdgpu_ring_mux *mux)
{
struct amdgpu_mux_entry *e;
Annotation
- Immediate include surface: `linux/slab.h`, `drm/drm_print.h`, `amdgpu_ring_mux.h`, `amdgpu_ring.h`, `amdgpu.h`.
- Detected declarations: `function amdgpu_ring_mux_copy_pkt_from_sw_ring`, `function amdgpu_mux_resubmit_chunks`, `function list_for_each_entry`, `function amdgpu_ring_mux_schedule_resubmit`, `function amdgpu_mux_resubmit_fallback`, `function amdgpu_ring_mux_init`, `function amdgpu_ring_mux_fini`, `function list_for_each_entry_safe`, `function amdgpu_ring_mux_add_sw_ring`, `function amdgpu_ring_mux_set_wptr`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.