FILE OPERATIONS(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… FILE OPERATIONS πŸ’…

okay bestie, welcome to file operations β€” section 9 of the Kernel API Manual β€” and no, that's not a typo, we're in kernel-land now. grab a strawberry drink πŸ“ and let's get into it.

So. Drivers must define the file operations structure that forms the DRM userspace API entry point, even though most of those operations are actually implemented in the DRM core. Yeah, the core does the heavy lifting, but you still gotta show up and define the struct. πŸ’β€β™€οΈ

The resulting struct file_operations must be stored in the drm_driver.fops field.

The mandatory functions are drm_open, drm_read, drm_ioctl and drm_compat_ioctl if CONFIG_COMPAT is enabled. Note that drm_compat_ioctl will be NULL if CONFIG_COMPAT=n, so there's no need to sprinkle #ifdef into the code. slay, no preprocessor crimes today 🧚

Drivers which implement private ioctls that require 32/64 bit compatibility support must provide their own file_operations.compat_ioctl handler that processes private ioctls and calls drm_compat_ioctl for core ioctls.


In addition drm_read and drm_poll provide support for DRM events. DRM events are a generic and extensible means to send asynchronous events to userspace through the file descriptor. They are used to send vblank event and page flip completions by the KMS API. πŸ’« But drivers can also use it for their own needs, e.g. to signal completion of rendering.

For the driver-side event interface, see drm_event_reserve_init and drm_send_event as the main starting points. 🫢

The memory mapping implementation will vary depending on how the driver manages memory. For GEM-based drivers this is drm_gem_mmap.

heads up: no other file operations are supported by the DRM userspace API. that's the whole list, don't get creative πŸ’€

Overall the following is an example file_operations structure:

        static const example_drm_fops = {
                .owner = THIS_MODULE,
                .open = drm_open,
                .release = drm_release,
                .unlocked_ioctl = drm_ioctl,
                .compat_ioctl = drm_compat_ioctl, // NULL if CONFIG_COMPAT=n
                .poll = drm_poll,
                .read = drm_read,
                .mmap = drm_gem_mmap,
        };

For plain GEM based drivers there is the DEFINE_DRM_GEM_FOPS macro, and for DMA based drivers there is the DEFINE_DRM_GEM_DMA_FOPS macro to make this simpler. macros that save you typing are literally my love language ✨

The driver's file_operations must be stored in drm_driver.fops. (yeah, i said it twice, it's that important πŸ’…)

For driver-private IOCTL handling see the more detailed discussion in :ref:IOCTL support in the userland interfaces chapter<drm_driver_ioctl>`` .


✨ SEE ALSO ✨

the whole friend group, no cap πŸ‘‘:


okay that's the whole page, go be iconic with your file_operations πŸŒˆπŸ’– this one lives over in ./drivers/gpu/drm, it's dated October 2026, and it came straight out of the Kernel API Manual. mwah, study safe πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from