-
Type:
Task
-
Resolution: Unresolved
-
Priority:
Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: Cache and Eviction
-
None
-
Storage Engines - Transactions
-
286.234
-
SE Transactions - 2026-09-25
-
3
Background
WT-18238 fixed a TSan-reported data race on eviction_dirty_trigger, eviction_dirty_target, and eviction_updates_trigger — these three fields are written both by WT_CONNECTION::reconfigure and by a runtime actor (connection close and/or checkpoint), and are read from hot paths without synchronization. That fix converted all access to the relaxed-atomic helpers (_wt_atomic_load_double_relaxed / _wt_atomic_store_double_relaxed) and added wt_shared annotations where missing.
Four sibling fields in the same WT_EVICT struct were deliberately left out of that fix because their only runtime writer is WT_CONNECTION::reconfigure (no connection-close or checkpoint writer):
- eviction_trigger (the "clean" trigger)
- eviction_target (the "clean" target)
- eviction_updates_target
- eviction_checkpoint_target
Problem
WT_CONNECTION::reconfigure can be called at any time while the connection is active, concurrently with eviction threads, the cache pool, and load control — all of which read these four fields with plain (non-atomic) loads on hot paths (evict_thread.c, evict_inline.h, evict_walk.c, cache_pool.c, conn_load_control.c). This is the same class of unsynchronized concurrent access as WT-18238, just not yet caught by TSan in CI — it is a latent defect rather than a confirmed failure.
Existing partial atomicity: eviction_target, eviction_trigger, and eviction_updates_target are already read atomically in exactly one place — _wt_evict_stats_update in evict_conn.c (~line 449-457), which reports them via wt_atomic_load_double_relaxed for statistics output. Every other access site for these three fields (hot paths listed above, and the _evict_validate_config reconfigure/validation logic itself) is still a plain load/store. So these three fields are not "not yet atomic" but "inconsistently atomic" — the fix needs to unify all sites, not introduce atomicity from scratch. eviction_checkpoint_target has no pre-existing atomic access anywhere; it is fully plain.
Rough scope from investigation (~50 access points across 7 files):
- eviction_trigger: ~18 access points (evict_conn.c, evict_thread.c, evict_inline.h, cache_pool.c, conn_load_control.c)
- eviction_target: ~12 access points (evict_thread.c, evict_inline.h, evict_walk.c, evict_conn.c, cache_pool.c)
- eviction_updates_target: ~11 access points (evict_walk.c, evict_thread.c, evict_conn.c)
- eviction_checkpoint_target: ~9 access points (evict_conn.c, checkpoint_txn.c)
Fix
Same mechanical pattern as WT-18238: convert all reads/writes of these four fields to _wt_atomic_load_double_relaxed/_wt_atomic_store_double_relaxed, and add the wt_shared annotation to their declarations in evict.h (currently missing on all four). For eviction_target/eviction_trigger/eviction_updates_target, this also resolves the existing atomic/non-atomic inconsistency between the stats-reporting path and every other access site.
Explicitly out of scope
This ticket is not about WT-17015. WT-17015 is scoped to the checkpoint eviction-trigger start/end restore mechanism (__checkpoint_update_evict_triggers_start/_end), which needs true compare-and-swap semantics (load current value, compare against a remembered expected value, conditionally restore) and cannot use a plain atomic store — a different and harder problem than this ticket's plain atomicity cleanup. Do not conflate the two.