STRUCT DRM_GPUVM(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’œ struct drm_gpuvm β€” DRM GPU VA Manager πŸ’œ

okay so this is from the Kernel API Manual, and bestie, it's the whole struct drm_gpuvm, like, the actual DRM GPU VA Manager. it's giving "one struct to rule the whole virtual address space" and honestly? iconic. let's get into it 🫢


✨ NAME ✨

struct drm_gpuvm β€” the DRM GPU VA Manager, fr fr. this is the main character of GPU virtual address space management πŸ’…


🌸 SYNOPSIS 🌸

struct drm_gpuvm {
    const char *name;
    enum drm_gpuvm_flags flags;
    struct drm_device *drm;
    u64 mm_start;
    u64 mm_range;
    struct {
      struct rb_root_cached tree;
      struct list_head list;
    } rb;
    struct kref kref;
    struct drm_gpuva kernel_alloc_node;
    const struct drm_gpuvm_ops *ops;
    struct drm_gem_object *r_obj;
    struct {
      struct list_head list;
      struct list_head *local_list;
      spinlock_t lock;
    } extobj;
    struct {
      struct list_head list;
      struct list_head *local_list;
      spinlock_t lock;
    } evict;
    struct llist_head bo_defer;
 };

like, look at all those nested anonymous structs. the structure. the nesting. highkey obsessed πŸ¦‹


πŸŽ€ Members πŸŽ€

okay bestie, member by member, no skipping, no cap:

  • name β€” the name of the DRM GPU VA space. yes it's just a string. yes it's still the moment πŸ’«
  • flags β€” the drm_gpuvm_flags of this GPUVM. the vibe check of the whole VM, basically ✨
  • drm β€” the drm_device this VM lives in. its home. its whole address 🏠
  • mm_start β€” start of the VA space. where it all begins πŸ₯Ί
  • mm_range β€” length of the VA space. how much room we're working with πŸ“
  • rb β€” structures to track drm_gpuva entries πŸ’–
    • rb.tree β€” the rb-tree to track GPU VA mappings 🌳
    • rb.list β€” the list_head to track GPU VA mappings πŸ“‹
  • kref β€” reference count of this object. the classic "who's still holding a ref" situation πŸ™ˆ
  • kernel_alloc_node β€” a drm_gpuva representing the address space cutout reserved for the kernel. kernel gets its own lil VIP section πŸ‘‘
  • ops β€” drm_gpuvm_ops providing the split/merge steps to drivers. the driver's cheat sheet for splitting and merging, lowkey essential πŸ’…
  • r_obj β€” Resv GEM object; representing the GPUVM's common dma_resv. one shared reservation object for everybody 🀝
  • extobj β€” structure holding the extobj list πŸ“¦
    • extobj.list β€” list_head storing drm_gpuvm_bos serving as external object 🌈
    • extobj.local_list β€” pointer to the local list temporarily storing entries from the external object list. a lil temporary holding pen 🍼
    • extobj.lock β€” spinlock to protect the extobj list πŸ”’
  • evict β€” structure holding the evict list and evict list lock 🧹
    • evict.list β€” list_head storing drm_gpuvm_bos currently being evicted πŸ‘‹
    • evict.local_list β€” pointer to the local list temporarily storing entries from the evicted object list. again: temporary pen, but for the evicted ones πŸšͺ
    • evict.lock β€” spinlock to protect the evict list πŸ”
  • bo_defer β€” structure holding vm_bos that need to be destroyed. cleanup crew energy πŸ’€

πŸ”₯ Description πŸ”₯

so the DRM GPU VA Manager keeps track of a GPU's virtual address space by using maple_tree structures. love that for it. typically, this structure is embedded in bigger driver structures β€” it's not out here alone, it's part of a friend group 🧚

drivers can pass addresses and ranges in an arbitrary unit, e.g. bytes or pages. literally whatever unit, the manager does not care πŸ’…

there should be one manager instance per GPU virtual address space. one. per. space. no sharing, no splitting, periodt πŸ‘‘


πŸ‘€ SEE ALSO πŸ‘€

the whole squad, a.k.a. the kernel file ./include/drm/drm_gpuvm.h and everybody in it:

enum drm_gpuva_flags(9), struct drm_gpuva(9), drm_gpuva_invalidate(9), drm_gpuva_invalidated(9), enum drm_gpuvm_flags(9), drm_gpuvm_get(9), drm_gpuvm_resv_protected(9), drm_gpuvm_immediate_mode(9), drm_gpuvm_resv(9), drm_gpuvm_resv_obj(9), drm_gpuvm_is_extobj(9), drm_gpuvm_for_each_va_range(9), drm_gpuvm_for_each_va_range_safe(9), drm_gpuvm_for_each_va(9), drm_gpuvm_for_each_va_safe(9), struct drm_gpuvm_exec(9), drm_gpuvm_exec_unlock(9), drm_gpuvm_exec_resv_add_fence(9), drm_gpuvm_exec_validate(9), struct drm_gpuvm_bo(9), drm_gpuvm_bo_get(9), drm_gpuvm_bo_gem_evict(9), drm_gpuvm_bo_for_each_va(9), drm_gpuvm_bo_for_each_va_safe(9), enum drm_gpuva_op_type(9), struct drm_gpuva_op_map(9), struct drm_gpuva_op_unmap(9), struct drm_gpuva_op_remap(9), struct drm_gpuva_op_prefetch(9), struct drm_gpuva_op(9), struct drm_gpuva_ops(9), drm_gpuva_for_each_op(9), drm_gpuva_for_each_op_safe(9), drm_gpuva_for_each_op_from_reverse(9), drm_gpuva_for_each_op_reverse(9), drm_gpuva_first_op(9), drm_gpuva_last_op(9), drm_gpuva_prev_op(9), drm_gpuva_next_op(9), struct drm_gpuvm_map_req(9), struct drm_gpuvm_ops(9), drm_gpuva_op_remap_to_unmap_range(9)

that's a whole friend group and they're all invited to the group chat πŸ˜­πŸ’–


ngl this page came from ./include/drm and it's dated October 2026, so it's from the future AND the headers. slay. okay bye bestie, go manage those virtual addresses πŸ’œβœ¨πŸŽ€
πŸ“¦ where this page comes from