drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c- Extension
.c- Size
- 36888 bytes
- Lines
- 1410
- 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
drm/drm_auth.hdrm/drm_exec.hlinux/pm_runtime.hdrm/drm_drv.hamdgpu.hamdgpu_reset.hamdgpu_vm.hamdgpu_userq.hamdgpu_hmm.hamdgpu_userq_fence.h
Detected Declarations
function filesfunction amdgpu_userq_is_reset_type_supportedfunction amdgpu_userq_mgr_reset_workfunction amdgpu_userq_hang_detect_workfunction amdgpu_userq_start_hang_detect_workfunction amdgpu_userq_process_fence_irqfunction amdgpu_userq_input_va_validatefunction amdgpu_userq_buffer_va_mappedfunction amdgpu_userq_buffer_vas_mappedfunction amdgpu_userq_preempt_helperfunction amdgpu_userq_restore_helperfunction amdgpu_userq_unmap_helperfunction amdgpu_userq_map_helperfunction amdgpu_userq_wait_for_last_fencefunction amdgpu_userq_cleanupfunction amdgpu_userq_ensure_ev_fencefunction amdgpu_userq_get_doorbell_indexfunction amdgpu_bo_sizefunction amdgpu_userq_destroyfunction amdgpu_userq_kref_destroyfunction amdgpu_userq_putfunction amdgpu_userq_priority_permitfunction amdgpu_userq_createfunction amdgpu_userq_input_args_validatefunction amdgpu_userq_enabledfunction amdgpu_userq_ioctlfunction amdgpu_userq_restore_allfunction amdgpu_userq_validate_vmfunction amdgpu_userq_bo_validatefunction amdgpu_userq_vm_validatefunction xa_for_eachfunction amdgpu_userq_restore_workerfunction amdgpu_userq_evict_allfunction amdgpu_userq_wait_for_signalfunction xa_for_eachfunction amdgpu_userq_evictfunction amdgpu_userq_mgr_initfunction amdgpu_userq_mgr_cancel_reset_workfunction amdgpu_userq_mgr_cancel_resumefunction amdgpu_userq_mgr_finifunction amdgpu_userq_suspendfunction xa_for_eachfunction amdgpu_userq_resumefunction xa_for_eachfunction amdgpu_userq_stop_sched_for_enforce_isolationfunction amdgpu_userq_start_sched_for_enforce_isolationfunction xa_for_eachfunction amdgpu_userq_gem_va_unmap_validate
Annotated Snippet
if (r) {
gpu_reset = true;
break;
}
}
}
if (gpu_reset) {
struct amdgpu_reset_context reset_context;
memset(&reset_context, 0, sizeof(reset_context));
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
reset_context.src = AMDGPU_RESET_SRC_USERQ;
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
/*set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);*/
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
}
}
static void amdgpu_userq_hang_detect_work(struct work_struct *work)
{
struct amdgpu_usermode_queue *queue =
container_of(work, struct amdgpu_usermode_queue,
hang_detect_work.work);
/*
* Don't schedule the work here! Scheduling or queue work from one reset
* handler to another is illegal if you don't take extra precautions!
*/
amdgpu_userq_mgr_reset_work(&queue->userq_mgr->reset_work);
}
/*
* Start hang detection for a user queue fence. A delayed work will be scheduled
* to reset the queues when the fence doesn't signal in time.
*/
void amdgpu_userq_start_hang_detect_work(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_device *adev;
unsigned long timeout_ms;
adev = queue->userq_mgr->adev;
/* Determine timeout based on queue type */
switch (queue->queue_type) {
case AMDGPU_RING_TYPE_GFX:
timeout_ms = adev->gfx_timeout;
break;
case AMDGPU_RING_TYPE_COMPUTE:
timeout_ms = adev->compute_timeout;
break;
case AMDGPU_RING_TYPE_SDMA:
timeout_ms = adev->sdma_timeout;
break;
default:
timeout_ms = adev->gfx_timeout;
break;
}
queue_delayed_work(adev->reset_domain->wq, &queue->hang_detect_work,
msecs_to_jiffies(timeout_ms));
}
void amdgpu_userq_process_fence_irq(struct amdgpu_device *adev, u32 doorbell)
{
struct xarray *xa = &adev->userq_doorbell_xa;
struct amdgpu_usermode_queue *queue;
unsigned long flags;
int r;
xa_lock_irqsave(xa, flags);
queue = xa_load(xa, doorbell);
if (queue) {
r = amdgpu_userq_fence_driver_process(queue->fence_drv);
/*
* We are in interrupt context here, this *can't* wait for
* reset work to finish.
*/
if (r >= 0)
cancel_delayed_work(&queue->hang_detect_work);
/* Restart the timer when there are still fences pending */
if (r == 1)
amdgpu_userq_start_hang_detect_work(queue);
}
xa_unlock_irqrestore(xa, flags);
}
Annotation
- Immediate include surface: `drm/drm_auth.h`, `drm/drm_exec.h`, `linux/pm_runtime.h`, `drm/drm_drv.h`, `amdgpu.h`, `amdgpu_reset.h`, `amdgpu_vm.h`, `amdgpu_userq.h`.
- Detected declarations: `function files`, `function amdgpu_userq_is_reset_type_supported`, `function amdgpu_userq_mgr_reset_work`, `function amdgpu_userq_hang_detect_work`, `function amdgpu_userq_start_hang_detect_work`, `function amdgpu_userq_process_fence_irq`, `function amdgpu_userq_input_va_validate`, `function amdgpu_userq_buffer_va_mapped`, `function amdgpu_userq_buffer_vas_mapped`, `function amdgpu_userq_preempt_helper`.
- 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.