<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 22, 2018 at 11:01 PM, Peter Hutterer <span dir="ltr"><<a href="mailto:peter.hutterer@who-t.net" target="_blank">peter.hutterer@who-t.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Sun, Apr 22, 2018 at 06:07:36PM +0000, Friedrich, Eugen (ADITG/ESB) wrote:<br>
> Hi, sorry for late replay<br>
> <br>
> Best regards<br>
> <br>
> Eugen Friedrich<br>
> Engineering Software Base (ADITG/ESB)<br>
> <br>
> Tel. +49 5121 49 6921<br>
> > -----Original Message-----<br>
> > From: Peter Hutterer [mailto:<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.<wbr>net</a>]<br>
> > Sent: Freitag, 6. April 2018 04:29<br>
> > To: Friedrich, Eugen (ADITG/ESB)<br>
> > Cc: Matt Hoosier; Pekka Paalanen; wayland mailing list<br>
> > Subject: Re: [PATCH libinput 0/1] Initialization race against udev<br>
> > <br>
> > On Thu, Apr 05, 2018 at 01:20:51PM +0000, Friedrich, Eugen (ADITG/ESB) wrote:<br>
> > > Hi Peter<br>
> > ><br>
> > > Best regards<br>
> > ><br>
> > > Eugen Friedrich<br>
> > > Engineering Software Base (ADITG/ESB)<br>
> > ><br>
> > > Tel. +49 5121 49 6921<br>
> > ><br>
> > > > -----Original Message-----<br>
> > > > From: wayland-devel [mailto:<a href="mailto:wayland-devel-">wayland-devel-</a><br>
> > > > <a href="mailto:bounces@lists.freedesktop.org">bounces@lists.freedesktop.org</a>] On Behalf Of Peter Hutterer<br>
> > > > Sent: Donnerstag, 5. April 2018 06:27<br>
> > > > To: Matt Hoosier<br>
> > > > Cc: Pekka Paalanen; wayland mailing list<br>
> > > > Subject: Re: [PATCH libinput 0/1] Initialization race against udev<br>
> > > ><br>
> > > > On Wed, Apr 04, 2018 at 09:04:32AM -0500, Matt Hoosier wrote:<br>
> > > > > I encounter another "bad" behavior related to multiple firings of the UDev<br>
> > > > > 'add' event for a given input node.<br>
> > > > ><br>
> > > > > Typically on modest embedded systems, you do not want to run the<br>
> > > > exhaustive<br>
> > > > > 'udevadm trigger' during the main booting sequence. That causes hundreds<br>
> > > > or<br>
> > > > > thousands of UDev nodes to be crawled and processed by udevd all during<br>
> > > > the<br>
> > > > > first moments of userspace. These overall bulk of these nodes are pretty<br>
> > > > > much irrelevant to the use-case of the device. The time spent processing<br>
> > > > > these non-essential /sys devices can easily slow down the device's<br>
> > > > progress<br>
> > > > > toward starting a UI with basic touch support and loading drivers for the<br>
> > > > > handful of essential peripherals by 10 or 15 seconds.<br>
> > > > ><br>
> > > > > Instead, it works better to manually command the same UDev coldplugging<br>
> > > > > that would have been done by 'udevadm trigger', but for a very small<br>
> > > > > hand-picked set of devices rather than everything in /sys/devices. The time<br>
> > > > > savings are large. Of course, for completeness you do eventually have to<br>
> > > > > run 'udevadm trigger' so that the full set of hardware and kernel software<br>
> > > > > features are activated, but that can wait until after the main KPIs are<br>
> > > > > achieved.<br>
> > > > ><br>
> > > > > This scheme generally works just fine. Manually stimulating udevd to<br>
> > > > > coldplug the specific devices you need keeps everything general:<br>
> > > > > applications that find their hardware with UDev (such as with libinput or<br>
> > > > > Weston's DRM backend) all get to rely on their usual well-tested<br>
> > > > codepaths.<br>
> > > > ><br>
> > > > > But there is a snag: if a device like /dev/input/event0 has been<br>
> > > > > coldplugged once with the hands-on technique, then all the daemons that<br>
> > > > > care about it have already seen one UDev ACTION=add event for it. When<br>
> > > > the<br>
> > > > > late-running 'udevadm trigger' does its exhaustive sweep across<br>
> > > > > /sys/devices, this will cause a second ACTION=add event to be triggered<br>
> > > > for<br>
> > > > > /dev/input/event0. Currently (well, with libinput 1.1.1) this causes<br>
> > > > > libinput -- and consequently Weston -- to open a second filedescriptor<br>
> > > > > against /dev/input/event0, so that all input events are received in<br>
> > > > > duplicate. That confuses the compositor's and applications' input event<br>
> > > > > handling.<br>
> > > > ><br>
> > > > > Would it be tolerable to put a patch into either libinput or Weston to<br>
> > > > > guard against double-opening the same input device? I realize that the<br>
> > > > > scheme outlined above is probably technically in violation of the expected<br>
> > > > > UDev initialization scheme, but I'm not aware of any way to suppress<br>
> > > > udevd<br>
> > > > > from broadcasting the 'add' action to all udev clients even though the<br>
> > > > > device has already been coldplugged once. It seems to me at least plausible<br>
> > > > > that the Weston stack would benefit from guarding against getting into this<br>
> > > > > bad state from receiving unexpected UDev events.<br>
> > > ><br>
> > > ><br>
> > > > I don't think a weston patch is likely to help you here since libinput's<br>
> > > > udev handling is independent of weston. but tbh, I'd rather not do this in<br>
> > > > libinput either. as you write, you're not really behaving like udev is<br>
> > > > supposed to and once we start having to deal with that the floodgates are<br>
> > > > open for weird patches. The code for this should be relatively<br>
> > > > self-contained and easy-enough to maintain, please maintain that as a<br>
> > > > distribution-specific patch.<br>
> > ><br>
> > > [EF] but as I can see there is a race condition which can always occur in<br>
> > > any system if device will be added to the system after installation of the<br>
> > > udev monitor and before initializing already coldplugged devices.<br>
> > > Can we really just accept this and hope it will never happen? Or I'm missing<br>
> > something?<br>
> > <br>
> > yeah, that race condition could occur but the chances are ... very slim.<br>
> > By the time libinput starts up, all the built-in devices are already<br>
> > connected and what are the chances that you plug in a USB device at that<br>
> > precise ms?<br>
> > <br>
> > Now, if you feel like writing patches for this you're welcome if they're not<br>
> > too intrusive but one problem with those patches is likely that they're<br>
> > almost impossible to test for the udev backend (other than by manually<br>
> > pausing libinput at the right time and hoping). So unless you can come up<br>
> > with a solution for that too, I'd rather take my chances with the race<br>
> > condition than maintaining untestable code that may not work correctly in<br>
> > the one case where we need it :)<br>
> <br>
> [ef] I agree about the point of not testable code.<br>
> My plan was to modify the evdev_udev_handler function and add check <br>
> in the "add" action to verify if the device is already added.<br>
> For testing we can just trigger the "add" action manually to execute new<br>
> code path, should be exactly same as problem I would like to solve and<br>
> it should also solve the original point mentioned by Matt.<br>
> Can you agree on this?<br>
<br>
</div></div>you'll need to figure out a way how to automate this with the test suite.<br>
Should be possible running udevadm commands within the test but anything<br>
that requires a real "manually" isn't going to survive for long. Humans are<br>
lazy, machine testing is the way to go :)<br></blockquote><div><br></div><div>If your question was aimed at me: I don't have a very strong opinion about tactics for this. My only goal was to make Weston resilient against duplicate UDev "device added" announcements. Whatever layer works best to short-circuit the construction of a second instance of touch-processing machinery is fine for me.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
> > > > especially if you're really still on 1.1.1 which came out in 2015...<br>
> > > ><br>
> > > > As for how it would work: device_added in src/udev-seat.c, you can get to<br>
> > > > the libinput_seat which has the device list (they're all struct<br>
> > > > evdev_device). You can get the fd from that and stat() it for the st_rdev<br>
> > > > or, simpler, add a field and strdup the device node into that struct and<br>
> > > > compare that.<br>
> > > ><br>
> > > > On second thought: I'm not sure how exactly you're handling the<br>
> > > > cold-plugging but is there a way you can add a udev rule that assigns<br>
> > > > LIBINPUT_IGNORE_DEVICE=1 to all input devices already handled?<br>
> > ><br>
> > > [EF] Could not get the exact idea! Should we set the attribute<br>
> > > LIBINPUT_IGNORE_DEVICE from the libinput code?<br>
> > <br>
> > Above you wrote:<br>
> > > Manually stimulating udevd to<br>
> > > coldplug the specific devices you need keeps everything general:<br>
> > <br>
> > I don't actually know what you mean by this, so I'm not sure what the udev<br>
> > behaviour is in this case. But if you're holding back the<br>
> > trigger anyway is that you can do whatever you do for the devices, then drop<br>
> > a udev rule in that sets LIBINPUT_IGNORE_DEVICE, then you run the udevadm<br>
> > trigger. Any device that is now handled by udev will have that property<br>
> > assigned and will thus be ignored, including all your duplicates.<br>
> > <br>
> > > Additional idea would be to use USEC_INITIALIZED time as unique identifier<br>
> > > in one boot cycle.<br>
> > <br>
> > Can you expand on how you think this would work?<br>
> <br>
> [ef] to find out if the device is already added or not I need some unique identifier<br>
> of the device, I thought to add the USEC_INITIALIZED member to each device<br>
> and if there is a device with the same USEC_INITIALIZED we will skip it. <br>
<br>
</div></div>oh right. Nice idea, seems a bit roundabout though :)<br>
The syspath of a device should be unique since the kernel keeps incrementing<br>
the inputXXXX number. We already use that for some conflict resolution<br>
between devices and it's readily accessible, so that should work well enough.<br>
<br>
Cheers,<br>
   Peter<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
> <br>
> > <br>
> > Cheers,<br>
> >    Peter<br>
> > <br>
> > > > > On Wed, Apr 4, 2018 at 6:51 AM, Pekka Paalanen <<a href="mailto:ppaalanen@gmail.com">ppaalanen@gmail.com</a>><br>
> > > > wrote:<br>
> > > > ><br>
> > > > > > From: Pekka Paalanen <<a href="mailto:pekka.paalanen@collabora.co.uk">pekka.paalanen@collabora.co.<wbr>uk</a>><br>
> > > > > ><br>
> > > > > > Hi,<br>
> > > > > ><br>
> > > > > > here is a patch for a race that was troubling a distribution for an<br>
> > > > > > embedded device. The original form of this patch has been in developer<br>
> > > > > > use for months now, and it seems to work there. For this version I have<br>
> > > > > > only changed the logging and fixed a leak.<br>
> > > > > ><br>
> > > > > > I originally discussed this issue on #wayland with Peter Hutterer on<br>
> > > > > > September 22, 2017. The discussion is quoted below to refresh our<br>
> > > > > > memories.<br>
> > > > > ><br>
> > > > > > In the distribution, Weston is started by systemd, the system is not<br>
> > > > > > very CPU-powerful, and lots of things are happening during the boot,<br>
> > > > > > which may all contribute to making this race possible to lose.<br>
> > > > > ><br>
> > > > > > I've only tested briefly on my work desktop to see that Weston still<br>
> > > > > > appears to find the input devices I expect. Obviously my desktop would<br>
> > > > > > never lose the race, because there are no input devices being hotplugged<br>
> > > > > > at the same time as Weston is starting up.<br>
> > > > > ><br>
> > > > > > The timer/idle callback idea is not implemented here, and neither is the<br>
> > > > > > double-add filtering. Let me know if you require those.<br>
> > > > > ><br>
> > > > > ><br>
> > > > > > Thanks,<br>
> > > > > > pq<br>
> > > > > ><br>
> > > > > ><br>
> > > > > > < pq> whot, btw. we've looking into some fun libinput vs. udev<br>
> > > > > > device initialization race here. Apparently the device enumeration<br>
> > > > > > on libinput start-up may race with udev preparing devices at the<br>
> > > > > > same time, so the initial device enumeration for weston may see<br>
> > > > > > devices that have not had all their udev properties set yet. Do you<br>
> > > > > > recall ever fighting such issues?<br>
> > > > > ><br>
> > > > > > < pq> whot, another issue is that we may see a double-add of a<br>
> > > > > > device, first from the initial enumeration (with possibly missing<br>
> > > > > > properties) and then a second time as a hotplug event because<br>
> > > > > > libinput (correctly) listens for events before it enume existing<br>
> > > > > > devices.<br>
> > > > > ><br>
> > > > > > < whot> pq: yes, I've seen this a lot with the test suite, but never<br>
> > > > > > in real life<br>
> > > > > ><br>
> > > > > > < whot> I'm pretty sure in my case it's always a lingering udev<br>
> > > > > > device or some lingering properties<br>
> > > > > ><br>
> > > > > > < whot> e.g. a tablet has some keyboard properties set because the<br>
> > > > > > kernel re-uses the event node<br>
> > > > > ><br>
> > > > > > < whot> but that's triggered by the test suite using the path<br>
> > > > > > interface and there's bound to be a window where we can race. it<br>
> > > > > > shouldn't happen with the udev device, I think<br>
> > > > > ><br>
> > > > > > < pq> specifically, in the target device/system with touchscreens<br>
> > > > > > and weston, there are udev rules to set WL_OUTPUT on the device, but<br>
> > > > > > weston does not always see it.<br>
> > > > > ><br>
> > > > > > < pq> well, we use libinput via weston, and I don't think weston<br>
> > > > > > uses the path-based function. It's really the initial enumeration of<br>
> > > > > > input devices in libinput that has the issue.<br>
> > > > > ><br>
> > > > > > < whot> pq: a double-add is a bug, I can picture that happening with<br>
> > > > > > the current code. should be fixable<br>
> > > > > ><br>
> > > > > >  * whot mumples something about syspath comparisons to filter that<br>
> > > > > > out<br>
> > > > > ><br>
> > > > > > < whot> mumbles, even. but it's late nough that I'm also open for<br>
> > > > > > mumpling<br>
> > > > > ><br>
> > > > > > < pq> whot, nice. Yeah, let's see if we have a patch to submit or<br>
> > > > > > just a bug report, it might take a while.<br>
> > > > > ><br>
> > > > > > < whot> pq: for the missing properties I have no idea, but that<br>
> > > > > > would, if anything, be a systemd bug<br>
> > > > > ><br>
> > > > > > < pq> whot, really? What's udev_device_get_is_<wbr>initialised() for<br>
> > > > > > then? Does it not apply to the initial device enumeration as done by<br>
> > > > > > libinput?<br>
> > > > > ><br>
> > > > > > < pq> whot, how does initial device enumeration work? Does it go the<br>
> > > > > > udev daemon or just look in sysfs on its own?<br>
> > > > > ><br>
> > > > > > < whot> udev_device_get_is_initialized may help but it didn't with<br>
> > > > > > the test suite<br>
> > > > > ><br>
> > > > > > < whot> but for your case, it might just because you're fighting a<br>
> > > > > > different race<br>
> > > > > ><br>
> > > > > > < whot> should be easy enough to printf that to the log in your case<br>
> > > > > > and check if it's false when it fails<br>
> > > > > ><br>
> > > > > > < pq> whot, oh yeah, this didn't feel like a lingering device issue.<br>
> > > > > ><br>
> > > > > > < whot> initial enumeration: see udev_input_add_devices in<br>
> > > > > > src/udev-seat.c<br>
> > > > > ><br>
> > > > > > < whot> basically: "get list of devices maching subsystem input,<br>
> > > > > > create udev device for each syspath in that list"<br>
> > > > > ><br>
> > > > > > < pq> whot, our current idea is to have the initial enumeration to<br>
> > > > > > ignore devices where udev_device_get_is_<wbr>initialized() returns false,<br>
> > > > > > because presumably we will get the hotplug event later anyway.<br>
> > > > > ><br>
> > > > > > < pq> that would avoid any busy-loop waiting<br>
> > > > > ><br>
> > > > > > < whot> you could schedule a callback for that device's syspath<br>
> > > > > ><br>
> > > > > > < whot> takes the whole "presumably" out of the question :)<br>
> > > > > ><br>
> > > > > > < pq> you mean like an idle task to re-check it?<br>
> > > > > ><br>
> > > > > > < whot> yeah, that or a timer<br>
> > > > > ><br>
> > > > > > < whot> not sure we have idle sources in libinput right now, so a<br>
> > > > > > timer is your better option here<br>
> > > > > ><br>
> > > > > > < pq> whot, ok, sure. Thanks for the tip. :-)<br>
> > > > > ><br>
> > > > > > Nandor Han (1):<br>
> > > > > >   udev: validate input devices during cold-plug<br>
> > > > > ><br>
> > > > > >  src/udev-seat.c | 11 +++++++++++<br>
> > > > > >  1 file changed, 11 insertions(+)<br>
> > > > > ><br>
> > > > > > --<br>
> > > > > > 2.16.1<br>
> > > > > ><br>
> > > > > > ______________________________<wbr>_________________<br>
> > > > > > wayland-devel mailing list<br>
> > > > > > <a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.<wbr>freedesktop.org</a><br>
> > > > > > <a href="https://lists.freedesktop.org/mailman/listinfo/wayland-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/wayland-devel</a><br>
> > > > > ><br>
> > > ><br>
> > > > > ______________________________<wbr>_________________<br>
> > > > > wayland-devel mailing list<br>
> > > > > <a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.<wbr>freedesktop.org</a><br>
> > > > > <a href="https://lists.freedesktop.org/mailman/listinfo/wayland-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/wayland-devel</a><br>
> > > ><br>
> > > > ______________________________<wbr>_________________<br>
> > > > wayland-devel mailing list<br>
> > > > <a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.<wbr>freedesktop.org</a><br>
> > > > <a href="https://lists.freedesktop.org/mailman/listinfo/wayland-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/wayland-devel</a><br>
> > ><br>
> <br>
</div></div></blockquote></div><br></div></div>