drivers/gpu/drm/xe/xe_query.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_query.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/xe/xe_query.c- Extension
.c- Size
- 21325 bytes
- Lines
- 822
- 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.
- 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
xe_query.hlinux/nospec.hlinux/sched/clock.hdrm/ttm/ttm_placement.hgenerated/xe_wa_oob.huapi/drm/xe_drm.hregs/xe_engine_regs.hregs/xe_gt_regs.hxe_bo.hxe_device.hxe_eu_stall.hxe_exec_queue.hxe_force_wake.hxe_ggtt.hxe_gt.hxe_gt_topology.hxe_guc_hwconfig.hxe_macros.hxe_mmio.hxe_oa.hxe_pxp.hxe_ttm_vram_mgr.hxe_vram_types.hxe_wa.h
Detected Declarations
function calc_hw_engine_info_sizefunction for_each_gtfunction __clock_id_to_funcfunction hwe_read_timestampfunction query_engine_cyclesfunction xe_with_force_wakefunction query_enginesfunction for_each_gtfunction calc_mem_regions_sizefunction query_mem_regionsfunction query_configfunction query_gt_listfunction for_each_gtfunction query_hwconfigfunction calc_topo_query_sizefunction for_each_gtfunction copy_maskfunction query_gt_topologyfunction for_each_gtfunction query_uc_fw_versionfunction for_each_tilefunction calc_oa_unit_query_sizefunction for_each_gtfunction query_oa_unitsfunction for_each_hw_enginefunction query_pxp_statusfunction query_eu_stallfunction xe_query_ioctl
Annotated Snippet
for_each_hw_engine(hwe, gt, id) {
if (xe_hw_engine_is_reserved(hwe))
continue;
i++;
}
return sizeof(struct drm_xe_query_engines) +
i * sizeof(struct drm_xe_engine);
}
typedef u64 (*__ktime_func_t)(void);
static __ktime_func_t __clock_id_to_func(clockid_t clk_id)
{
/*
* Use logic same as the perf subsystem to allow user to select the
* reference clock id to be used for timestamps.
*/
switch (clk_id) {
case CLOCK_MONOTONIC:
return &ktime_get_ns;
case CLOCK_MONOTONIC_RAW:
return &ktime_get_raw_ns;
case CLOCK_REALTIME:
return &ktime_get_real_ns;
case CLOCK_BOOTTIME:
return &ktime_get_boottime_ns;
case CLOCK_TAI:
return &ktime_get_clocktai_ns;
default:
return NULL;
}
}
static void
hwe_read_timestamp(struct xe_hw_engine *hwe, u64 *engine_ts, u64 *cpu_ts,
u64 *cpu_delta, __ktime_func_t cpu_clock)
{
struct xe_mmio *mmio = &hwe->gt->mmio;
u32 upper, lower, old_upper, loop = 0;
struct xe_reg upper_reg = RING_TIMESTAMP_UDW(hwe->mmio_base),
lower_reg = RING_TIMESTAMP(hwe->mmio_base);
upper = xe_mmio_read32(mmio, upper_reg);
do {
*cpu_delta = local_clock();
*cpu_ts = cpu_clock();
lower = xe_mmio_read32(mmio, lower_reg);
*cpu_delta = local_clock() - *cpu_delta;
old_upper = upper;
upper = xe_mmio_read32(mmio, upper_reg);
} while (upper != old_upper && loop++ < 2);
*engine_ts = (u64)upper << 32 | lower;
}
static int
query_engine_cycles(struct xe_device *xe,
struct drm_xe_device_query *query)
{
struct drm_xe_query_engine_cycles __user *query_ptr;
struct drm_xe_engine_class_instance *eci;
struct drm_xe_query_engine_cycles resp;
size_t size = sizeof(resp);
__ktime_func_t cpu_clock;
struct xe_hw_engine *hwe;
struct xe_gt *gt;
if (IS_SRIOV_VF(xe))
return -EOPNOTSUPP;
if (query->size == 0) {
query->size = size;
return 0;
} else if (XE_IOCTL_DBG(xe, query->size != size)) {
return -EINVAL;
}
query_ptr = u64_to_user_ptr(query->data);
if (copy_from_user(&resp, query_ptr, size))
return -EFAULT;
cpu_clock = __clock_id_to_func(resp.clockid);
if (!cpu_clock)
return -EINVAL;
eci = &resp.eci;
gt = xe_device_get_gt(xe, eci->gt_id);
if (!gt)
return -EINVAL;
Annotation
- Immediate include surface: `xe_query.h`, `linux/nospec.h`, `linux/sched/clock.h`, `drm/ttm/ttm_placement.h`, `generated/xe_wa_oob.h`, `uapi/drm/xe_drm.h`, `regs/xe_engine_regs.h`, `regs/xe_gt_regs.h`.
- Detected declarations: `function calc_hw_engine_info_size`, `function for_each_gt`, `function __clock_id_to_func`, `function hwe_read_timestamp`, `function query_engine_cycles`, `function xe_with_force_wake`, `function query_engines`, `function for_each_gt`, `function calc_mem_regions_size`, `function query_mem_regions`.
- 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.
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.