Documentation/process/botching-up-ioctls.rst
Source file repositories/reference/linux-study-clean/Documentation/process/botching-up-ioctls.rst
File Facts
- System
- Linux kernel
- Corpus path
Documentation/process/botching-up-ioctls.rst- Extension
.rst- Size
- 11574 bytes
- Lines
- 226
- Domain
- Support Tooling And Documentation
- Bucket
- Documentation
- Inferred role
- Support Tooling And Documentation: documentation
- Status
- atlas-only
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
- No top-level syscall, struct, function, initcall, or export declaration detected by the generator.
Annotated Snippet
=================================
(How to avoid) Botching up ioctls
=================================
From: https://blog.ffwll.ch/2013/11/botching-up-ioctls.html
By: Daniel Vetter, Copyright © 2013 Intel Corporation
One clear insight kernel graphics hackers gained in the past few years is that
trying to come up with a unified interface to manage the execution units and
memory on completely different GPUs is a futile effort. So nowadays every
driver has its own set of ioctls to allocate memory and submit work to the GPU.
Which is nice, since there's no more insanity in the form of fake-generic, but
actually only used once interfaces. But the clear downside is that there's much
more potential to screw things up.
To avoid repeating all the same mistakes again I've written up some of the
lessons learned while botching the job for the drm/i915 driver. Most of these
only cover technicalities and not the big-picture issues like what the command
submission ioctl exactly should look like. Learning these lessons is probably
something every GPU driver has to do on its own.
Prerequisites
-------------
First the prerequisites. Without these you have already failed, because you
will need to add a 32-bit compat layer:
* Only use fixed sized integers. To avoid conflicts with typedefs in userspace
the kernel has special types like __u32, __s64. Use them.
* Align everything to the natural size and use explicit padding. 32-bit
platforms don't necessarily align 64-bit values to 64-bit boundaries, but
64-bit platforms do. So we always need padding to the natural size to get
this right.
* Pad the entire struct to a multiple of 64-bits if the structure contains
64-bit types - the structure size will otherwise differ on 32-bit versus
64-bit. Having a different structure size hurts when passing arrays of
structures to the kernel, or if the kernel checks the structure size, which
e.g. the drm core does.
* Pointers are __u64, cast from/to a uintptr_t on the userspace side and
from/to a void __user * in the kernel. Try really hard not to delay this
conversion or worse, fiddle the raw __u64 through your code since that
diminishes the checking tools like sparse can provide. The macro
u64_to_user_ptr can be used in the kernel to avoid warnings about integers
and pointers of different sizes.
Basics
------
With the joys of writing a compat layer avoided we can take a look at the basic
fumbles. Neglecting these will make backward and forward compatibility a real
pain. And since getting things wrong on the first attempt is guaranteed you
will have a second iteration or at least an extension for any given interface.
* Have a clear way for userspace to figure out whether your new ioctl or ioctl
extension is supported on a given kernel. If you can't rely on old kernels
rejecting the new flags/modes or ioctls (since doing that was botched in the
past) then you need a driver feature flag or revision number somewhere.
* Have a plan for extending ioctls with new flags or new fields at the end of
the structure. The drm core checks the passed-in size for each ioctl call
and zero-extends any mismatches between kernel and userspace. That helps,
but isn't a complete solution since newer userspace on older kernels won't
notice that the newly added fields at the end get ignored. So this still
needs a new driver feature flags.
Annotation
- Atlas domain: Support Tooling And Documentation / Documentation.
- Implementation status: atlas-only.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.