diff options
| -rw-r--r-- | meta/recipes-core/glibc/glibc/0026-PR25847-5.patch | 188 | ||||
| -rw-r--r-- | meta/recipes-core/glibc/glibc_2.35.bb | 1 |
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 @@ | |||
| 1 | From f904a81ff8d0469ceaf3220329e716c03fcbd2d3 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Malte Skarupke <malteskarupke@fastmail.fm> | ||
| 3 | Date: Tue, 14 Oct 2025 05:59:02 -0700 | ||
| 4 | Subject: [PATCH] nptl: Remove g_refs from condition variables | ||
| 5 | |||
| 6 | This variable used to be needed to wait in group switching until all sleepers | ||
| 7 | have confirmed that they have woken. This is no longer needed. Nothing waits | ||
| 8 | on this variable so there is no need to track how many threads are currently | ||
| 9 | asleep in each group. | ||
| 10 | |||
| 11 | The following commits have been cherry-picked from Glibc master branch: | ||
| 12 | Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847 | ||
| 13 | cmmit: c36fc50781995e6758cae2b6927839d0157f213c | ||
| 14 | |||
| 15 | Upstream-Status: Submitted | ||
| 16 | [https://sourceware.org/pipermail/libc-stable/2025-July/002278.html] | ||
| 17 | |||
| 18 | Signed-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 | |||
| 26 | diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c | ||
| 27 | index 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); | ||
| 121 | diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c | ||
| 122 | index 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; | ||
| 159 | diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h | ||
| 160 | index 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]; | ||
| 173 | diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h | ||
| 174 | index 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 | -- | ||
| 187 | 2.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 \ |
