summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Dora <sunilkumar.dora@windriver.com>2025-10-14 07:43:42 -0700
committerSteve Sakoman <steve@sakoman.com>2025-10-17 07:27:24 -0700
commitdd624cec3bf42b3fe75b1a34fbf59bf96a3453d6 (patch)
tree46ac30c6b6706be69105f30af7b5d35e6c4f1393
parent2fdbec72e5a0c9619827e2951fb407992b9eb9c3 (diff)
downloadpoky-dd624cec3bf42b3fe75b1a34fbf59bf96a3453d6.tar.gz
glibc: Remove g_refs from condition variables
The following commits have been cherry-picked from Glibc master branch: Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847 [1] https://sourceware.org/git/?p=glibc.git;a=commit;h=c36fc50781995e6758cae2b6927839d0157f213c [2] https://sourceware.org/pipermail/libc-stable/2025-July/002278.html (From OE-Core rev: 1972b6776fa8a23b9d373d516ace32e136e9058f) Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-core/glibc/glibc/0026-PR25847-5.patch188
-rw-r--r--meta/recipes-core/glibc/glibc_2.35.bb1
2 files changed, 189 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/0026-PR25847-5.patch b/meta/recipes-core/glibc/glibc/0026-PR25847-5.patch
new file mode 100644
index 0000000000..e50e942471
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0026-PR25847-5.patch
@@ -0,0 +1,188 @@
1From f904a81ff8d0469ceaf3220329e716c03fcbd2d3 Mon Sep 17 00:00:00 2001
2From: Malte Skarupke <malteskarupke@fastmail.fm>
3Date: Tue, 14 Oct 2025 05:59:02 -0700
4Subject: [PATCH] nptl: Remove g_refs from condition variables
5
6This variable used to be needed to wait in group switching until all sleepers
7have confirmed that they have woken. This is no longer needed. Nothing waits
8on this variable so there is no need to track how many threads are currently
9asleep in each group.
10
11The following commits have been cherry-picked from Glibc master branch:
12Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
13cmmit: c36fc50781995e6758cae2b6927839d0157f213c
14
15Upstream-Status: Submitted
16[https://sourceware.org/pipermail/libc-stable/2025-July/002278.html]
17
18Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
19---
20 nptl/pthread_cond_wait.c | 52 +------------------------
21 nptl/tst-cond22.c | 12 +++---
22 sysdeps/nptl/bits/thread-shared-types.h | 3 +-
23 sysdeps/nptl/pthread.h | 2 +-
24 4 files changed, 9 insertions(+), 60 deletions(-)
25
26diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
27index 47e834ca..8a9219e0 100644
28--- a/nptl/pthread_cond_wait.c
29+++ b/nptl/pthread_cond_wait.c
30@@ -143,23 +143,6 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
31 }
32 }
33
34-/* Wake up any signalers that might be waiting. */
35-static void
36-__condvar_dec_grefs (pthread_cond_t *cond, unsigned int g, int private)
37-{
38- /* Release MO to synchronize-with the acquire load in
39- __condvar_quiesce_and_switch_g1. */
40- if (atomic_fetch_add_release (cond->__data.__g_refs + g, -2) == 3)
41- {
42- /* Clear the wake-up request flag before waking up. We do not need more
43- than relaxed MO and it doesn't matter if we apply this for an aliased
44- group because we wake all futex waiters right after clearing the
45- flag. */
46- atomic_fetch_and_relaxed (cond->__data.__g_refs + g, ~(unsigned int) 1);
47- futex_wake (cond->__data.__g_refs + g, INT_MAX, private);
48- }
49-}
50-
51 /* Clean-up for cancellation of waiters waiting for normal signals. We cancel
52 our registration as a waiter, confirm we have woken up, and re-acquire the
53 mutex. */
54@@ -171,8 +154,6 @@ __condvar_cleanup_waiting (void *arg)
55 pthread_cond_t *cond = cbuffer->cond;
56 unsigned g = cbuffer->wseq & 1;
57
58- __condvar_dec_grefs (cond, g, cbuffer->private);
59-
60 __condvar_cancel_waiting (cond, cbuffer->wseq >> 1, g, cbuffer->private);
61 /* FIXME With the current cancellation implementation, it is possible that
62 a thread is cancelled after it has returned from a syscall. This could
63@@ -327,15 +308,6 @@ __condvar_cleanup_waiting (void *arg)
64 sufficient because if a waiter can see a sufficiently large value, it could
65 have also consume a signal in the waiters group.
66
67- It is essential that the last field in pthread_cond_t is __g_signals[1]:
68- The previous condvar used a pointer-sized field in pthread_cond_t, so a
69- PTHREAD_COND_INITIALIZER from that condvar implementation might only
70- initialize 4 bytes to zero instead of the 8 bytes we need (i.e., 44 bytes
71- in total instead of the 48 we need). __g_signals[1] is not accessed before
72- the first group switch (G2 starts at index 0), which will set its value to
73- zero after a harmless fetch-or whose return value is ignored. This
74- effectively completes initialization.
75-
76
77 Limitations:
78 * This condvar isn't designed to allow for more than
79@@ -440,21 +412,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
80 if ((int)(signals - lowseq) >= 2)
81 break;
82
83- /* No signals available after spinning, so prepare to block.
84- We first acquire a group reference and use acquire MO for that so
85- that we synchronize with the dummy read-modify-write in
86- __condvar_quiesce_and_switch_g1 if we read from that. In turn,
87- in this case this will make us see the advancement of __g_signals
88- to the upcoming new g1_start that occurs with a concurrent
89- attempt to reuse the group's slot.
90- We use acquire MO for the __g_signals check to make the
91- __g1_start check work (see spinning above).
92- Note that the group reference acquisition will not mask the
93- release MO when decrementing the reference count because we use
94- an atomic read-modify-write operation and thus extend the release
95- sequence. */
96- atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
97-
98 // Now block.
99 struct _pthread_cleanup_buffer buffer;
100 struct _condvar_cleanup_buffer cbuffer;
101@@ -471,18 +428,11 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
102
103 if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
104 {
105- __condvar_dec_grefs (cond, g, private);
106- /* If we timed out, we effectively cancel waiting. Note that
107- we have decremented __g_refs before cancellation, so that a
108- deadlock between waiting for quiescence of our group in
109- __condvar_quiesce_and_switch_g1 and us trying to acquire
110- the lock during cancellation is not possible. */
111+ /* If we timed out, we effectively cancel waiting. */
112 __condvar_cancel_waiting (cond, seq, g, private);
113 result = err;
114 goto done;
115 }
116- else
117- __condvar_dec_grefs (cond, g, private);
118
119 /* Reload signals. See above for MO. */
120 signals = atomic_load_acquire (cond->__data.__g_signals + g);
121diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c
122index 1336e9c7..bdcb45c5 100644
123--- a/nptl/tst-cond22.c
124+++ b/nptl/tst-cond22.c
125@@ -106,13 +106,13 @@ do_test (void)
126 status = 1;
127 }
128
129- printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
130+ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n",
131 c.__data.__wseq.__value32.__high,
132 c.__data.__wseq.__value32.__low,
133 c.__data.__g1_start.__value32.__high,
134 c.__data.__g1_start.__value32.__low,
135- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
136- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
137+ c.__data.__g_signals[0], c.__data.__g_size[0],
138+ c.__data.__g_signals[1], c.__data.__g_size[1],
139 c.__data.__g1_orig_size, c.__data.__wrefs);
140
141 if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)
142@@ -152,13 +152,13 @@ do_test (void)
143 status = 1;
144 }
145
146- printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
147+ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n",
148 c.__data.__wseq.__value32.__high,
149 c.__data.__wseq.__value32.__low,
150 c.__data.__g1_start.__value32.__high,
151 c.__data.__g1_start.__value32.__low,
152- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
153- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
154+ c.__data.__g_signals[0], c.__data.__g_size[0],
155+ c.__data.__g_signals[1], c.__data.__g_size[1],
156 c.__data.__g1_orig_size, c.__data.__wrefs);
157
158 return status;
159diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
160index 5653507e..6f17afa4 100644
161--- a/sysdeps/nptl/bits/thread-shared-types.h
162+++ b/sysdeps/nptl/bits/thread-shared-types.h
163@@ -95,8 +95,7 @@ struct __pthread_cond_s
164 {
165 __atomic_wide_counter __wseq;
166 __atomic_wide_counter __g1_start;
167- unsigned int __g_refs[2] __LOCK_ALIGNMENT;
168- unsigned int __g_size[2];
169+ unsigned int __g_size[2] __LOCK_ALIGNMENT;
170 unsigned int __g1_orig_size;
171 unsigned int __wrefs;
172 unsigned int __g_signals[2];
173diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
174index dedad4ec..bbb36540 100644
175--- a/sysdeps/nptl/pthread.h
176+++ b/sysdeps/nptl/pthread.h
177@@ -152,7 +152,7 @@ enum
178
179
180 /* Conditional variable handling. */
181-#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
182+#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, 0, 0, {0, 0} } }
183
184
185 /* Cleanup buffers */
186--
1872.49.0
188
diff --git a/meta/recipes-core/glibc/glibc_2.35.bb b/meta/recipes-core/glibc/glibc_2.35.bb
index f9086c0855..e744260e87 100644
--- a/meta/recipes-core/glibc/glibc_2.35.bb
+++ b/meta/recipes-core/glibc/glibc_2.35.bb
@@ -66,6 +66,7 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
66 file://0026-PR25847-2.patch \ 66 file://0026-PR25847-2.patch \
67 file://0026-PR25847-3.patch \ 67 file://0026-PR25847-3.patch \
68 file://0026-PR25847-4.patch \ 68 file://0026-PR25847-4.patch \
69 file://0026-PR25847-5.patch \
69 \ 70 \
70 file://0001-Revert-Linux-Implement-a-useful-version-of-_startup_.patch \ 71 file://0001-Revert-Linux-Implement-a-useful-version-of-_startup_.patch \
71 file://0002-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch \ 72 file://0002-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch \