Preliminary udev support
Kevin Murphy
kemurphy.cmu at gmail.com
Sun Mar 10 06:47:22 PDT 2013
Hey,
So I was rereading my patch and remembered that I watch "graphics" for
framebuffer devices, and then when udev finds them, I check to see if it's
associated with a "drm" device:
+ /* We want to see if the framebuffer is associated with a
DRM-capable
+ * graphics card */
+ udev = udev_device_get_udev (dev);
+ cards = udev_enumerate_new (udev);
+ udev_enumerate_add_match_parent (cards,
udev_device_get_parent(dev));
+ udev_enumerate_add_match_subsystem (cards, "drm");
+
+ /* Udev assigns the "seat" tag to framebuffer and graphics
card
+ * devices; without matching this tag, we also end up with
the
+ * connected displays and the control interface to the card,
which
+ * we don't care about at the moment. */
+ udev_enumerate_add_match_tag (cards, "seat");
+ udev_enumerate_scan_devices (cards);
+
+ card_entry = udev_enumerate_get_list_entry (cards);
+
+ if (card_entry != NULL)
+ {
+ struct udev_device *card;
+ const char *card_path;
+
+
+ card_path = udev_list_entry_get_name (card_entry);
+ card = udev_device_new_from_syspath (udev, card_path);
+ card_node = udev_device_get_devnode(card);
+
+ if (card_node != NULL)
+ {
+ ply_trace ("Found DRM card %s for framebuffer %s",
card_node, fb_node);
+ card_node = strdup (card_node);
+ }
+ else
+ {
+ ply_trace ("This is strange, DRM card found with no
device node...");
+ ply_trace ("Continuing as if no card found");
+ }
[snip]
+ ply_renderer_t *renderer = NULL;
+
+ if (card_node != NULL)
+ {
+ renderer = ply_renderer_new (PLYMOUTH_PLUGIN_PATH
"renderers/drm.so",
+ card_node,
+
state->local_console_terminal);
+
+ if (renderer == NULL || !ply_renderer_open (renderer))
+ {
+ ply_trace ("Could not open renderer for %s, falling
back to framebuffer", card_node);
+ ply_renderer_free (renderer);
+ renderer = NULL;
+ }
+ }
+
+ if (renderer == NULL)
+ {
+ renderer = ply_renderer_new (PLYMOUTH_PLUGIN_PATH
"renderers/frame-buffer.so",
+ fb_node,
+
state->local_console_terminal);
+
+ if (renderer == NULL || !ply_renderer_open (renderer))
+ {
+ ply_trace ("Could not open renderer for %s,
aborting", fb_node);
+ ply_renderer_free (renderer);
+
+ if (card_node != NULL)
+ {
+ free (card_node);
+ }
+
+ return;
+ }
+ }
This way we get automatic fallback to the framebuffer if the user's system
doesn't have a drm-capable card. Do you think this is the right way to go
about it?
Thanks,
Kevin
On Fri, Mar 1, 2013 at 11:16 AM, Ray Strode <halfline at gmail.com> wrote:
> Hi,
>
> > + udev_enum = udev_enumerate_new (state->udev);
> > + udev_enumerate_add_match_subsystem (udev_enum, "graphics");
> > + udev_enumerate_add_match_tag(udev_enum, "seat");
> > + udev_enumerate_add_match_is_initialized(udev_enum);
> > + udev_enumerate_scan_devices (udev_enum);
> > +
> > + entries = udev_enumerate_get_list_entry (udev_enum);
> >
> > Unless I'm mistaken about how to drive the udev API, that should just
> simply
> > gather a list of all graphics devices with the "seat" tag that have been
> > fully initialized out of the list of all the devices that udev has
> detected
> > at that point; the ordering with framebuffer devices shouldn't come into
> > play.
> I believe the "graphics" subsystem corresponds to /sys/class/graphics
> which is the legacy fb device subsystem.
>
> > As far as I remember, udev events don't fire until the device is fully
> initialized.
>
> I remember looking into this a while back briefly. let me see if i
> can find the log... Ok it was actually from way back in october.
> Pasted below:
>
> <poettering> airlied: around?
> <poettering> ajax: or you?
> <poettering> got a question regarding fb and drm device nodes
> <poettering> do we get any guarantee about the order in which they
> show up in userspace?
> <poettering> the reason i am asking is this:
> <poettering> logind currently watches for fb device nodes to show up
> <poettering> it uses that as the main indicator for a seat being around
> <poettering> now, if the drm device node can show up after the fb node
> <poettering> then we'll inform gdm about the seat a bit too early
> <poettering> where it will start x at a time where drm is not yet
> available
> <poettering> now, what i am wondering about:
> <poettering> a) is there a guarantee that fb shows up after drm?
> <poettering> b) if not, can we get one?
> <poettering> c) if we can't get one, should i just forget about fb and
> always only watch drm?
> <poettering> d) and if c), are there any devices we stop supporting
> that way?
> <poettering> any other thoughts?
> <mjg59> poettering: Pretty sure that the drm device needs to exist for
> the KMS fb nodes to exist
> <mjg59> But that's not quite the same as the drm device *nodes* existing
> <mjg59> Let me look at that a bit more
> <poettering> to me only the order for the udev events matters really...
> <mjg59> poettering: This is the card node rather than any connectors,
> right?
> <mjg59> poettering: Looks like the card%d sysfs node will be created
> in drm_get_pci_dev()
> <mjg59> poettering: And I can't see any way the framebuffers could be
> created before that
> <halfline> well the real question is, at what point can we safely open
> /dev/dri/card0 and have it 1) exist and 2) not give any errors because
> we're trying to use it before things are fully initialized
> <ajax> mclasen: working on it, but afaik things should build in f18.
> <mclasen> ajax: ok, I'll try again
> <mclasen> ajax: also, did you see poetterings question ?
> <ajax> i did, i'm afraid i don't know that answer
> <ajax> my personal preference would be to not have fbdev emulation at
> all anymore really
> <ajax> but that probably doesn't help in the case of handing off the
> device from efifb to drm
> <mclasen> there seems to be a question about the readiness of
> /dev/dri/card0 too, though
> <ajax> that seems like a bad question though
> <mclasen> bad in the sense of ill-posed, or in the sense of 'you
> won't
> like the answer' ?
> <ajax> i guess i'm not sure why we'd get into a scenario where it
> could exist but be "not ready"
> <ajax> and if we could, why we wouldn't just consider that a drm bug.
> <mjg59> sysfs node is created before driver->load() is called
> <halfline> poettering,mjg59: looking at the code..drm_pci.c
> drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY) creates the card0
> device and then dev->driver->load(dev, ent->driver_data) is called
> after taht
> <halfline> mjg59: jinx
> <ajax> uh, okay, let's just move A below B then.
> <ajax> nothing in ->load should be looking at the chardev info i don't
> think
> <mjg59> Yeah that does seem like a generally bad idea
> <mjg59> But does anything open card0 before there are any connectors?
> <halfline> well anyway ret = intel_fbdev_init(dev); is called after
> the whole lot
> <halfline> so what poettering is doing should be fine
> <halfline> assuming the other drivers are okay
> <ajax> mjg59: if we emit udev plug events when the connectors appear,
> then who cares?
> <ajax> just uevents i guess
> <halfline> well it's the difference between things occasionally
> failing and things not occasionally failing...
> <ajax> no, it's the difference between the opener being correct and
> not being correct.
> <halfline> heh
> <ajax> connectors can already come and go
> <ajax> so you ought already to be looking for that
> <halfline> ought but not
> <halfline> (for plymouth anyway)
> <ajax> yeah, i didn't say we _are_ correct, just that the way forward
> is, er, straightforward
> <ajax> but in the static connector list case i think those all exist
> by the time ->load is done
> <mclasen> makes sense; if there are events for connectors appearing,
> we should deal with them
> <ajax> so simply not exposing the chardev before initialization seems
> like it'll paper over that ordering issue
> <mjg59> ajax: As long as ->load() doesn't create any connector objects
> <mjg59> Because that depends on the sysfs parent already existing
> <ajax> clearly i'm missing something here
> <halfline> well poettering is just waiting for the /dev/fb device to
> show up which should be fine paper
> <mjg59> ajax: drm_get_minor() is currently called before the driver
> ->load() method. This guarantees that there's a sysfs object for the
> card, and any connectors will use that as their parent. You suggested
> moving it to after ->load(). That's fine as long as nothing tries to
> create connectors in the load() method.
> <ajax> remind me which cog in this hell machine is responsible for
> making the /dev node exist
> <mjg59> ajax: udev will create the device node some amount of time
> after the sysfs object is created
> <mjg59> ajax: But depending on it to not do that until after load() is racy
> <mjg59> It could happen at any time after the card sysfs object is created
> <ajax> this seems like a class of races that others have to have faced
> <mjg59> I blame drm's awful abstractions
> <mjg59> Anyway, the device will normally be created during boot, so
> the only thing that could really be racing with it is plymouth
> <mjg59> Lennart's stuff is waiting for framebuffer creation, which
> works as a useful extra sequencing point
> <halfline> cosimoc's machine boots so fast that plymouth isn't in the
> picture and he gets software rendering for gnome-shell
> <halfline> well once in a while
> <halfline> because pam_systemd runs before the /dev/dri/card0 exists
> <halfline> and so it doesn't given gdm access rights to it
> <halfline> so we're going to make GDM not start an X server until
> systemd gives the go ahead
> <halfline> and systemd gives the go ahead when /dev/fb0 shows up
> <halfline> so we should be good
> <poettering> mjg59: so you say fb is a good sync point?
> <poettering> if that's the case then i am happy
> <poettering> and if fb is dropped one day we can reinvestigate the
> whole issue
> <poettering> all i am aksing for basically is that by the time fb was
> handled by userspace all initialization that X might need of the
> drivers is complete
> <halfline> poettering: so i checked intel, radeon, and nouveau
> earlier, and they all did fbdev initialization at the end
> <halfline> so i think you're safe
> <mjg59> poettering: "Good" may be overstating
> <mjg59> But I suspect it'd work
> <notting> does gnome-tweak-tool tweak non-dconf settings?
> <kay> mjg59: udev does not create any device node since quite some
> time, it's all in the kernel, /dev is at the same time as /sys
> <mjg59> kay: Yeah ok I need to pay more attention
> <kay> mjg59: udev today does only symlinks and permissions at event
> time. devtmpfs does all the nodes stuff. udev does not even have the
> code anymore to call mknod() in the hotplug handler ...
> <airlied> please don'
> <airlied> please don'y rely on /dev/fb nodes
> <airlied> its not good
> <airlied> all the other stuff is protected by drm_global_muetx
> <airlied> so if you open before we area ready it'll block
> <airlied> since drm_stub_open also takes the drm_global_mutex
> <airlied> we don't want to require drm to provide fb emulation for
> ever
> <airlied> poettering, halfline, ajax, mjg59 ^
> <halfline> airlied: hmm, pretty sure we've had bugs plymouth bugs in
> the past where if we open /dev/dri/card0 too early it's there but
> fails
> <halfline> anyway the problem this time around was it not being there
> at all
> <halfline> so pam_systemd couldn't trigger ACL changes to it
> <airlied> halfline: yeah there was problems years ago
> <airlied> its almsot like we fixed them :-)
> <airlied> though I'm trying to remember when we did
> <airlied> b64c115eb22516ecd187c74ad6de3f1693f1dc7b 2 years ago
> <airlied> I've had alternate patches to move stuff around but I never
> trusted them enough
> <airlied> and I didn't think open was too contended
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/plymouth/attachments/20130310/38f6d5bb/attachment-0001.html>
More information about the plymouth
mailing list