mirror of
https://github.com/redis/redis.git
synced 2026-07-16 13:32:51 -04:00
Fix race condition for lookupCommand (#14466)
Fixes data race where main thread modifies pauserehash in dictNext while IO thread reads `useStoredKeyApi()` in `lookupCommand()->dictFind()` path. ASAN detected overlapping memory access at same byte offset causing race condition. When bit fields are adjacent in a struct, modifying one bit field requires a read-modify-write operation on the entire memory unit, which can cause race conditions with concurrent access to other bit fields in the same unit. This was introduced by https://github.com/redis/redis/pull/13696, although it was changed by https://github.com/redis/redis/pull/14440, but this issue still exist. The fix moves `useStoredKeyApi` to share a memory word with `pauseAutoResize` instead. Since `pauseAutoResize` is never modified for `server.commands`, this eliminates the race condition while maintaining memory efficiency through bit field packing. Reproduce step: ``` make SANITIZER=thread ./runtest --tsan --config io-threads 4 --accurate --verbose --dump-logs --single unit/obuf-limits --loop --stop ``` failed CI: https://github.com/redis/redis/actions/runs/18803219305/job/53653572710 --------- Co-authored-by: Moti Cohen <moti.cohen@redis.com>
This commit is contained in:
parent
91b5808fd6
commit
6ea4e2c949
1 changed files with 6 additions and 4 deletions
10
src/dict.h
10
src/dict.h
|
|
@ -127,12 +127,14 @@ struct dict {
|
|||
|
||||
long rehashidx; /* rehashing not in progress if rehashidx == -1 */
|
||||
|
||||
/* Keep small vars at end for optimal (minimal) struct padding */
|
||||
unsigned pauserehash : 15; /* If >0 rehashing is paused */
|
||||
/* Note: pauserehash is a full unsigned so iterator increments
|
||||
* don't perform RMW on the same storage unit as other bitfields. */
|
||||
unsigned pauserehash; /* If >0 rehashing is paused */
|
||||
|
||||
unsigned useStoredKeyApi : 1; /* See comment of storedHashFunction above */
|
||||
/* Keep small vars at end for optimal (minimal) struct padding */
|
||||
signed char ht_size_exp[2]; /* exponent of size. (size = 1<<exp) */
|
||||
int16_t pauseAutoResize; /* If >0 automatic resizing is disallowed (<0 indicates coding error) */
|
||||
signed pauseAutoResize: 15; /* If >0 automatic resizing is disallowed (<0 indicates coding error) */
|
||||
unsigned useStoredKeyApi: 1; /* See comment of storedHashFunction above */
|
||||
void *metadata[];
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue