From aeb20dd2f5d757d1aa377022977d2277f4eac8ad Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Fri, 11 Sep 2020 19:01:52 +0800 Subject: [PATCH] crimson/object_context: make obc interruptible * add tri_mutex::abort() to pass given exception to all waiters * add ObjectContext::interrupt() to abort all pending consumers of current object context Fixes: https://tracker.ceph.com/issues/47311 Signed-off-by: Xuehan Xu Signed-off-by: Kefu Chai --- src/crimson/common/tri_mutex.h | 10 ++++++++++ src/crimson/osd/object_context.h | 10 ++++++++++ src/crimson/osd/recovery_backend.cc | 4 +++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/crimson/common/tri_mutex.h b/src/crimson/common/tri_mutex.h index 63ca81a1542..d8c8e66fbb6 100644 --- a/src/crimson/common/tri_mutex.h +++ b/src/crimson/common/tri_mutex.h @@ -35,6 +35,16 @@ public: bool is_acquired() const; + /// pass the provided exception to any waiting waiters + template + void abort(Exception ex) { + while (!waiters.empty()) { + auto& waiter = waiters.front(); + waiter.pr.set_exception(std::make_exception_ptr(ex)); + waiters.pop_front(); + } + } + private: void wake(); unsigned readers = 0; diff --git a/src/crimson/osd/object_context.h b/src/crimson/osd/object_context.h index 3bd6073d9e6..6f158bbd64e 100644 --- a/src/crimson/osd/object_context.h +++ b/src/crimson/osd/object_context.h @@ -11,6 +11,7 @@ #include "common/intrusive_lru.h" #include "osd/object_state.h" +#include "crimson/common/exception.h" #include "crimson/common/tri_mutex.h" #include "crimson/osd/osd_operation.h" @@ -84,6 +85,15 @@ public: loaded = true; } + /// pass the provided exception to any waiting consumers of this ObjectContext + template + void interrupt(Exception ex) { + rwlock.abort(std::move(ex)); + if (recovery_read_marker) { + drop_recovery_read(); + } + } + private: tri_mutex rwlock; bool recovery_read_marker = false; diff --git a/src/crimson/osd/recovery_backend.cc b/src/crimson/osd/recovery_backend.cc index 77a5480a975..c3c4ed9a5c8 100644 --- a/src/crimson/osd/recovery_backend.cc +++ b/src/crimson/osd/recovery_backend.cc @@ -42,7 +42,9 @@ void RecoveryBackend::clean_up(ceph::os::Transaction& t, if ((recovery_waiter.pi && recovery_waiter.pi->is_complete()) || (!recovery_waiter.pi && recovery_waiter.obc && recovery_waiter.obc->obs.exists)) { - recovery_waiter.obc->drop_recovery_read(); + recovery_waiter.obc->interrupt( + ::crimson::common::actingset_changed( + pg.is_primary())); recovery_waiter.interrupt(why); } } -- 2.39.5