mirror of
https://git.yoctoproject.org/poky
synced 2026-05-30 12:29:55 +00:00
glibc: nptl Remove unnecessary catch-all-wake in condvar group switch
The following commits have been cherry-picked from Glibc master branch: Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847 Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=commit;h=b42cc6af11062c260c7dfa91f1c89891366fed3e] (From OE-Core rev: 02f2ac08edb506ec43cec93a5b09f5e6d7df02ec) Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
committed by
Steve Sakoman
parent
a9b8182e89
commit
cdd974ba56
@@ -0,0 +1,77 @@
|
|||||||
|
From 28a5082045429fdc5a4744d45fdc5b5202528eaa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||||
|
Date: Mon, 16 Jun 2025 23:29:49 -0700
|
||||||
|
Subject: [PATCH] nptl: Remove unnecessary catch-all-wake in condvar group
|
||||||
|
switch
|
||||||
|
|
||||||
|
This wake is unnecessary. We only switch groups after every sleeper in a group
|
||||||
|
has been woken. Sure, they may take a while to actually wake up and may still
|
||||||
|
hold a reference, but waking them a second time doesn't speed that up. Instead
|
||||||
|
this just makes the code more complicated and may hide problems.
|
||||||
|
|
||||||
|
In particular this safety wake wouldn't even have helped with the bug that was
|
||||||
|
fixed by Barrus' patch: The bug there was that pthread_cond_signal would not
|
||||||
|
switch g1 when it should, so we wouldn't even have entered this code path.
|
||||||
|
|
||||||
|
The following commits have been cherry-picked from Glibc master branch:
|
||||||
|
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||||
|
|
||||||
|
Upstream-Status: Backport
|
||||||
|
[https://sourceware.org/git/?p=glibc.git;a=commit;h=b42cc6af11062c260c7dfa91f1c89891366fed3e]
|
||||||
|
|
||||||
|
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||||
|
---
|
||||||
|
nptl/pthread_cond_common.c | 30 +-----------------------------
|
||||||
|
1 file changed, 1 insertion(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||||
|
index 306a207dd6..f976a533a1 100644
|
||||||
|
--- a/nptl/pthread_cond_common.c
|
||||||
|
+++ b/nptl/pthread_cond_common.c
|
||||||
|
@@ -221,13 +221,7 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||||
|
* New waiters arriving concurrently with the group switching will all go
|
||||||
|
into G2 until we atomically make the switch. Waiters existing in G2
|
||||||
|
are not affected.
|
||||||
|
- * Waiters in G1 have already received a signal and been woken. If they
|
||||||
|
- haven't woken yet, they will be closed out immediately by the advancing
|
||||||
|
- of __g_signals to the next "lowseq" (low 31 bits of the new g1_start),
|
||||||
|
- which will prevent waiters from blocking using a futex on
|
||||||
|
- __g_signals since it provides enough signals for all possible
|
||||||
|
- remaining waiters. As a result, they can each consume a signal
|
||||||
|
- and they will eventually remove their group reference. */
|
||||||
|
+ * Waiters in G1 have already received a signal and been woken. */
|
||||||
|
|
||||||
|
/* Update __g1_start, which finishes closing this group. The value we add
|
||||||
|
will never be negative because old_orig_size can only be zero when we
|
||||||
|
@@ -240,28 +234,6 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||||
|
|
||||||
|
unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||||
|
|
||||||
|
- /* If any waiters still hold group references (and thus could be blocked),
|
||||||
|
- then wake them all up now and prevent any running ones from blocking.
|
||||||
|
- This is effectively a catch-all for any possible current or future
|
||||||
|
- bugs that can allow the group size to reach 0 before all G1 waiters
|
||||||
|
- have been awakened or at least given signals to consume, or any
|
||||||
|
- other case that can leave blocked (or about to block) older waiters.. */
|
||||||
|
- if ((atomic_fetch_or_release (cond->__data.__g_refs + g1, 0) >> 1) > 0)
|
||||||
|
- {
|
||||||
|
- /* First advance signals to the end of the group (i.e. enough signals
|
||||||
|
- for the entire G1 group) to ensure that waiters which have not
|
||||||
|
- yet blocked in the futex will not block.
|
||||||
|
- Note that in the vast majority of cases, this should never
|
||||||
|
- actually be necessary, since __g_signals will have enough
|
||||||
|
- signals for the remaining g_refs waiters. As an optimization,
|
||||||
|
- we could check this first before proceeding, although that
|
||||||
|
- could still leave the potential for futex lost wakeup bugs
|
||||||
|
- if the signal count was non-zero but the futex wakeup
|
||||||
|
- was somehow lost. */
|
||||||
|
- atomic_store_release (cond->__data.__g_signals + g1, lowseq);
|
||||||
|
-
|
||||||
|
- futex_wake (cond->__data.__g_signals + g1, INT_MAX, private);
|
||||||
|
- }
|
||||||
|
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||||
|
No old waiter can neither grab a signal nor acquire a reference without
|
||||||
|
noticing that __g1_start is larger.
|
||||||
|
--
|
||||||
|
2.49.0
|
||||||
|
|
||||||
@@ -64,6 +64,7 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
|
|||||||
file://0025-CVE-2025-4802.patch \
|
file://0025-CVE-2025-4802.patch \
|
||||||
file://0026-PR25847-1.patch \
|
file://0026-PR25847-1.patch \
|
||||||
file://0026-PR25847-2.patch \
|
file://0026-PR25847-2.patch \
|
||||||
|
file://0026-PR25847-3.patch \
|
||||||
\
|
\
|
||||||
file://0001-Revert-Linux-Implement-a-useful-version-of-_startup_.patch \
|
file://0001-Revert-Linux-Implement-a-useful-version-of-_startup_.patch \
|
||||||
file://0002-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch \
|
file://0002-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch \
|
||||||
|
|||||||
Reference in New Issue
Block a user