Should drm's modetest work when an X server is running?

David Herrmann dh.herrmann at gmail.com
Mon Mar 3 16:07:04 PST 2014


Hi

On Tue, Mar 4, 2014 at 12:53 AM, Daniel Kurtz <djkurtz at chromium.org> wrote:
> Dear dri developers,
>
> Should libdrm's modetest work when an X server is running?
> Should drmOpen(name, NULL) succeed when the drm device is already open?
> Is "name" passed to drmOpen() the "drm" name returned by drmGetVersion()?
> Or, is it the the kernel driver/module name?

Don't use drmOpen(). Seriously, there's no reason for it. There is
open(), use it, don't bother with all that legacy. And if legacy code
uses drmOpen(), it's really easy to fix it to just use plain open().
The wrappers made sense when we had UMS or maybe with xf86-video
drivers. But for anything else, just use udev to enumerate the
drm-devices and then open() the node. If you don't like udev, iterate
over /dev/dri/.

Regarding modetest: yes, it's supposed to work while an xserver is
running, as long as you run it on a separate VT. Furthermore, the
drivers obviously need to be KMS drivers for both, otherwise behavior
is undefined, anyway. However, drmOpen() is known to fail in such
situations, so my recommendation is to fix modetest. I doubt that we
will revert kernel changes for /proc just to make drmOpen() work in
multi-gfx systems again.

Thanks
David

> tl;dr
>
> Over the past couple of days I have been trying to get "modetest" from
> the libdrm repository to run on my exynos based ARM chromebook.
>
> With an X server running, "modetest" fails like this:
> # modetest
> trying to open device 'exynos'...failed.
> no device found.
>
> Without an X server, "modetest" succeeds:
> # modetest
> trying to open device 'exynos'...success.
> Encoders:
> id crtc type possible crtcs possible clones
> 15 5 TMDS 0x00000001 0x00000003
> 18 0 TMDS 0x00000002 0x00000003
> ...
>
> So, why is modetest failing when the X server is running?
>
> If we don't specify a module (-M) or device (-D) on the command line,
> modetest searches through a hard coded list of "modules":
> const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx",
> "omapdrm", "exynos", "tilcdc", "msm" };
>
> For each module, it tries to open it with drmOpen:
>   dev.fd = drmOpen(modules[i], device);
>
> When checking for "exynos", this becomes...
> drmOpen("exynos", NULL), which first calls
>   -> drmAvailable()
>     -> drmOpenMinor(0, 1, DRM_NODE_RENDER)
>       -> drmOpenDevice(makedev(DRM_MAJOR, 0), 0, DRM_NODE_RENDER);
>         -> this eventually calls open("/dev/dri/card0"), which returns
> a valid fd.
> drmOpen("exynos", NULL) then calls
>   -> drmOpenByName("exynos")
>      -> /* Redundant drmAvailable() check */
>      -> for i=0:15:
>        -> drmOpenMinor(i, 1, DRM_NODE_RENDER);
>          -> if it returns a valid fd: version = drmGetVersion(fd)
>            -> if version->name == "exynos": id = drmGetBusid(fd);
>              -> if id != NULL && id != "":  Success! return the fd
>
> In other words, drmOpen("exynos", NULL) succeeds if any of
> "/dev/dri/card*" can be opened, it drmGetVersion() succeeds and
> returns version->name == "exynos", and if drmGetBusid(fd) is NULL or
> "".  In other words, it opens the first minor number that matches the
> DRM "version" name and doesn't already have a busid assigned (ie, the
> first matching minor that isn't in use).
>
> So, this explains why modetest works when my X server is stopped.  The
> drm name matches, and there is no busid, so drmOpen() happily returns
> an fd.
>
> But on a system with intel graphics (i915), modetest works even with
> the X server running, why?
> It turns out that there is another chunk of code in drmOpenByName(),
> that is linux only, and implements "Backward-compatibility /proc
> support".  In a loop it reads "/proc/dri/*/name" and matches the first
> field against the "name" passed in to drmOpenByName().  If this
> matches:
>   * if there are 3 fields, the 3rd field is passed to drmOpenByBusid()
>   * if there were only 2 fields, the 2nd field is parsed as a long and
> passed as the dev parameter to drmOpenDevice().
>
> "On my intel machine, the first field is "i915", the same name
> returned as the version->name for drmGetVersion(), so we end up doing
> something like drmOpenByBusid("pci:0000:00:02.0), which succeeds
> because that matches what is returned by drmGetBusid().
>
> $ cat /proc/dri/0/name
> i915 0000:00:02.0 pci:0000:00:02.0
>
> But, for exynos, the the driver name is actually "exynos-drm", so the
> check fails, and drmOpen("exynos", NULL) fails.
>
> # cat /proc/dri/0/name
> exynos-drm exynos-drm platform:exynos-drm:00
>
> I'm obviously using an older kernel.  From the kernel git log, I see
> that danvet recently removed the entire proc interface.  So, does that
> mean that on up to date kernels modetest (and the other libdrm tests)
> will now also fail for intel if X is running (since the proc back door
> is no longer available)?
> Is this "working as intended"?
>
> -Dan
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list