On Mon Sep 28, 2026 at 3:37 PM CEST, Thomas Hellström wrote:
> It doesn't have to in a model where all users are removed before the
> drm device is freed. Following your argument, shouldn't that drm_device
> reference should also be accompanied by a module reference? Except that
> will block rmmod?
Yes, if we establish that a DRM device must outlive a GPUVM (which by convention
we implicitly do by storing a pointer) then you don't need a reference count.
However, there's nothing that ensures the caller sticks to the convention. And
given that the DRM device is reference counted already, taking the reference
count is the correct thing to do.
(As a side note, in Rust you can actually model and enforce this lifetime
relationship at compile time without a reference count. You can even establish
more granular lifetime relationships. For instance, you could have:
struct GpuVm<'a> {
drm: &'a drm::Device<Registered>,
}
and establish that a GPUVM can only ever live as long as the DRM device is
registered and therefore implicitly also establish that the GPUVM can't outlive
driver unbind, as a DRM device can't be registered beyond driver unbind and
hence the lifetime 'a is guaranteed to end before driver unbind.
In C you can only establish this by convention, and at least take the reference
count.)
The module reference seems orthogonal though, GPUVM is not actively emitting
calls into anything (unlike a workqueue for instance), it's a passive data
structure. So, there's no need for any defensive measure AFAICS.
> Without knowing for sure, I think this was the route taken with
> hotplugging.
Sure, both approaches are there to cover hotplugging. Almost all class device
implementations have to consider hotplugging as it is depends on the bus the
physical device sits on whether hot(un)plug can happen.
> But isn't essentially what you describe a design where we release all
> dma_buf, file- and drm_pagemap references of struct drm_device at
> module_unload time. That would replace their references with SRCU
> protecting the drm_device pointer, falling back to a stub behaviour
> when unbind has been called. So the "Can I access hardware?" would be
> replaced by a "Can I access the DRM device?".
I think the question is not "Can I access the DRM device?", the question is "Is
the DRM device still registered?", or IOW, "Is the DRM device still backed by a
driver?".
There's a bounded lifetime when a driver is allowed to operated a device, which
is between probe and remove. This is (typically) the same scope as the class
device (e.g. DRM) is registered.
After the driver is unbound from it's (physical) bus device, there's no value
anymore in letting the driver operate the class device (which is exactly what
register() / unregister() describes) in the first place.
There's nothing hardware specific left at this point, so it is not a driver job
anymore; the lifetime decoupling can be at subsystem / component level (e.g. DMA
fence).
> That's an interesting idea, but would probably need careful work so
> fence waits etc. doesn't block the SRCU read sections. And ofc to avoid
> user-space regressing.
For the fence waits specifically, this can (or should) never happen. Driver
fences must be signaled on driver unbind. The hardware is gone at this point,
there's nothing left that could signal them otherwise.
> FWIW, IIRC that SRCU is only strictly needed when non-driver code
> (pagemap, files and dma-buf) drops the last drm_device reference
> without having a module reference. And there is no such code (yet)
> AFAIK, so I can drop that patch to when we think it's necessary and we
> have other driver buy-ins.
I think those components should do the lifetime decoupling work instead. Once
the driver is unbound, none of the driver callbacks are "special" anymore as
there's nothing hardware specific left at this point.