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? 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@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel