]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd/PG: support is_locked() in non-debug mode
authorKefu Chai <kchai@redhat.com>
Sat, 20 Jul 2019 11:34:02 +0000 (19:34 +0800)
committerKefu Chai <kchai@redhat.com>
Sat, 3 Aug 2019 03:27:21 +0000 (11:27 +0800)
`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 <kchai@redhat.com>
src/osd/PG.cc
src/osd/PG.h

index 64c99990a7ac9276ffec7664dc22de4412c20753..238698da13c39f4c8fa34fda106d7418a7fca11f 100644 (file)
@@ -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;
index beffac1a8a11cd10cb229b36bac5c37e121ae5f7..7482add43971c05cecdf1cf3aaf100652bccca3a 100644 (file)
@@ -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<unsigned int> ref{0};
 
 #ifdef PG_DEBUG_REFS