STRUCT DRM_I915_QUERY_MEMORY_REGIONS(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– struct drm_i915_query_memory_regions(9) πŸ’–

okay so bestie, welcome to the Kernel API Manual β€” this page is literally all about struct drm_i915_query_memory_regions, and by the end you're gonna know it like the back of your hand. no cap. πŸ¦‹


✨ NAME ✨

struct drm_i915_query_memory_regions β€” yeah so the page header just gives you the struct name and dips, that's it, that's the whole NAME section πŸ™ˆ (there's genuinely no description tagline after the dash, so don't come for me)


⭐ SYNOPSIS ⭐

the whole shape of it, bestie, look:

struct drm_i915_query_memory_regions {
    __u32 num_regions;
    __u32 rsvd[3];
    struct drm_i915_memory_region_info regions[];
 };

like... three fields, one of them flexes an unsized array, we love a growable moment πŸ‘‘


πŸ’… Members πŸ’…

  • num_regions β€” the number of supported regions. the headcount. how many besties are in this region group chat πŸ’–
  • rsvd β€” MBZ, which means Must Be Zero. do not touch. do not decorate. leave it at zero, periodt. 🫢
  • regions β€” the actual tea β˜• β€” info about each supported region, one struct per region.

🌸 Description 🌸

okay so here's the vibe: the region info query is how you get the driver to list every region it knows about. it does that by filling in an array of struct drm_i915_memory_region_info structures. that's it, that's the whole job. it's giving census, but for memory regions 🧚

and here's the literal example for getting the list of supported regions, i did not change a single character because this is sacred code:

struct drm_i915_query_memory_regions *info;
struct drm_i915_query_item item = {
        .query_id = DRM_I915_QUERY_MEMORY_REGIONS;
};
struct drm_i915_query query = {
        .num_items = 1,
        .items_ptr = (uintptr_t)item,
};
int err, i;

// First query the size of the blob we need, this needs to be large
// enough to hold our array of regions. The kernel will fill out the
// item.length for us, which is the number of bytes we need.
err = ioctl(fd, DRM_IOCTL_I915_QUERY, query);
if (err) ...

info = calloc(1, item.length);
// Now that we allocated the required number of bytes, we call the ioctl
// again, this time with the data_ptr pointing to our newly allocated
// blob, which the kernel can then populate with the all the region info.
item.data_ptr = (uintptr_t)info,

err = ioctl(fd, DRM_IOCTL_I915_QUERY, query);
if (err) ...

// We can now access each region in the array
for (i = 0; i < info->num_regions; i++) {
        struct drm_i915_memory_region_info mr = info->regions[i];
        u16 class = mr.region.class;
        u16 instance = mr.region.instance;

        ....
}

free(info);

the way this works is a two-pass situation, and honestly? iconic. πŸŽ€

  1. first ioctl(fd, DRM_IOCTL_I915_QUERY, query) call β€” you're just asking "how many bytes do i need?" the kernel fills out item.length for you with the exact byte count. no guessing required, it literally tells you. πŸ’«
  2. then info = calloc(1, item.length); β€” allocate that many bytes, slay.
  3. then you set item.data_ptr = (uintptr_t)info, and hit the same ioctl(fd, DRM_IOCTL_I915_QUERY, query) again β€” this time the kernel populates your freshly allocated blob with all the region info. ate and left no crumbs πŸ”₯
  4. then you loop for (i = 0; i < info->num_regions; i++), grab each struct drm_i915_memory_region_info mr = info->regions[i];, and read mr.region.class and mr.region.instance into your u16s. main character data extraction moment πŸ‘‘
  5. and obviously free(info); β€” memory hygiene is self care, bestie, do not leak 🫧
ngl both ioctl calls check if (err) ... β€” please actually handle your errors, i'm begging πŸ™ the ... is a placeholder, not a lifestyle.

πŸ¦‹ SEE ALSO πŸ¦‹

the whole friend group, in order, exactly as listed β€” go say hi to all of them:

  • Kernel file ./tools/perf/trace/beauty/include/uapi/drm/i915_drm.h
  • uevents generated by i915 on its device node(9)
  • struct i915_user_extension(9)
  • enum drm_i915_gem_engine_class(9)
  • struct i915_engine_class_instance(9)
  • perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915(9)
  • struct drm_i915_getparam(9)
  • drm_i915_getparam_t(9)
  • struct drm_i915_gem_mmap_offset(9)
  • struct drm_i915_gem_set_domain(9)
  • struct drm_i915_gem_exec_fence(9)
  • struct drm_i915_gem_execbuffer_ext_timeline_fences(9)
  • struct drm_i915_gem_execbuffer2(9)
  • struct drm_i915_gem_caching(9)
  • struct drm_i915_gem_context_create_ext(9)
  • struct drm_i915_gem_context_param(9)
  • Virtual Engine uAPI(9)
  • struct i915_context_engines_parallel_submit(9)
  • Context Engine Map uAPI(9)
  • struct drm_i915_gem_context_create_ext_setparam(9)
  • struct drm_i915_gem_vm_control(9)
  • struct drm_i915_gem_userptr(9)
  • struct drm_i915_perf_oa_config(9)
  • struct drm_i915_query_item(9)
  • struct drm_i915_query(9)
  • struct drm_i915_query_topology_info(9)
  • Engine Discovery uAPI(9)
  • struct drm_i915_engine_info(9)
  • struct drm_i915_query_engine_info(9)
  • struct drm_i915_query_perf_config(9)
  • enum drm_i915_gem_memory_class(9)
  • struct drm_i915_gem_memory_class_instance(9)
  • struct drm_i915_memory_region_info(9)
  • struct drm_i915_query_guc_submission_version(9)
  • GuC HWCONFIG blob uAPI(9)
  • struct drm_i915_gem_create_ext(9)
  • struct drm_i915_gem_create_ext_memory_regions(9)
  • struct drm_i915_gem_create_ext_protected_content(9)
  • struct drm_i915_gem_create_ext_set_pat(9)

ok and one last thing β€” the footer on this page shows the source as ./tools/perf/trace/beauty/incl... (yep, truncated like that in the original, not me being lazy πŸ’€) and the date is October 2026. so that's the version deets, mwah, go query some regions bestie, you're gonna do amazing πŸ’œβœ¨πŸŒˆ
πŸ“¦ where this page comes from