lkml.org 
[lkml]   [2017]   [Jun]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v2] firmware: fix sending -ERESTARTSYS due to signal on fallback
    On Fri, Jun 09, 2017 at 09:40:47AM +0200, Martin Fuzzey wrote:
    > On 09/06/17 03:57, Luis R. Rodriguez wrote:
    > > On Thu, Jun 8, 2017 at 6:10 PM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
    > > > > Android didn't send the signal, the kernel did (SIGCHLD).
    > > > >
    > > > > Like this:
    > > > >
    > > > > 1) Android init (pid=1) fork()s (say pid=42) [this child process is totally
    > > > > unrelated to firmware loading]
    > > > > 2) Android init (pid=1) does a write() on a (driver custom) sysfs file which
    > > > > ends up calling request_firmware() kernel side
    > > > > 3) The firmware loading fallback mechanism is used, the request is sent to
    > > > > userspace and pid 1 waits in the kernel on wait_*
    > > > > 4) before firmware loading completes pid 42 dies (for any reason - in my
    > > > > case normal termination)
    > > Martin just to be clear, by "normal case termination" do you mean
    > > completing successfully ?? Ie the firmware actually did make it onto
    > > the device ?
    >
    > The firmware did *not* make it onto the device since the request_firmware()
    > call returned an error
    > (the code that would have transfered it to the device is only executed
    > following a successful request_firmware)
    >
    > The process that terminates normally is unrelated to firmware loading as I
    > said above.
    >
    > The only things that matter are:
    > - It is a child process of the process that calls request_firmware()
    > - It terminates *while* the the wait_ is still in progress
    >
    >
    > Here is a way of reproducing the problem using the test_firmware module
    > (which I only just saw) on normal linux with no Android or custom driver
    >
    >
    > #!/bin/sh
    > set -e
    >
    > # Make sure the system firmware loader doesn't get in the way
    > /etc/init.d/udev stop
    >
    > modprobe test_firmware
    >
    > DIR=/sys/devices/virtual/misc/test_firmware
    >
    > echo 10 >/sys/class/firmware/timeout;
    > sleep 2 &
    > echo -n "/some/non/existing/file.bin" > "$DIR"/trigger_request;
    >
    >
    >
    > If run with the "sleep 2 &" it terminates after 2 seconds
    > If the sleep is commented it runs for the expected 10 seconds (the firmware
    > loading timeout)
    >
    > Since the sleep process is a child of the script process requesting a
    > firmware load its death causes a SIGCHLD causing request_firmware() to abort
    > prematurely.

    BTW I've run some more tests and if you use request_firmware_nowait() the above
    issue also is avoidable. Also, if you use the custom fallback (uevent parameter
    is false) the timeout is max value always. The only way to kill the custom
    requests is through the echo -1 > loading or the max timeout triggers (don't
    rely on that!). The custom interface was a bad idea though so best to just
    avoid it.

    Anyway I can reproduce in my tests now, will add this testcase as well.
    The stable fixes will be sent as well.

    Luis

    \
     
     \ /
      Last update: 2017-06-12 01:54    [W:4.612 / U:0.244 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site