forked from pool/glibc
- gshadow-erange-rhandling.patch: gshadow: Matching sgetsgent, sgetsgent_r ERANGE handling (BZ #30151) - system-sigchld-block.patch: posix: Fix system blocks SIGCHLD erroneously (BZ #30163) - gmon-buffer-alloc.patch: gmon: Fix allocated buffer overflow (BZ #29444) - check-pf-cancel-handler.patch: __check_pf: Add a cancellation cleanup handler (BZ #20975) - powerpc64-fcntl-lock.patch: io: Fix F_GETLK, F_SETLK, and F_SETLKW for powerpc64 - realloc-limit-chunk-reuse.patch: realloc: Limit chunk reuse to only growing requests (BZ #30579) - dl-find-object-return.patch: elf: _dl_find_object may return 1 during early startup (BZ #30515) - Need to build with GCC 12 as minimum - fix-locking-in-_IO_cleanup.patch: Update to final version OBS-URL: https://build.opensuse.org/request/show/1098077 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=655
86 lines
2.7 KiB
Diff
86 lines
2.7 KiB
Diff
From f5d377c896b95fefc712b0fd5e5804ae3f48d392 Mon Sep 17 00:00:00 2001
|
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
|
Date: Thu, 27 Apr 2023 13:06:15 -0700
|
|
Subject: [PATCH] __check_pf: Add a cancellation cleanup handler [BZ #20975]
|
|
|
|
There are reports for hang in __check_pf:
|
|
|
|
https://github.com/JoeDog/siege/issues/4
|
|
|
|
It is reproducible only under specific configurations:
|
|
|
|
1. Large number of cores (>= 64) and large number of threads (> 3X of
|
|
the number of cores) with long lived socket connection.
|
|
2. Low power (frequency) mode.
|
|
3. Power management is enabled.
|
|
|
|
While holding lock, __check_pf calls make_request which calls __sendto
|
|
and __recvmsg. Since __sendto and __recvmsg are cancellation points,
|
|
lock held by __check_pf won't be released and can cause deadlock when
|
|
thread cancellation happens in __sendto or __recvmsg. Add a cancellation
|
|
cleanup handler for __check_pf to unlock the lock when cancelled by
|
|
another thread. This fixes BZ #20975 and the siege hang issue.
|
|
|
|
(cherry picked from commit a443bd3fb233186038b8b483959ecb7978d1abea)
|
|
---
|
|
sysdeps/unix/sysv/linux/Makefile | 2 ++
|
|
sysdeps/unix/sysv/linux/check_pf.c | 15 +++++++++++++++
|
|
2 files changed, 17 insertions(+)
|
|
|
|
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
|
index f298878e8f..94747b37a6 100644
|
|
--- a/sysdeps/unix/sysv/linux/Makefile
|
|
+++ b/sysdeps/unix/sysv/linux/Makefile
|
|
@@ -456,6 +456,8 @@ sysdep_headers += netinet/if_fddi.h netinet/if_tr.h \
|
|
netrom/netrom.h netpacket/packet.h netrose/rose.h \
|
|
neteconet/ec.h netiucv/iucv.h
|
|
sysdep_routines += netlink_assert_response
|
|
+
|
|
+CFLAGS-check_pf.c += -fexceptions
|
|
endif
|
|
|
|
# Don't compile the ctype glue code, since there is no old non-GNU C library.
|
|
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
|
|
index de207122b0..50654cb28d 100644
|
|
--- a/sysdeps/unix/sysv/linux/check_pf.c
|
|
+++ b/sysdeps/unix/sysv/linux/check_pf.c
|
|
@@ -292,6 +292,14 @@ make_request (int fd, pid_t pid)
|
|
return NULL;
|
|
}
|
|
|
|
+#ifdef __EXCEPTIONS
|
|
+static void
|
|
+cancel_handler (void *arg __attribute__((unused)))
|
|
+{
|
|
+ /* Release the lock. */
|
|
+ __libc_lock_unlock (lock);
|
|
+}
|
|
+#endif
|
|
|
|
void
|
|
attribute_hidden
|
|
@@ -304,6 +312,10 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
|
|
struct cached_data *olddata = NULL;
|
|
struct cached_data *data = NULL;
|
|
|
|
+#ifdef __EXCEPTIONS
|
|
+ /* Make sure that lock is released when the thread is cancelled. */
|
|
+ __libc_cleanup_push (cancel_handler, NULL);
|
|
+#endif
|
|
__libc_lock_lock (lock);
|
|
|
|
if (cache_valid_p ())
|
|
@@ -338,6 +350,9 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
|
|
}
|
|
}
|
|
|
|
+#ifdef __EXCEPTIONS
|
|
+ __libc_cleanup_pop (0);
|
|
+#endif
|
|
__libc_lock_unlock (lock);
|
|
|
|
if (data != NULL)
|
|
--
|
|
2.41.0
|
|
|