From 9eead2052b3a6c247b7173a6b0ec9d7c3f343e64 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Sat, 20 Jul 2019 19:34:02 +0800 Subject: [PATCH] osd/PG: support is_locked() in non-debug mode `PG` print details info in the prefix of logging messages if the PG is being locked by current thread. but `ceph::mutex` is an alias of `std::mutex` in non-debug mode, so neither `mutex::is_locked_by_me()` nor `mutex::is_locked()` is supported in non-debug mode. to continue supporting this feature, `PG::locked_by` is added to memorize the thread id of the owner of the lock. Signed-off-by: Kefu Chai --- src/osd/PG.cc | 30 +++++++++++++++++++++++++++--- src/osd/PG.h | 14 +++++--------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 64c99990a7a..238698da13c 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -226,17 +226,41 @@ PG::~PG() void PG::lock(bool no_lockdep) const { +#ifdef CEPH_DEBUG_MUTEX _lock.lock(no_lockdep); +#else + _lock.lock(); + locked_by = std::this_thread::get_id(); +#endif // if we have unrecorded dirty state with the lock dropped, there is a bug ceph_assert(!recovery_state.debug_has_dirty_state()); dout(30) << "lock" << dendl; } +bool PG::is_locked() const +{ + return ceph_mutex_is_locked(_lock); +} + +void PG::unlock() const +{ + //generic_dout(0) << this << " " << info.pgid << " unlock" << dendl; + ceph_assert(!recovery_state.debug_has_dirty_state()); +#ifndef CEPH_DEBUG_MUTEX + locked_by = {}; +#endif + _lock.unlock(); +} + std::ostream& PG::gen_prefix(std::ostream& out) const { OSDMapRef mapref = recovery_state.get_osdmap(); +#ifdef CEPH_DEBUG_MUTEX if (_lock.is_locked_by_me()) { +#else + if (locked_by == std::this_thread::get_id()) { +#endif out << "osd." << osd->whoami << " pg_epoch: " << (mapref ? mapref->get_epoch():0) << " " << *this << " "; @@ -389,7 +413,7 @@ bool PG::op_has_sufficient_caps(OpRequestRef& op) bool PG::requeue_scrub(bool high_priority) { - ceph_assert(is_locked()); + ceph_assert(ceph_mutex_is_locked(_lock)); if (scrub_queued) { dout(10) << __func__ << ": already queued" << dendl; return false; @@ -417,7 +441,7 @@ void PG::queue_recovery() bool PG::queue_scrub() { - ceph_assert(is_locked()); + ceph_assert(ceph_mutex_is_locked(_lock)); if (is_scrubbing()) { return false; } @@ -1323,7 +1347,7 @@ void PG::requeue_map_waiters() // returns true if a scrub has been newly kicked off bool PG::sched_scrub() { - ceph_assert(is_locked()); + ceph_assert(ceph_mutex_is_locked(_lock)); ceph_assert(!is_scrubbing()); if (!(is_primary() && is_active() && is_clean())) { return false; diff --git a/src/osd/PG.h b/src/osd/PG.h index beffac1a8a1..7482add4397 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -217,14 +217,8 @@ public: handle.reset_tp_timeout(); } void lock(bool no_lockdep = false) const; - void unlock() const { - //generic_dout(0) << this << " " << info.pgid << " unlock" << dendl; - ceph_assert(!recovery_state.debug_has_dirty_state()); - _lock.unlock(); - } - bool is_locked() const { - return _lock.is_locked(); - } + void unlock() const; + bool is_locked() const; const spg_t& get_pgid() const { return pg_id; @@ -608,7 +602,9 @@ protected: // put() should be called on destruction of some previously copied pointer. // unlock() when done with the current pointer (_most common_). mutable ceph::mutex _lock = ceph::make_mutex("PG::_lock"); - +#ifndef CEPH_DEBUG_MUTEX + mutable std::thread::id locked_by; +#endif std::atomic ref{0}; #ifdef PG_DEBUG_REFS -- 2.39.5