drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c- Extension
.c- Size
- 30877 bytes
- Lines
- 1150
- 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/slab.hlinux/list.hkfd_device_queue_manager.hkfd_priv.hkfd_kernel_queue.hamdgpu_amdkfd.hamdgpu_reset.h
Detected Declarations
function filesfunction list_for_each_entryfunction assign_queue_slot_by_qidfunction find_available_queue_slotfunction kfd_process_dequeue_from_devicefunction down_read_trylockfunction pqm_set_gwsfunction kfd_process_dequeue_from_all_devicesfunction pqm_initfunction pqm_clean_queue_resourcefunction pqm_uninitfunction list_for_each_entry_safefunction init_user_queuefunction oversubscriptionfunction pqm_create_queuefunction pqm_destroy_queuefunction pqm_update_queue_propertiesfunction pqm_update_mqdfunction KFD_GC_VERSIONfunction pqm_get_wave_statefunction pqm_get_queue_snapshotfunction list_for_each_entryfunction get_queue_data_sizesfunction kfd_process_get_queue_infofunction list_for_each_entryfunction pqm_checkpoint_mqdfunction criu_checkpoint_queuefunction criu_checkpoint_queues_devicefunction list_for_each_entryfunction kfd_criu_checkpoint_queuesfunction set_queue_properties_from_criufunction kfd_criu_restore_queuefunction pqm_get_queue_checkpoint_infofunction pqm_debugfs_mqdsfunction list_for_each_entry
Annotated Snippet
down_read_trylock(&dev->adev->reset_domain->sem)) {
amdgpu_mes_flush_shader_debugger(dev->adev,
pdd->proc_ctx_gpu_addr,
ffs(pdd->dev->xcc_mask) - 1);
up_read(&dev->adev->reset_domain->sem);
}
pdd->already_dequeued = true;
}
int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid,
void *gws)
{
struct mqd_update_info minfo = {0};
struct kfd_node *dev = NULL;
struct process_queue_node *pqn;
struct kfd_process_device *pdd;
struct kgd_mem *mem = NULL;
int ret;
pqn = get_queue_by_qid(pqm, qid);
if (!pqn) {
pr_err("Queue id does not match any known queue\n");
return -EINVAL;
}
if (pqn->q)
dev = pqn->q->device;
if (WARN_ON(!dev))
return -ENODEV;
pdd = kfd_get_process_device_data(dev, pqm->process);
if (!pdd) {
pr_err("Process device data doesn't exist\n");
return -EINVAL;
}
/* Only allow one queue per process can have GWS assigned */
if (gws && pdd->qpd.num_gws)
return -EBUSY;
if (!gws && pdd->qpd.num_gws == 0)
return -EINVAL;
if ((KFD_GC_VERSION(dev) != IP_VERSION(9, 4, 3) &&
KFD_GC_VERSION(dev) != IP_VERSION(9, 4, 4) &&
KFD_GC_VERSION(dev) != IP_VERSION(9, 5, 0)) &&
!dev->kfd->shared_resources.enable_mes) {
if (gws)
ret = amdgpu_amdkfd_add_gws_to_process(pdd->process->kgd_process_info,
gws, &mem);
else
ret = amdgpu_amdkfd_remove_gws_from_process(pdd->process->kgd_process_info,
pqn->q->gws);
if (unlikely(ret))
return ret;
pqn->q->gws = mem;
} else {
/*
* Intentionally set GWS to a non-NULL value
* for devices that do not use GWS for global wave
* synchronization but require the formality
* of setting GWS for cooperative groups.
*/
pqn->q->gws = gws ? ERR_PTR(-ENOMEM) : NULL;
}
pdd->qpd.num_gws = gws ? dev->adev->gds.gws_size : 0;
minfo.update_flag = gws ? UPDATE_FLAG_IS_GWS : 0;
return pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
pqn->q, &minfo);
}
void kfd_process_dequeue_from_all_devices(struct kfd_process *p)
{
int i;
for (i = 0; i < p->n_pdds; i++)
kfd_process_dequeue_from_device(p->pdds[i]);
}
int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p)
{
INIT_LIST_HEAD(&pqm->queues);
pqm->queue_slot_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
GFP_KERNEL);
if (!pqm->queue_slot_bitmap)
return -ENOMEM;
pqm->process = p;
Annotation
- Immediate include surface: `linux/slab.h`, `linux/list.h`, `kfd_device_queue_manager.h`, `kfd_priv.h`, `kfd_kernel_queue.h`, `amdgpu_amdkfd.h`, `amdgpu_reset.h`.
- Detected declarations: `function files`, `function list_for_each_entry`, `function assign_queue_slot_by_qid`, `function find_available_queue_slot`, `function kfd_process_dequeue_from_device`, `function down_read_trylock`, `function pqm_set_gws`, `function kfd_process_dequeue_from_all_devices`, `function pqm_init`, `function pqm_clean_queue_resource`.
- 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.