STRUCT DRM_GEM_OBJECT(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸŽ€ struct drm_gem_object(9) πŸŽ€

okay so bestie, welcome to the struct drm_gem_object(9) page from your very own Kernel API Manual β€” like, this is the whole vibe of a GEM buffer object and honestly? it ate. let's get into it πŸ’…


✨ NAME ✨

struct drm_gem_object β€” GEM buffer object. that's it, that's the whole name, iconic.


🌸 SYNOPSIS 🌸

here's the struct in all its glory, copy it exactly bestie, no cap:

struct drm_gem_object {
    struct kref refcount;
    unsigned handle_count;
    struct drm_device *dev;
    struct file *filp;
    struct drm_vma_offset_node vma_node;
    size_t size;
    int name;
    struct dma_buf *dma_buf;
    struct dma_buf_attachment *import_attach;
    struct dma_resv *resv;
    struct dma_resv _resv;
    struct {
      struct list_head list;
      struct mutex lock;
    } gpuva;
    const struct drm_gem_object_funcs *funcs;
    struct list_head lru_node;
    struct drm_gem_lru *lru;
 };

πŸ’– Members πŸ’–

  • refcount β€” the reference count of this object, the little number keeping it alive 🫢

pleaseeee use drm_gem_object_get to acquire a reference, and drm_gem_object_put_locked or drm_gem_object_put to release a reference to a GEM buffer object. that's the whole ritual, don't freestyle it.

  • handle_count β€” this is the GEM file_priv handle count of this object.

each handle also holds a reference, so it's double-dipping (affectionate). and note: when the handle_count drops to 0, any global names (e.g. the id in the flink namespace) will be cleared. bye bestie πŸ‘‹

protected by drm_device.object_name_lock.

  • dev β€” the DRM dev this object belongs to. its home base fr fr.
  • filp β€” SHMEM file node used as backing storage for swappable buffer objects. GEM also supports driver private objects with driver-specific backing storage (contiguous DMA memory, special reserved blocks). in that case filp is NULL. so like, sometimes it's a NULL situation and that's fine πŸ’€
  • vma_node β€” mapping info for this object to support mmap. drivers are supposed to allocate the mmap offset using drm_gem_create_mmap_offset. the offset itself can be retrieved using drm_vma_node_offset_addr.

the memory mapping itself is handled by drm_gem_mmap, which also checks that userspace is allowed to access the object. security check, we love to see it ✨

  • size β€” size of the object, in bytes. immutable over the object's lifetime. so it is NOT changing, don't even try, it's set in its ways and honestly same.
  • name β€” global name for this object, starts at 1. 0 means unnamed. access is covered by drm_device.object_name_lock. this is used by the GEM_FLINK and GEM_OPEN ioctls. iykyk πŸ”₯
  • dma_buf β€” dma-buf associated with this GEM object.

pointer to the dma-buf associated with this gem object (either through importing or exporting). we break the resulting reference loop when the last gem handle for this object is released. very much a "we don't do infinite loops here" moment.

protected by drm_device.object_name_lock.

  • import_attach β€” dma-buf attachment backing this object.

any foreign dma_buf imported as a gem object has this set to the attachment point for the device. this is invariant over the lifetime of a gem object β€” like, it does not change, periodt.

the drm_gem_object_funcs.free callback is responsible for cleaning up the dma_buf attachment and references acquired at import time. that's its whole job, let it cook πŸ“

note that the drm gem/prime core does not depend upon drivers setting this field any more. so for drivers where this doesn't make sense (e.g. virtual devices or a displaylink behind an usb bus) they can simply leave it as NULL. no pressure bestie πŸ’œ
  • resv β€” pointer to reservation object associated with the this GEM object.

normally (resv == &_resv) except for imported GEM objects. so it's usually pointing at its own little buddy right there in the struct, cute.

  • _resv β€” a reservation object for this GEM object.

this is unused for imported GEM objects. it's just sitting there vibing when nobody needs it πŸ™ˆ

  • gpuva β€” fields used by GPUVM to manage mappings pointing to this GEM object.

when DRM_GPUVM_IMMEDIATE_MODE is set, this list is protected by the mutex. otherwise, the list is protected by the GEMs dma_resv lock.

note that all entries in this list must agree on whether DRM_GPUVM_IMMEDIATE_MODE is set. everyone on the same page, or it's chaos 🌈
  • gpuva.list β€” list of GPUVM mappings attached to this GEM object.

drivers should lock list accesses with either the GEMs dma_resv lock (drm_gem_object.resv) or the drm_gem_object.gpuva.lock mutex. pick one, be consistent, slay.

  • gpuva.lock β€” lock protecting access to drm_gem_object.gpuva.list when DRM_GPUVM_IMMEDIATE_MODE is used.

only used when DRM_GPUVM_IMMEDIATE_MODE is set. it should be safe to take this mutex during the fence signalling path, so do not allocate memory while holding this lock. fr fr, do not. otherwise, the dma_resv lock should be used.

  • funcs β€” optional GEM object functions. if this is set, it will be used instead of the corresponding drm_driver GEM callbacks.

new drivers should use this. like, the new kids on the block are doing it this way, so πŸ‘‘

  • lru_node β€” list node in a drm_gem_lru.
  • lru β€” the current LRU list that the GEM object is on.

access to this field must be done with drm_device::gem_lru_mutex held. hold the lock or don't touch it, those are the options πŸ’…


πŸ¦‹ Description πŸ¦‹

this structure defines the generic parts for GEM buffer objects, which are mostly around handling mmap and userspace handles. the boring-but-essential plumbing, basically. and yes β€” buffer objects are often abbreviated to BO. now you know, and you can drop it in conversation like it's nothing 🧚


πŸ‘‘ SEE ALSO πŸ‘‘

kernel file ./include/drm/drm_gem.h and all these besties: enum drm_gem_object_status(9), struct drm_gem_object_funcs(9), struct drm_gem_lru(9), DRM_GEM_FOPS(9), DEFINE_DRM_GEM_FOPS(9), drm_gem_get_huge_mnt(9), drm_gem_object_get(9), drm_gem_object_put(9), drm_gem_object_is_shared_for_memory_stats(9), drm_gem_is_imported(9), drm_gem_gpuva_init(9), drm_gem_for_each_gpuvm_bo(9), drm_gem_for_each_gpuvm_bo_safe(9).


aaaand that's the page!! this lil masterpiece lives in ./include/drm and it's stamped October 2026 β€” so like, slightly future-dated and honestly? main character energy ⭐ go forth and hold your locks properly, bestie πŸ’–πŸŽ€

πŸ“¦ where this page comes from