[PATCH v2 02/37] drm/nouveau: handle pci/tegra drm_dev_{alloc, register} from common code

Danilo Krummrich dakr at redhat.com
Sat Jul 27 01:54:43 UTC 2024


On Fri, Jul 26, 2024 at 11:07:19PM +1000, Ben Skeggs wrote:
> On 27/7/24 01:41, Danilo Krummrich wrote:
> 
> > On Fri, Jul 26, 2024 at 02:27:53PM +1000, Ben Skeggs wrote:
> > > > > > > +
> > > > > > > +static struct nouveau_drm *
> > > > > > > +nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *parent,
> > > > > > > +		       struct nvkm_device *device)
> > > > > > > +{
> > > > > > > +	struct nouveau_drm *drm;
> > > > > > > +	int ret;
> > > > > > > +
> > > > > > > +	drm = kzalloc(sizeof(*drm), GFP_KERNEL);
> > > > > > > +	if (!drm)
> > > > > > > +		return ERR_PTR(-ENOMEM);
> > > > > > > +
> > > > > > > +	drm->dev = drm_dev_alloc(drm_driver, parent);
> > > > > > Since you're reworking this anyways, can we switch to devm_drm_dev_alloc()?
> > > > > > 
> > > > > > This also gets us rid of nouveau_drm_device_del().
> > > > > No, we can't.  I originally had this change as a cleanup patch in the series
> > > > > I posted implementing aux bus support.  However it turns out that in order
> > > > > to avoid breaking udev etc, we can't use the aux device as parent of the drm
> > > > Can you please expand a bit on what was breaking?
> > > Sorry, I meant to say PRIME, not udev.  The device selection logic ties the
> > > DRM device back to its sysfs node, and doesn't understand the auxiliary
> > > bus.  So, if nouveau were to use its auxiliary device as parent of the DRM
> > > device, PRIME breaks.
> > The Vulkan device selector stuff looks like it should mostly work.
> > 
> > However, I guess you refer to the loader stuff in Mesa that uses
> > drmGetDevices2() from libdrm? This stuff indeed whitelists busses it accepts to
> > report DRM device from:
> > 
> > 	{ "/pci", DRM_BUS_PCI },
> > 	{ "/usb", DRM_BUS_USB },
> > 	{ "/platform", DRM_BUS_PLATFORM },
> > 	{ "/spi", DRM_BUS_PLATFORM },
> > 	{ "/host1x", DRM_BUS_HOST1X },
> > 	{ "/virtio", DRM_BUS_VIRTIO },
> > 
> > Not a big deal to just add it for a new driver, but obviously we can't just do
> > this for an existing one.
> > 
> > > Fortunately it didn't turn out to be necessary, and we
> > > can happily probe() against the auxiliary device and still use the PCI
> > > device as the DRM device's parent.
> > At a first glance, I guess this should work. But, before we introduce
> > workarounds like this one and add even more complexity, I wonder what's the
> > benefit of doing this for Nouveau in the first place? I think we agreed to this
> > split for Nova, for the reasons discussed in [1].
> 
> Because, as I already mentioned in the cover letter for series I posted

For some reason your auxbus series never hit my inbox - fetched it from lore
now.

> implementing the auxiliary bus support, this brings immediate benefits to
> users, such as eliminating the long pauses on systems using prime whilst the
> entire GPU is woken up for some PCI query by userspace.

Sounds good, what is the difference we're talking about?

> 
> It also (finally) integrates Tegra in a reasonably clean fashion, and would
> allow the DRM-level suspend/resume code to be shared there too if someone
> were to implement the platform-level code for it.  That was not possible
> before.

I agree it's an advantage, but it's probably not too bad as it currently is
either.

> 
> > 
> > [1] https://lore.kernel.org/dri-devel/20240613170211.88779-1-bskeggs@nvidia.com/
> > 
> > > > > device and instead have to continue passing the pci/platform device as we do
> > > > > now.
> > > > > 
> > > > > Using devm_drm_dev_alloc() with the pci device as parent would tie the
> > > > > lifetime of the drm device to the pci device, which is owned by nvkm (after
> > > > How does this tie the lifetime of the drm device to the pci device? It's the
> > > > other way around, the drm device takes a reference of its parent (i.e. the pci
> > > > device).
> > > > 
> > > > I don't think there's anything wrong with that.
> > > My understanding is that devres will cleanup allocations when the driver
> > > detaches from the device.
> > Right, I think I took that too literally.
> > 
> > The lifetime of the DRM device (or more precisely one of its references) is
> > bound to the binding between the parent device and its corresponding driver.
> > 
> > But the lifetime of the parent device itself is bound to the DRM device.
> > 
> > So, yes this doesn't work, and proves the point that initializing the DRM device
> > with the parent's parent is just a workaround.
> 
> You're greatly overstating the "complexity" that's added here. It's a minor
> inconvenience that doesn't require much code at all to implement, and is
> essentially irrelevant outside of module load/unload.

When I was talking about complexity I was referring to the changes required to
integrate the auxbus stuff.

Having to call drm_dev_put() from .remove() by hand obviously isn't something
I'm overly concerned about in terms of complexity...

> 
> I agree it's not ideal, and userspace should gain auxiliary bus support
> before a new driver implements a similar architecture, but it's really not
> that big a deal.
> 
> > 
> > > With the auxdev changes, it's *NVKM* that's
> > > attached to the PCI device, not the DRM driver (which is attached to an
> > > auxiliary device instead).
> > > 
> > > This means that the devm_drm_dev_init_release() won't be called when the DRM
> > > driver detaches from its auxiliary device as it should, but when NVKM
> > > detaches from the PCI device, which isn't the most obvious and could lead to
> > > confusion.
> > > 
> > > It also entirely blows up in the split module case as nouveau.ko is unloaded
> > > already by the time NVKM detaches and drm_dev_put() gets called.
> > > 
> > > > > the auxdev series).  We could look at changing devm_drm_dev_alloc() of
> > > > > course, but I think that's best left until later.
> > > > I don't think that this is necessary.
> 



More information about the Nouveau mailing list