summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-core/glibc/glibc/0026-PR25847-9.patch193
-rw-r--r--meta/recipes-core/glibc/glibc_2.35.bb1
2 files changed, 194 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/0026-PR25847-9.patch b/meta/recipes-core/glibc/glibc/0026-PR25847-9.patch
new file mode 100644
index 0000000000..49815c6fb7
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0026-PR25847-9.patch
@@ -0,0 +1,193 @@
1From c2677e68956bb9677d8de4ee6c5341b1a744d490 Mon Sep 17 00:00:00 2001
2From: Malte Skarupke <malteskarupke@fastmail.fm>
3Date: Tue, 14 Oct 2025 06:40:57 -0700
4Subject: [PATCH] nptl: Use all of g1_start and g_signals
5
6The LSB of g_signals was unused. The LSB of g1_start was used to indicate
7which group is G2. This was used to always go to sleep in pthread_cond_wait
8if a waiter is in G2. A comment earlier in the file says that this is not
9correct to do:
10
11 "Waiters cannot determine whether they are currently in G2 or G1 -- but they
12 do not have to because all they are interested in is whether there are
13 available signals"
14
15I either would have had to update the comment, or get rid of the check. I
16chose to get rid of the check. In fact I don't quite know why it was there.
17There will never be available signals for group G2, so we didn't need the
18special case. Even if there were, this would just be a spurious wake. This
19might have caught some cases where the count has wrapped around, but it
20wouldn't reliably do that, (and even if it did, why would you want to force a
21sleep in that case?) and we don't support that many concurrent waiters
22anyway. Getting rid of it allows us to use one more bit, making us more
23robust to wraparound.
24
25The following commits have been cherry-picked from Glibc master branch:
26Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
27commit: 91bb902f58264a2fd50fbce8f39a9a290dd23706
28
29Upstream-Status: Submitted
30[https://sourceware.org/pipermail/libc-stable/2025-July/002283.html]
31
32Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
33---
34 nptl/pthread_cond_broadcast.c | 4 ++--
35 nptl/pthread_cond_common.c | 26 ++++++++++----------------
36 nptl/pthread_cond_signal.c | 2 +-
37 nptl/pthread_cond_wait.c | 14 +++++---------
38 4 files changed, 18 insertions(+), 28 deletions(-)
39
40diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
41index a0743558..ef0943cd 100644
42--- a/nptl/pthread_cond_broadcast.c
43+++ b/nptl/pthread_cond_broadcast.c
44@@ -57,7 +57,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
45 {
46 /* Add as many signals as the remaining size of the group. */
47 atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
48- cond->__data.__g_size[g1] << 1);
49+ cond->__data.__g_size[g1]);
50 cond->__data.__g_size[g1] = 0;
51
52 /* We need to wake G1 waiters before we switch G1 below. */
53@@ -73,7 +73,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
54 {
55 /* Step (3): Send signals to all waiters in the old G2 / new G1. */
56 atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
57- cond->__data.__g_size[g1] << 1);
58+ cond->__data.__g_size[g1]);
59 cond->__data.__g_size[g1] = 0;
60 /* TODO Only set it if there are indeed futex waiters. */
61 do_futex_wake = true;
62diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
63index 3baac4da..e48f9143 100644
64--- a/nptl/pthread_cond_common.c
65+++ b/nptl/pthread_cond_common.c
66@@ -208,9 +208,9 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
67 behavior.
68 Note that this works correctly for a zero-initialized condvar too. */
69 unsigned int old_orig_size = __condvar_get_orig_size (cond);
70- uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
71- if (((unsigned) (wseq - old_g1_start - old_orig_size)
72- + cond->__data.__g_size[g1 ^ 1]) == 0)
73+ uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond);
74+ uint64_t new_g1_start = old_g1_start + old_orig_size;
75+ if (((unsigned) (wseq - new_g1_start) + cond->__data.__g_size[g1 ^ 1]) == 0)
76 return false;
77
78 /* We have to consider the following kinds of waiters:
79@@ -221,16 +221,10 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
80 are not affected.
81 * Waiters in G1 have already received a signal and been woken. */
82
83- /* Update __g1_start, which closes this group. The value we add will never
84- be negative because old_orig_size can only be zero when we switch groups
85- the first time after a condvar was initialized, in which case G1 will be
86- at index 1 and we will add a value of 1. Relaxed MO is fine because the
87- change comes with no additional constraints that others would have to
88- observe. */
89- __condvar_add_g1_start_relaxed (cond,
90- (old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
91-
92- unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
93+ /* Update __g1_start, which closes this group. Relaxed MO is fine because
94+ the change comes with no additional constraints that others would have
95+ to observe. */
96+ __condvar_add_g1_start_relaxed (cond, old_orig_size);
97
98 /* At this point, the old G1 is now a valid new G2 (but not in use yet).
99 No old waiter can neither grab a signal nor acquire a reference without
100@@ -242,13 +236,13 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
101 g1 ^= 1;
102 *g1index ^= 1;
103
104- /* Now advance the new G1 g_signals to the new lowseq, giving it
105+ /* Now advance the new G1 g_signals to the new g1_start, giving it
106 an effective signal count of 0 to start. */
107- atomic_store_release (cond->__data.__g_signals + g1, lowseq);
108+ atomic_store_release (cond->__data.__g_signals + g1, (unsigned)new_g1_start);
109
110 /* These values are just observed by signalers, and thus protected by the
111 lock. */
112- unsigned int orig_size = wseq - (old_g1_start + old_orig_size);
113+ unsigned int orig_size = wseq - new_g1_start;
114 __condvar_set_orig_size (cond, orig_size);
115 /* Use and addition to not loose track of cancellations in what was
116 previously G2. */
117diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
118index a9bc10dc..07427369 100644
119--- a/nptl/pthread_cond_signal.c
120+++ b/nptl/pthread_cond_signal.c
121@@ -80,7 +80,7 @@ ___pthread_cond_signal (pthread_cond_t *cond)
122 release-MO store when initializing a group in __condvar_switch_g1
123 because we use an atomic read-modify-write and thus extend that
124 store's release sequence. */
125- atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
126+ atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 1);
127 cond->__data.__g_size[g1]--;
128 /* TODO Only set it if there are indeed futex waiters. */
129 do_futex_wake = true;
130diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
131index 40a74342..d7e073ab 100644
132--- a/nptl/pthread_cond_wait.c
133+++ b/nptl/pthread_cond_wait.c
134@@ -84,7 +84,7 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
135 not hold a reference on the group. */
136 __condvar_acquire_lock (cond, private);
137
138- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
139+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
140 if (g1_start > seq)
141 {
142 /* Our group is closed, so someone provided enough signals for it.
143@@ -259,7 +259,6 @@ __condvar_cleanup_waiting (void *arg)
144 * Waiters fetch-add while having acquire the mutex associated with the
145 condvar. Signalers load it and fetch-xor it concurrently.
146 __g1_start: Starting position of G1 (inclusive)
147- * LSB is index of current G2.
148 * Modified by signalers while having acquired the condvar-internal lock
149 and observed concurrently by waiters.
150 __g1_orig_size: Initial size of G1
151@@ -280,11 +279,9 @@ __condvar_cleanup_waiting (void *arg)
152 * Reference count used by waiters concurrently with signalers that have
153 acquired the condvar-internal lock.
154 __g_signals: The number of signals that can still be consumed, relative to
155- the current g1_start. (i.e. bits 31 to 1 of __g_signals are bits
156- 31 to 1 of g1_start with the signal count added)
157+ the current g1_start. (i.e. g1_start with the signal count added)
158 * Used as a futex word by waiters. Used concurrently by waiters and
159 signalers.
160- * LSB is currently reserved and 0.
161 __g_size: Waiters remaining in this group (i.e., which have not been
162 signaled yet.
163 * Accessed by signalers and waiters that cancel waiting (both do so only
164@@ -391,9 +388,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
165 too. */
166 unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
167 uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
168- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
169
170- if (seq < (g1_start >> 1))
171+ if (seq < g1_start)
172 {
173 /* If the group is closed already,
174 then this waiter originally had enough extra signals to
175@@ -406,13 +402,13 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
176 by now, perhaps in the process of switching back to an older
177 G2, but in either case we're allowed to consume the available
178 signal and should not block anymore. */
179- if ((int)(signals - lowseq) >= 2)
180+ if ((int)(signals - (unsigned int)g1_start) > 0)
181 {
182 /* Try to grab a signal. See above for MO. (if we do another loop
183 iteration we need to see the correct value of g1_start) */
184 if (atomic_compare_exchange_weak_acquire (
185 cond->__data.__g_signals + g,
186- &signals, signals - 2))
187+ &signals, signals - 1))
188 break;
189 else
190 continue;
191--
1922.49.0
193
diff --git a/meta/recipes-core/glibc/glibc_2.35.bb b/meta/recipes-core/glibc/glibc_2.35.bb
index 265dcb9129..26e8d8c408 100644
--- a/meta/recipes-core/glibc/glibc_2.35.bb
+++ b/meta/recipes-core/glibc/glibc_2.35.bb
@@ -70,6 +70,7 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
70 file://0026-PR25847-6.patch \ 70 file://0026-PR25847-6.patch \
71 file://0026-PR25847-7.patch \ 71 file://0026-PR25847-7.patch \
72 file://0026-PR25847-8.patch \ 72 file://0026-PR25847-8.patch \
73 file://0026-PR25847-9.patch \
73 \ 74 \
74 file://0001-Revert-Linux-Implement-a-useful-version-of-_startup_.patch \ 75 file://0001-Revert-Linux-Implement-a-useful-version-of-_startup_.patch \
75 file://0002-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch \ 76 file://0002-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch \