STRUCT DRM_FILE(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ¦‹ struct drm_file(9) β€” your fave Kernel API Manual, bestie πŸ¦‹

okay so before we even get into it β€” hi, this is the page for struct drm_file from the Kernel API Manual, and yes we are gonna read the whole thing together, no skimming, i got you πŸ’–


✨ NAME ✨

struct drm_file β€” the DRM file private data. that's it, that's the vibe: it's the per-open-file little private stash the DRM subsystem keeps for you πŸŽ€


🌸 SYNOPSIS 🌸

here's the whole struct, laid out, untouched, exactly as it lives β€” i'm literally not touching a single character of this, periodt:

struct drm_file {
    bool authenticated;
    bool stereo_allowed;
    bool universal_planes;
    bool atomic;
    bool aspect_ratio_allowed;
    bool writeback_connectors;
    bool plane_color_pipeline;
    bool was_master;
    bool is_master;
    bool supports_virtualized_cursor_plane;
    struct drm_master *master;
    spinlock_t master_lookup_lock;
    struct pid *pid;
    u64 client_id;
    drm_magic_t magic;
    struct list_head lhead;
    struct drm_minor *minor;
    struct idr object_idr;
    spinlock_t table_lock;
    struct xarray syncobj_xa;
    struct file *filp;
    void *driver_priv;
    struct list_head fbs;
    struct mutex fbs_lock;
    struct list_head blobs;
    wait_queue_head_t event_wait;
    struct list_head pending_event_list;
    struct list_head event_list;
    int event_space;
    struct mutex event_read_lock;
    struct drm_prime_file_private prime;
    const char *client_name;
    struct mutex client_name_lock;
    struct dentry *debugfs_client;
};

πŸ‘‘ MEMBERS πŸ‘‘

okay this is the long part and honestly the main character energy of the whole page. buckle up, we're going field by field, and nothing gets skipped πŸ’…

  • authenticated β€” tells you whether the client is allowed to submit rendering at all. for legacy nodes this means it must be authenticated, no exceptions. also: see the :ref:section on primary nodes and authentication <drm_primary_node>.
  • stereo_allowed β€” True when the client has asked us to expose stereo 3D mode flags. cute, they want depth perception 🌈
  • universal_planes β€” True if the client understands CRTC primary planes and cursor planes in the plane list. it gets set automatically when atomic is set β€” like a little freebie, iykyk.
  • atomic β€” True if the client understands atomic properties. slay.
  • aspect_ratio_allowed β€” True, if the client can handle picture aspect ratios and has requested to pass this information along with the mode. πŸ–ΌοΈ
  • writeback_connectors β€” True if client understands writeback connectors.
  • plane_color_pipeline β€” True if client understands plane color pipelines.
  • was_master β€” this client has, or had, master capability. protected by struct drm_device.master_mutex.

the whole point: it's used to ensure that CAP_SYS_ADMIN is not enforced, if the client is or was master in the past. so like, it's the "we used to be somebody" flag 😭

  • is_master β€” this client is the creator of master. protected by struct drm_device.master_mutex.

also see the :ref:section on primary nodes and authentication <drm_primary_node>.

  • supports_virtualized_cursor_plane β€” this client is capable of handling the cursor plane with the restrictions imposed on it by the virtualized drivers.

this implies that the cursor plane has to behave like a cursor, i.e. track cursor movement. it also requires setting of the hotspot properties by the client on the cursor plane. πŸ–±οΈ

  • master β€” the master this node is currently associated with. protected by struct drm_device.master_mutex, and serialized by master_lookup_lock.

only relevant if drm_is_primary_client returns true. note that this only matches drm_device.master if the master is the currently active one.

to update master, both drm_device.master_mutex and master_lookup_lock need to be held, therefore holding either of them is safe and enough for the read side.

when dereferencing this pointer, either hold struct drm_device.master_mutex for the duration of the pointer's use, or use drm_file_get_master if struct drm_device.master_mutex is not currently held and there is no other need to hold it. this prevents master from being freed during use. 🫢

also see authentication and is_master and the :ref:section on primary nodes and authentication <drm_primary_node>.

  • master_lookup_lock β€” serializes master.
  • pid β€” the process that is using this file.

⚠️ must only be dereferenced under a rcu_read_lock or equivalent.

updates are guarded with dev->filelist_mutex and reference must be dropped after a RCU grace period to accommodate lockless readers. no cap, this one's strict.

  • client_id β€” a unique id for fdinfo. πŸ’…
  • magic β€” authentication magic, see authenticated.
  • lhead β€” list of all open files of a DRM device, linked into drm_device.filelist. protected by drm_device.filelist_mutex.
  • minor β€” struct drm_minor for this file.
  • object_idr β€” mapping of mm object handles to object pointers. used by the GEM subsystem. protected by table_lock.

note that allocated entries might be NULL as a transient state when creating or deleting a handle. πŸ™ˆ

  • table_lock β€” protects object_idr.
  • syncobj_xa β€” mapping of sync object handles to object pointers.
  • filp β€” pointer to the core file structure.
  • driver_priv β€” optional pointer for driver private data. can be allocated in drm_driver.open and should be freed in drm_driver.postclose. (allocate in open, free in postclose β€” that's the whole contract bestie, don't get it twisted πŸŽ€)
  • fbs β€” list of struct drm_framebuffer associated with this file, using the drm_framebuffer.filp_head entry.

protected by fbs_lock. note that the fbs list holds a reference on the framebuffer object to prevent it from untimely disappearing. literally holding on for dear life 😭

  • fbs_lock β€” protects fbs.
  • blobs β€” user-created blob properties; this retains a reference on the property.

protected by drm_mode_config.blob_lock;

  • event_wait β€” waitqueue for new events added to event_list.
  • pending_event_list β€” list of pending struct drm_pending_event, used to clean up pending events in case this file gets closed before the event is signalled. uses the drm_pending_event.pending_link entry.

protect by drm_device.event_lock.

  • event_list β€” list of struct drm_pending_event, ready for delivery to userspace through drm_read. uses the drm_pending_event.link entry.

protect by drm_device.event_lock.

  • event_space β€” available event space to prevent userspace from exhausting kernel memory. currently limited to the fairly arbitrary value of 4KB. (yes, "fairly arbitrary" is the official wording and honestly? iconic.)
  • event_read_lock β€” serializes drm_read.
  • prime β€” per-file buffer caches used by the PRIME buffer sharing code.
  • client_name β€” userspace-provided name; useful for accounting and debugging. πŸ“
  • client_name_lock β€” protects client_name.
  • debugfs_client β€” debugfs directory for each client under a drm node.

πŸ’œ DESCRIPTION πŸ’œ

this structure tracks DRM state per open file descriptor. that's the whole thing! it's the little per-fd brain cell 🧚


🌟 SEE ALSO 🌟


πŸ’€ real talk: none of these locks are decorative. if the page says hold master_lookup_lock or drm_device.master_mutex, hold them β€” that's how you avoid a use-after-free situation that would be genuinely tragic.

and that's the page!! this one came out of ./include/drm, dated October 2026, and it's literally titled struct drm_file(9) β€” go off, kernel docs, you ate πŸ«Άβœ¨πŸŽ€

πŸ“¦ where this page comes from