Skip to content

Commit

Permalink
Merge pull request #10447 from neondatabase/releases/2025-01-20-hotfix
Browse files Browse the repository at this point in the history
Release: storage hotfix 2025-01-20
  • Loading branch information
problame authored Jan 20, 2025
2 parents 3399eea + e0c504a commit 4dec0dd
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions pageserver/src/tenant/timeline/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,32 +588,40 @@ impl<T: Types> Drop for Cache<T> {
let Some(handle_inner_arc) = handle_inner_weak.upgrade() else {
continue;
};
let handle_timeline = handle_inner_arc
let Some(handle_timeline) = handle_inner_arc
// locking rules: drop lock before acquiring other lock below
.lock()
.expect("poisoned")
.shutdown();
.shutdown()
else {
// Concurrent PerTimelineState::shutdown.
continue;
};
// Clean up per_timeline_state so the HandleInner allocation can be dropped.
let per_timeline_state = handle_timeline.per_timeline_state();
let mut handles_lock_guard = per_timeline_state.handles.lock().expect("mutex poisoned");
let Some(handles) = &mut *handles_lock_guard else {
continue;
};
let Some(removed_handle_inner_arc) = handles.remove(&self.id) else {
// There could have been a shutdown inbetween us upgrading the weak and locking the mutex.
// Concurrent PerTimelineState::shutdown.
continue;
};
drop(handles_lock_guard); // locking rules: remember them when!
assert!(Arc::ptr_eq(&removed_handle_inner_arc, &handle_inner_arc,));
drop(handles_lock_guard); // locking rules!
assert!(Arc::ptr_eq(&removed_handle_inner_arc, &handle_inner_arc));
}
}
}

impl<T: Types> HandleInner<T> {
fn shutdown(&mut self) -> Arc<T::Timeline> {
fn shutdown(&mut self) -> Option<Arc<T::Timeline>> {
match std::mem::replace(self, HandleInner::ShutDown) {
HandleInner::KeepingTimelineGateOpen { timeline, .. } => timeline,
HandleInner::KeepingTimelineGateOpen { timeline, .. } => Some(timeline),
HandleInner::ShutDown => {
unreachable!("handles are only shut down once in their lifetime");
// Duplicate shutdowns are possible because both Cache::drop and PerTimelineState::shutdown
// may do it concurrently, but locking rules disallow holding per-timeline-state lock and
// the handle lock at the same time.
None
}
}
}
Expand Down

1 comment on commit 4dec0dd

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6680 tests run: 6348 passed, 0 failed, 332 skipped (full report)


Flaky tests (4)

Postgres 17

Postgres 14

Test coverage report is not available

The comment gets automatically updated with the latest test results
4dec0dd at 2025-01-20T15:44:47.628Z :recycle:

Please sign in to comment.