From: Kefu Chai Date: Sun, 8 Aug 2021 17:21:38 +0000 (+0800) Subject: crimson/common: instantiate interrupt_cond in .cc X-Git-Tag: v17.1.0~1168^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c037e9562215ac6a005e62f70ca20818076cc5c3;p=ceph.git crimson/common: instantiate interrupt_cond in .cc so we can explicitly instantiate it. this should address the segfault when accessing interrupt_cond when it is defined as a plain thread local storage template variable in the header file. it seems Clang is not able to identify the access to TLS variable and the value of %fs segment register of the main thread is always zero if interrupt_cond is defined as a plain global variable stored in thread local storage. Signed-off-by: Kefu Chai --- diff --git a/src/crimson/common/interruptible_future.h b/src/crimson/common/interruptible_future.h index 51b50f04ebb6..8fdbd03cf2e6 100644 --- a/src/crimson/common/interruptible_future.h +++ b/src/crimson/common/interruptible_future.h @@ -42,6 +42,22 @@ // interruptor::with_interruption() and helpers can be used by users to wrap a future in // the interruption machinery. +namespace crimson::os::seastore { + class TransactionConflictCondition; +} + +// GCC tries to instantiate +// seastar::lw_shared_ptr. +// but we *may* not have the definition of TransactionConflictCondition at this moment, +// a full specialization for lw_shared_ptr_accessors helps to bypass the default +// lw_shared_ptr_accessors implementation, where std::is_base_of<.., T> is used. +namespace seastar::internal { + template<> + struct lw_shared_ptr_accessors<::crimson::os::seastore::TransactionConflictCondition, void> + : lw_shared_ptr_accessors_no_esft<::crimson::os::seastore::TransactionConflictCondition> + {}; +} + namespace crimson::interruptible { struct ready_future_marker {}; @@ -58,6 +74,8 @@ using InterruptCondRef = seastar::lw_shared_ptr; template thread_local InterruptCondRef interrupt_cond; +extern template thread_local InterruptCondRef +interrupt_cond; template class [[nodiscard]] interruptible_future_detail {}; @@ -439,7 +457,7 @@ public: using ex_type = typename trait::template arg<0>::type; return core_type::then_wrapped( [func=std::forward(func), - interrupt_condition=interrupt_cond](auto&& fut) mutable + interrupt_condition=interrupt_cond](auto&& fut) mutable -> Result { if (!fut.failed()) { return seastar::make_ready_future(fut.get()); diff --git a/src/crimson/os/seastore/CMakeLists.txt b/src/crimson/os/seastore/CMakeLists.txt index 08d7605528c7..71050d099e0e 100644 --- a/src/crimson/os/seastore/CMakeLists.txt +++ b/src/crimson/os/seastore/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(crimson-seastore STATIC segment_manager/ephemeral.cc segment_manager/block.cc transaction_manager.cc + transaction.cc journal.cc cache.cc lba_manager.cc diff --git a/src/crimson/os/seastore/transaction.cc b/src/crimson/os/seastore/transaction.cc new file mode 100644 index 000000000000..ce02a95ef918 --- /dev/null +++ b/src/crimson/os/seastore/transaction.cc @@ -0,0 +1,8 @@ +#include "transaction.h" +#include "crimson/common/interruptible_future.h" + +namespace crimson::interruptible { +template +thread_local InterruptCondRef<::crimson::os::seastore::TransactionConflictCondition> +interrupt_cond<::crimson::os::seastore::TransactionConflictCondition>; +} diff --git a/src/test/crimson/test_interruptible_future.cc b/src/test/crimson/test_interruptible_future.cc index bc59119f9176..c6af5f4957e9 100644 --- a/src/test/crimson/test_interruptible_future.cc +++ b/src/test/crimson/test_interruptible_future.cc @@ -39,6 +39,12 @@ private: bool interrupt = false; }; +namespace crimson::interruptible { +template +thread_local InterruptCondRef +interrupt_cond; +} + TEST_F(seastar_test_suite_t, basic) { using interruptor =