drivers/gpu/drm/radeon/radeon_cs.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/radeon_cs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/radeon/radeon_cs.c- Extension
.c- Size
- 23858 bytes
- Lines
- 891
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/list_sort.hlinux/pci.hlinux/uaccess.hdrm/drm_device.hdrm/drm_file.hdrm/radeon_drm.hradeon.hradeon_reg.hradeon_trace.h
Detected Declarations
struct radeon_cs_bucketsfunction radeon_cs_buckets_initfunction radeon_cs_buckets_addfunction radeon_cs_buckets_get_listfunction radeon_cs_parser_relocsfunction radeon_cs_get_ringfunction radeon_cs_sync_ringsfunction list_for_each_entryfunction radeon_cs_parser_initfunction cmp_size_smaller_firstfunction radeon_cs_parser_finifunction list_for_each_entryfunction radeon_cs_ib_chunkfunction radeon_bo_vm_update_ptefunction radeon_cs_ib_vm_chunkfunction radeon_cs_handle_lockupfunction radeon_cs_ib_fillfunction radeon_cs_ioctlfunction radeon_cs_packet_parsefunction radeon_cs_packet_next_is_pkt3_nopfunction radeon_cs_dump_packetfunction radeon_cs_packet_next_reloc
Annotated Snippet
struct radeon_cs_buckets {
struct list_head bucket[RADEON_CS_NUM_BUCKETS];
};
static void radeon_cs_buckets_init(struct radeon_cs_buckets *b)
{
unsigned i;
for (i = 0; i < RADEON_CS_NUM_BUCKETS; i++)
INIT_LIST_HEAD(&b->bucket[i]);
}
static void radeon_cs_buckets_add(struct radeon_cs_buckets *b,
struct list_head *item, unsigned priority)
{
/* Since buffers which appear sooner in the relocation list are
* likely to be used more often than buffers which appear later
* in the list, the sort mustn't change the ordering of buffers
* with the same priority, i.e. it must be stable.
*/
list_add_tail(item, &b->bucket[min(priority, RADEON_CS_MAX_PRIORITY)]);
}
static void radeon_cs_buckets_get_list(struct radeon_cs_buckets *b,
struct list_head *out_list)
{
unsigned i;
/* Connect the sorted buckets in the output list. */
for (i = 0; i < RADEON_CS_NUM_BUCKETS; i++) {
list_splice(&b->bucket[i], out_list);
}
}
static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
{
struct radeon_cs_chunk *chunk;
struct radeon_cs_buckets buckets;
unsigned i;
bool need_mmap_lock = false;
int r;
if (p->chunk_relocs == NULL) {
return 0;
}
chunk = p->chunk_relocs;
p->dma_reloc_idx = 0;
/* FIXME: we assume that each relocs use 4 dwords */
p->nrelocs = chunk->length_dw / 4;
p->relocs = kvzalloc_objs(struct radeon_bo_list, p->nrelocs);
if (p->relocs == NULL) {
return -ENOMEM;
}
radeon_cs_buckets_init(&buckets);
for (i = 0; i < p->nrelocs; i++) {
struct drm_radeon_cs_reloc *r;
struct drm_gem_object *gobj;
unsigned priority;
r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4];
gobj = drm_gem_object_lookup(p->filp, r->handle);
if (gobj == NULL) {
DRM_ERROR("gem object lookup failed 0x%x\n",
r->handle);
return -ENOENT;
}
p->relocs[i].robj = gem_to_radeon_bo(gobj);
/* The userspace buffer priorities are from 0 to 15. A higher
* number means the buffer is more important.
* Also, the buffers used for write have a higher priority than
* the buffers used for read only, which doubles the range
* to 0 to 31. 32 is reserved for the kernel driver.
*/
priority = (r->flags & RADEON_RELOC_PRIO_MASK) * 2
+ !!r->write_domain;
/* The first reloc of an UVD job is the msg and that must be in
* VRAM, the second reloc is the DPB and for WMV that must be in
* VRAM as well. Also put everything into VRAM on AGP cards and older
* IGP chips to avoid image corruptions
*/
if (p->ring == R600_RING_TYPE_UVD_INDEX &&
(i <= 0 || pci_find_capability(p->rdev->pdev, PCI_CAP_ID_AGP) ||
p->rdev->family == CHIP_RS780 ||
p->rdev->family == CHIP_RS880)) {
/* TODO: is this still needed for NI+ ? */
Annotation
- Immediate include surface: `linux/list_sort.h`, `linux/pci.h`, `linux/uaccess.h`, `drm/drm_device.h`, `drm/drm_file.h`, `drm/radeon_drm.h`, `radeon.h`, `radeon_reg.h`.
- Detected declarations: `struct radeon_cs_buckets`, `function radeon_cs_buckets_init`, `function radeon_cs_buckets_add`, `function radeon_cs_buckets_get_list`, `function radeon_cs_parser_relocs`, `function radeon_cs_get_ring`, `function radeon_cs_sync_rings`, `function list_for_each_entry`, `function radeon_cs_parser_init`, `function cmp_size_smaller_first`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.