Blob Blame History Raw
From fce5b2ac2a51b9ecbfb258ff7e62f4e67a38d4c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 12 Mar 2021 10:20:38 +0100
Subject: [PATCH] sd-event: disable epoll_pwait2 for now

This reverts the gist of commit 798445ab84cff51bde7fcf936f0fb19c37cf858c.

Unfortunately the new syscall causes test-event to hang. 32 bit architectures
seem affected: i686 and arm32 in fedora koji. 32 bit build of test-event hangs
reliably under valgrind:

$ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig meson build-32 -Dc_args=-m32 -Dc_link_args=-m32 -Dcpp_args=-m32 -Dcpp_link_args=-m32 && ninja -C build-32 test-event && valgrind build/test-event

If I set epoll_pwait2_absent=true, so the new function is never called, then
the issue does not reproduce. It seems to be strictly tied to the syscall.

On amd64, the syscall is not used, at least with the kernel that Fedora
provides. The kernel patch 58169a52ebc9a733aeb5bea857bc5daa71a301bb says:

  For timespec, only support this new interface on 2038 aware platforms
  that define __kernel_timespec_t. So no CONFIG_COMPAT_32BIT_TIME.

And Fedora sets CONFIG_COMPAT_32BIT_TIME=y. I expect most other distros will too.

On amd64: epoll_wait_usec: epoll_pwait2: ret=-1 / errno=38
On i686 (same kernel): epoll_wait_usec: epoll_pwait2: ret=2 / errno=0

Is this some kind of emulation? Anyway, it seems that this is what is going wrong.

So let's disable the syscall until it becomes more widely available and the
kinks have been ironed out.

Fixes test-event issue in #19052.
---
 src/libsystemd/sd-event/sd-event.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 8f74b141015..b76b0623fe3 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -3808,10 +3808,15 @@ static int epoll_wait_usec(
                 int maxevents,
                 usec_t timeout) {
 
-        static bool epoll_pwait2_absent = false;
         int r, msec;
+#if 0
+        static bool epoll_pwait2_absent = false;
 
-        /* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not */
+        /* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not.
+         *
+         * FIXME: this is temporarily disabled until epoll_pwait2() becomes more widely available.
+         * See https://github.com/systemd/systemd/pull/18973 and
+         * https://github.com/systemd/systemd/issues/19052. */
 
         if (!epoll_pwait2_absent && timeout != USEC_INFINITY) {
                 struct timespec ts;
@@ -3829,6 +3834,7 @@ static int epoll_wait_usec(
 
                 epoll_pwait2_absent = true;
         }
+#endif
 
         if (timeout == USEC_INFINITY)
                 msec = -1;