]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/efivars: try re-reading efivars without delay first
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 31 May 2020 10:16:57 +0000 (12:16 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 2 Jun 2020 15:32:29 +0000 (17:32 +0200)
Quoting https://github.com/systemd/systemd/issues/14828#issuecomment-635212615:

> [kernel uses] msleep_interruptible() and that means when the process receives
> any kind of signal masked or not this will abort with EINTR.  systemd-logind
> gets signals from the TTY layer all the time though.

> Here's what might be happening: while logind reads the EFI stuff it gets a
> series of signals from the TTY layer, which causes the read() to be aborted
> with EINTR, which means logind will wait 50ms and retry. Which will be
> aborted again, and so on, until quite some time passed. If we'd not wait for
> the 50ms otoh we wouldn't wait so long, as then on each signal we'd
> immediately retry again.

src/basic/efivars.c

index 7cff80454488407d3582491ccb29a4dd4b9a9a0d..3954bd62f5cb3056227a4423adaca9311e398cd8 100644 (file)
@@ -25,7 +25,8 @@
 #if ENABLE_EFI
 
 /* Reads from efivarfs sometimes fail with EINTR. Retry that many times. */
-#define EFI_N_RETRIES 5
+#define EFI_N_RETRIES_NO_DELAY 20
+#define EFI_N_RETRIES_TOTAL 25
 #define EFI_RETRY_DELAY (50 * USEC_PER_MSEC)
 
 char* efi_variable_path(sd_id128_t vendor, const char *name) {
@@ -101,10 +102,11 @@ int efi_get_variable(
                         log_debug_errno(errno, "Reading from \"%s\" failed: %m", p);
                         if (errno != EINTR)
                                 return -errno;
-                        if (try >= EFI_N_RETRIES)
+                        if (try >= EFI_N_RETRIES_TOTAL)
                                 return -EBUSY;
 
-                        (void) usleep(EFI_RETRY_DELAY);
+                        if (try >= EFI_N_RETRIES_NO_DELAY)
+                                (void) usleep(EFI_RETRY_DELAY);
                 }
 
                 if (n != sizeof(a))