Re: [PATCH] HID: core: Call request_module before doing device_add

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Mar 25, 2019 at 11:57 AM Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
>
> Hi,
>
> On 25-03-19 11:54, Benjamin Tissoires wrote:
> > On Thu, Mar 21, 2019 at 3:51 PM Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
> >>
> >> Recent kernels allow the generic-hid driver to be used as fallback for
> >> devices with a specialized driver, when the hiddev is not listed in
> >> hid_have_special_driver. Over time we are removing more and more
> >> devices from the hid_have_special_driver table as devices get tested
> >> to support this setup.
> >>
> >> Before this commit the following happens when a HID device which has a
> >> special-driver and is no longer listed in hid_have_special_driver, gets
> >> enumerated:
> >>
> >> 1) device_add() gets called
> >> 2) bus_add_device() looks for a matching already registered hid driver,
> >>     and bind hid-generic to the new device
> >> 3) kobject_uevent(&dev->kobj, KOBJ_ADD) gets called notifying userspace of
> >>     the new hid_dev. udev calls modprobe based on the modalias in the uevent
> >> 4) The special driver gets loaded by modprobe
> >> 5) __hid_bus_reprobe_drivers() unbinds hid-generic and binds the new driver
> >>
> >> There are a couple of downsides to this:
> >>
> >> a) The probing messages printend when a HID driver bounds show up twice in
> >> dmesg, which is confusing for the user
> >>
> >> b) The (un)binding typically causes one or more evdev device-nodes to get
> >> (un)registed firing of udev events to which e.g. the xserver responds by
> >> (un)registering xinput devices and reporting this to interested clients.
> >> IOW the i. bind generic, ii. unbind generic, iii. bind special driver dance
> >> sets in motion a whole chain of events each step, while we really only want
> >> the events from step iii. to be reported to userspace.
> >>
> >> This commits introduces a request_module call before the device_add()
> >> call, so that the special-driver is loaded when step 2) looks for a
> >> matching driver and we directly bind the specialized driver.
> >>
> >> Note the request_module call translates to an execve("/sbin/modprobe", ...)
> >> and we now do this for each HID device added. So this is not entirely free,
> >> but adding HID devices is not something which happens 100s of times a
> >> second, so this should be fine.
> >>
> >> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
> >> ---
> >
> > This seems good, but I do wonder if there is a catch or not.
> > IIRC (I might be wrong), calling request_module() would try to load a
> > module synchronously. So what happens if you are in the initramfs
> > where you do not have any extra modules?
> > Would this result in a timeout and add a delay or will this
> > "immediately" return?
>
> You are right that the /sbin/modprobe call is synchronously, that
> is request_module will wait for the modprobe process to exit, note
> it waits for modprobe to exit, not for the module to show up.
>
>  > I am just worried this will not add some delays during boot.
>
> So AFAIK (and in my testing, I did specifically measure my systems
> boot time before and after), this will not cause additional delays,
> if the module is not present in the initrd, modprobe will simply fail
> to load it and exit immediately.
>

OK, good.

However, when testing the commit with a Logitech Unifying, hid-generic
still loads prior to hid-logitech-dj. But when creating the DJ
devices, hid-logitech-hidpp is loaded and we do not see hid-generic
for those devices.

Any ideas what could explain this?

Cheers,
Benjamin

> Regards,
>
> Hans
>
>
>
> >>   drivers/hid/hid-core.c | 8 ++++++++
> >>   1 file changed, 8 insertions(+)
> >>
> >> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> >> index da7231f2944a..ee5fb8a1dd50 100644
> >> --- a/drivers/hid/hid-core.c
> >> +++ b/drivers/hid/hid-core.c
> >> @@ -2351,6 +2351,14 @@ int hid_add_device(struct hid_device *hdev)
> >>          dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
> >>                       hdev->vendor, hdev->product, atomic_inc_return(&id));
> >>
> >> +       /*
> >> +        * Try loading the module for the device before the add, so that we do
> >> +        * not first have hid-generic binding only to have it replaced
> >> +        * immediately afterwards with a specialized driver.
> >> +        */
> >> +       request_module("hid:b%04Xg%04Xv%08Xp%08X\n",
> >> +                      hdev->bus, hdev->group, hdev->vendor, hdev->product);
> >> +
> >>          hid_debug_register(hdev, dev_name(&hdev->dev));
> >>          ret = device_add(&hdev->dev);
> >>          if (!ret)
> >> --
> >> 2.21.0
> >>



[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux