Skip to content

feat(cache): make FileCachePool thread-safe for multi-vCPU access - #1555

Merged
EricHuangqx merged 2 commits into
alibaba:mainfrom
xiaoyang-hhh:cache/multi-vcpu
Jul 22, 2026
Merged

feat(cache): make FileCachePool thread-safe for multi-vCPU access#1555
EricHuangqx merged 2 commits into
alibaba:mainfrom
xiaoyang-hhh:cache/multi-vcpu

Conversation

@xiaoyang-hhh

@xiaoyang-hhh xiaoyang-hhh commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

What

Make a single FileCachePool safe to use concurrently from multiple photon vCPUs (OS threads).

How

  • Add a photon::mutex m_lock_ guarding all pool metadata (fileIndex_, lru_, cold tiers, totalUsed_).
  • Lock order is one-way rw_lock → m_lock_: m_lock_ is held only across in-memory ops.
  • eviction/evict: snapshot victim under m_lock_ → release → do I/O (open()+WLOCK truncate) → re-lock to finalize.
  • Write path accounts size under the store rw_lock (updateSpace fstats under m_lock_), so accounting can't drift against eviction's WLOCK+truncate; forceRecycle() deferred to do_pwritev2 after the rw_lock is released.
  • running_/exit_/isFull_ and LruEntry::truncate_donestd::atomic.

Tests

  • New CachePool.concurrent_stress: writers vs evictors on a shared small file set across N vCPUs (max per-file rw_lock contention). Validates no crash/hang/metadata-corruption/totalUsed_ drift.
  • Full cache_test (18 tests) passes; concurrent_stress runs 100× with no deadlock.
  • Also validated end-to-end against ossfs2: all related tests pass, no deadlock/crash.

Not in scope

QuotaFilePool is not made thread-safe; documented with a TODO.

@xiaoyang-hhh
xiaoyang-hhh marked this pull request as ready for review July 16, 2026 07:52
@xiaoyang-hhh
xiaoyang-hhh marked this pull request as draft July 16, 2026 09:25
@lihuiba
lihuiba requested a review from Coldwings July 16, 2026 11:22
Guard all FileCachePool metadata (fileIndex_, lru_, cold tiers, totalUsed_,
tuning state) with a coarse photon::mutex (m_lock_) so one pool can be shared
across multiple photon vCPUs (OS threads).

Invariants:
- m_lock_ is held only across in-memory ops; never across open()/do_open() or
  forceRecycle()/eviction(), keeping the lock order rw_lock -> m_lock_ one-way
  (avoids ABBA with ObjectCache's per-item mutex and non-reentrant self-deadlock).
- eviction/evict snapshot a victim under m_lock_, release it, do the I/O
  (open()+WLOCK truncate), then re-lock to finalize.
- the write path accounts size under the store rw_lock (updateSpace fstats under
  m_lock_) so it can't drift against eviction's WLOCK+truncate; forceRecycle()
  is deferred to do_pwritev2 after rw_lock is released.
- running_/exit_/isFull_ and LruEntry::truncate_done become std::atomic.

Add a multi-vCPU concurrency stress test (CachePool.concurrent_stress).

QuotaFilePool is left unchanged and documented as not-yet-thread-safe (it is
currently unwired: the factory always builds a plain FileCachePool).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lihuiba
lihuiba requested a review from EricHuangqx July 18, 2026 03:48
@xiaoyang-hhh
xiaoyang-hhh marked this pull request as ready for review July 20, 2026 06:24
@EricHuangqx
EricHuangqx merged commit eef65fb into alibaba:main Jul 22, 2026
20 checks passed
xiaoyang-hhh added a commit that referenced this pull request Jul 27, 2026
)

* feat(cache): make FileCachePool thread-safe for multi-vCPU access

Guard all FileCachePool metadata (fileIndex_, lru_, cold tiers, totalUsed_,
tuning state) with a coarse photon::mutex (m_lock_) so one pool can be shared
across multiple photon vCPUs (OS threads).

Invariants:
- m_lock_ is held only across in-memory ops; never across open()/do_open() or
  forceRecycle()/eviction(), keeping the lock order rw_lock -> m_lock_ one-way
  (avoids ABBA with ObjectCache's per-item mutex and non-reentrant self-deadlock).
- eviction/evict snapshot a victim under m_lock_, release it, do the I/O
  (open()+WLOCK truncate), then re-lock to finalize.
- the write path accounts size under the store rw_lock (updateSpace fstats under
  m_lock_) so it can't drift against eviction's WLOCK+truncate; forceRecycle()
  is deferred to do_pwritev2 after rw_lock is released.
- running_/exit_/isFull_ and LruEntry::truncate_done become std::atomic.

Add a multi-vCPU concurrency stress test (CachePool.concurrent_stress).

QuotaFilePool is left unchanged and documented as not-yet-thread-safe (it is
currently unwired: the factory always builds a plain FileCachePool).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* check total used in eviction loop

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
lihuiba pushed a commit that referenced this pull request Jul 27, 2026
) (#1571)

* feat(cache): make FileCachePool thread-safe for multi-vCPU access

Guard all FileCachePool metadata (fileIndex_, lru_, cold tiers, totalUsed_,
tuning state) with a coarse photon::mutex (m_lock_) so one pool can be shared
across multiple photon vCPUs (OS threads).

Invariants:
- m_lock_ is held only across in-memory ops; never across open()/do_open() or
  forceRecycle()/eviction(), keeping the lock order rw_lock -> m_lock_ one-way
  (avoids ABBA with ObjectCache's per-item mutex and non-reentrant self-deadlock).
- eviction/evict snapshot a victim under m_lock_, release it, do the I/O
  (open()+WLOCK truncate), then re-lock to finalize.
- the write path accounts size under the store rw_lock (updateSpace fstats under
  m_lock_) so it can't drift against eviction's WLOCK+truncate; forceRecycle()
  is deferred to do_pwritev2 after rw_lock is released.
- running_/exit_/isFull_ and LruEntry::truncate_done become std::atomic.

Add a multi-vCPU concurrency stress test (CachePool.concurrent_stress).

QuotaFilePool is left unchanged and documented as not-yet-thread-safe (it is
currently unwired: the factory always builds a plain FileCachePool).



* check total used in eviction loop

---------

Co-authored-by: Xiaoyang Lu <luxiaoyang.lxy@alibaba-inc.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants