Commit 831d84b5 authored by Maged Michael's avatar Maged Michael Committed by Facebook GitHub Bot

hazptr: Add warnings for pathological performance.

Summary:
Add warnings for pathological cases:
- Too large retired lists
- Thread cache overflow

Move the warning for executor backlog to a separate function for clearer profiling.

Reviewed By: davidtgoldblatt

Differential Revision: D21314798

fbshipit-source-id: e07d6182309a0940adbdf76774a9c44fb1aa200c
parent 2ee65365
...@@ -113,6 +113,7 @@ class hazptr_domain { ...@@ -113,6 +113,7 @@ class hazptr_domain {
static constexpr int kThreshold = detail::hazptr_domain_rcount_threshold(); static constexpr int kThreshold = detail::hazptr_domain_rcount_threshold();
static constexpr int kMultiplier = 2; static constexpr int kMultiplier = 2;
static constexpr int kListTooLarge = 100000;
static constexpr uint64_t kSyncTimePeriod{2000000000}; // nanoseconds static constexpr uint64_t kSyncTimePeriod{2000000000}; // nanoseconds
static constexpr uintptr_t kTagBit = hazptr_obj<Atom>::kTagBit; static constexpr uintptr_t kTagBit = hazptr_obj<Atom>::kTagBit;
...@@ -304,6 +305,10 @@ class hazptr_domain { ...@@ -304,6 +305,10 @@ class hazptr_domain {
RetiredList& rlist, RetiredList& rlist,
bool lock, bool lock,
Atom<uint64_t>& sync_time) { Atom<uint64_t>& sync_time) {
int rcount = rlist.count();
if (rcount > kListTooLarge) {
warning_list_too_large(rlist, lock, rcount);
}
if (!(lock && rlist.check_lock()) && if (!(lock && rlist.check_lock()) &&
(rlist.check_threshold_try_zero_count(threshold()) || (rlist.check_threshold_try_zero_count(threshold()) ||
check_sync_time(sync_time))) { check_sync_time(sync_time))) {
...@@ -317,6 +322,17 @@ class hazptr_domain { ...@@ -317,6 +322,17 @@ class hazptr_domain {
} }
} }
/** warning_list_too_large **/
FOLLY_NOINLINE void
warning_list_too_large(RetiredList& rlist, bool lock, int rcount) {
static std::atomic<uint64_t> warning_count{0};
if ((warning_count++ % 10000) == 0) {
LOG(WARNING) << "Hazptr retired list too large:"
<< " rlist=" << &rlist << " lock=" << lock
<< " rcount=" << rcount;
}
}
/** check_sync_time_and_reclaim **/ /** check_sync_time_and_reclaim **/
void check_sync_time_and_reclaim() { void check_sync_time_and_reclaim() {
if (!tagged_.check_lock() && check_sync_time()) { if (!tagged_.check_lock() && check_sync_time()) {
...@@ -632,11 +648,18 @@ class hazptr_domain { ...@@ -632,11 +648,18 @@ class hazptr_domain {
LOG(INFO) << "Skip asynchronous reclamation by hazptr executor"; LOG(INFO) << "Skip asynchronous reclamation by hazptr executor";
} }
if (backlog >= 10) { if (backlog >= 10) {
warning_executor_backlog(backlog);
}
}
FOLLY_NOINLINE void warning_executor_backlog(int backlog) {
static std::atomic<uint64_t> warning_count{0};
if ((warning_count++ % 10000) == 0) {
LOG(WARNING) << backlog LOG(WARNING) << backlog
<< " request backlog for hazptr reclamation executora"; << " request backlog for hazptr reclamation executora";
} }
} }
}; // hazptr_domain }; // namespace folly
/** /**
* Free functions related to hazptr domains * Free functions related to hazptr domains
......
...@@ -113,9 +113,17 @@ class hazptr_tc { ...@@ -113,9 +113,17 @@ class hazptr_tc {
entry_[count_++].fill(hprec); entry_[count_++].fill(hprec);
return true; return true;
} }
warning_tc_overflow();
return false; return false;
} }
FOLLY_NOINLINE void warning_tc_overflow() {
static std::atomic<uint64_t> warning_count{0};
if ((warning_count++ % 10000) == 0) {
LOG(WARNING) << "Hazptr thread cache overflow " << this;
}
}
FOLLY_ALWAYS_INLINE uint8_t count() const noexcept { FOLLY_ALWAYS_INLINE uint8_t count() const noexcept {
return count_; return count_;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment