This is an automated email from the ASF dual-hosted git repository.
jvanderzee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new fd08fdd268 Use `this_ethread()` for evacuation block alloc (#11623)
fd08fdd268 is described below
commit fd08fdd268a83c5236599cd914a3f1953bd42154
Author: JosiahWI <[email protected]>
AuthorDate: Tue Jul 30 14:48:47 2024 -0500
Use `this_ethread()` for evacuation block alloc (#11623)
* Use `this_ethread()` for evacuation block alloc
I would like to extract a new class to handle the responsibility of document
evacuation, but that is hard because the evacuation logic uses the thread
holding the `StripeSM` mutex to do the `EvacuationBlock` allocation. I think
this is a hacky way to get the current thread, so I want to switch the calls
to `this_ethread()` which doesn't depend on the mutex's internal data and
describes precisely what it does. I'm PRing this change all by itself
because
from the perspective of the `StripeSM` API it is a behavior change. I don't
think there can be too many debug asserts for this change so I've added them
to every call into the evacuation logic, although if any of these asserts
were
violated we'd probably already have seen horrendous damage to the
unprotected
doubly-linked `evacuate` list and more.
* Implement suggestion by Chris McFarlen
* Call `this_ethread()` directly in the `THREAD_ALLOC` invocation.
This is how it works everywhere else. Fewer parameters, more consistency.
Yay!!
---
src/iocore/cache/CacheDir.cc | 8 ++++----
src/iocore/cache/CacheRead.cc | 5 +++++
src/iocore/cache/P_CacheVol.h | 38 +++++++++++++++++++++++++++++---------
src/iocore/cache/StripeSM.cc | 15 +++++++++------
4 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/src/iocore/cache/CacheDir.cc b/src/iocore/cache/CacheDir.cc
index c50b872ddd..a68e8767d8 100644
--- a/src/iocore/cache/CacheDir.cc
+++ b/src/iocore/cache/CacheDir.cc
@@ -833,7 +833,7 @@ dir_lookaside_insert(EvacuationBlock *eblock, StripeSM
*stripe, Dir *to)
(int)dir_phase(to));
ink_assert(stripe->mutex->thread_holding == this_ethread());
int i = key->slice32(3) % LOOKASIDE_SIZE;
- EvacuationBlock *b =
new_EvacuationBlock(stripe->mutex->thread_holding);
+ EvacuationBlock *b = new_EvacuationBlock();
b->evac_frags.key = *key;
b->evac_frags.earliest_key = *key;
b->earliest_evacuator = eblock->earliest_evacuator;
@@ -858,7 +858,7 @@ dir_lookaside_fixup(const CacheKey *key, StripeSM *stripe)
int64_t o = dir_offset(&b->dir), n = dir_offset(&b->new_dir);
stripe->ram_cache->fixup(key, static_cast<uint64_t>(o),
static_cast<uint64_t>(n));
stripe->lookaside[i].remove(b);
- free_EvacuationBlock(b, stripe->mutex->thread_holding);
+ free_EvacuationBlock(b);
return res;
}
b = b->link.next;
@@ -880,7 +880,7 @@ dir_lookaside_cleanup(StripeSM *stripe)
b->evac_frags.earliest_key.slice32(1));
i.remove(b);
free_CacheEvacuateDocVC(b->earliest_evacuator);
- free_EvacuationBlock(b, stripe->mutex->thread_holding);
+ free_EvacuationBlock(b);
b = nb;
goto Lagain;
}
@@ -901,7 +901,7 @@ dir_lookaside_remove(const CacheKey *key, StripeSM *stripe)
DDbg(dbg_ctl_dir_lookaside, "remove %X %X offset %" PRId64 " phase %d",
key->slice32(0), key->slice32(1),
dir_offset(&b->new_dir), dir_phase(&b->new_dir));
stripe->lookaside[i].remove(b);
- free_EvacuationBlock(b, stripe->mutex->thread_holding);
+ free_EvacuationBlock(b);
return;
}
b = b->link.next;
diff --git a/src/iocore/cache/CacheRead.cc b/src/iocore/cache/CacheRead.cc
index 5fdbf5e125..4cd1a34a97 100644
--- a/src/iocore/cache/CacheRead.cc
+++ b/src/iocore/cache/CacheRead.cc
@@ -24,6 +24,10 @@
#include "P_Cache.h"
#include "P_CacheDoc.h"
+#ifdef DEBUG
+#include "iocore/eventsystem/EThread.h"
+#endif
+
namespace
{
@@ -559,6 +563,7 @@ CacheVC::openReadClose(int event, Event * /* e ATS_UNUSED
*/)
VC_SCHED_LOCK_RETRY();
}
if (f.hit_evacuate && dir_valid(stripe, &first_dir) && closed > 0) {
+ ink_assert(stripe->mutex->thread_holding == this_ethread());
if (f.single_fragment) {
stripe->force_evacuate_head(&first_dir, dir_pinned(&first_dir));
} else if (dir_valid(stripe, &earliest_dir)) {
diff --git a/src/iocore/cache/P_CacheVol.h b/src/iocore/cache/P_CacheVol.h
index a448b41f84..2098eafa99 100644
--- a/src/iocore/cache/P_CacheVol.h
+++ b/src/iocore/cache/P_CacheVol.h
@@ -196,11 +196,31 @@ public:
int evacuateWrite(CacheEvacuateDocVC *evacuator, int event, Event *e);
int evacuateDocReadDone(int event, Event *e);
- int evac_range(off_t start, off_t end, int evac_phase);
- void periodic_scan();
- void scan_for_pinned_documents();
- void evacuate_cleanup_blocks(int i);
- void evacuate_cleanup();
+ int evac_range(off_t start, off_t end, int evac_phase);
+ /**
+ *
+ * The caller must hold the mutex.
+ */
+ void periodic_scan();
+ /**
+ *
+ * The caller must hold the mutex.
+ */
+ void scan_for_pinned_documents();
+ /**
+ *
+ * The caller must hold the mutex.
+ */
+ void evacuate_cleanup_blocks(int i);
+ /**
+ *
+ * The caller must hold the mutex.
+ */
+ void evacuate_cleanup();
+ /**
+ *
+ * The caller must hold the mutex.
+ */
EvacuationBlock *force_evacuate_head(Dir const *dir, int pinned);
int within_hit_evacuate_window(Dir const *dir) const;
@@ -310,9 +330,9 @@ StripeSM::cancel_trigger()
}
inline EvacuationBlock *
-new_EvacuationBlock(EThread *t)
+new_EvacuationBlock()
{
- EvacuationBlock *b = THREAD_ALLOC(evacuationBlockAllocator, t);
+ EvacuationBlock *b = THREAD_ALLOC(evacuationBlockAllocator,
this_ethread());
b->init = 0;
b->readers = 0;
b->earliest_evacuator = nullptr;
@@ -321,7 +341,7 @@ new_EvacuationBlock(EThread *t)
}
inline void
-free_EvacuationBlock(EvacuationBlock *b, EThread *t)
+free_EvacuationBlock(EvacuationBlock *b)
{
EvacuationKey *e = b->evac_frags.link.next;
while (e) {
@@ -329,7 +349,7 @@ free_EvacuationBlock(EvacuationBlock *b, EThread *t)
evacuationKeyAllocator.free(e);
e = n;
}
- THREAD_FREE(b, evacuationBlockAllocator, t);
+ THREAD_FREE(b, evacuationBlockAllocator, this_ethread());
}
inline OpenDirEntry *
diff --git a/src/iocore/cache/StripeSM.cc b/src/iocore/cache/StripeSM.cc
index 2368c5283a..2e1fc0769b 100644
--- a/src/iocore/cache/StripeSM.cc
+++ b/src/iocore/cache/StripeSM.cc
@@ -133,8 +133,7 @@ StripeSM::begin_read(CacheVC *cont) const
}
// we don't actually need to preserve this block as it is already in
// memory, but this is easier, and evacuations are rare
- EThread *t = cont->mutex->thread_holding;
- b = new_EvacuationBlock(t);
+ b = new_EvacuationBlock();
b->readers = 1;
b->dir = cont->earliest_dir;
b->evac_frags.key = cont->earliest_key;
@@ -161,7 +160,7 @@ StripeSM::close_read(CacheVC *cont) const
}
if (b->readers && !--b->readers) {
evacuate[i].remove(b);
- free_EvacuationBlock(b, t);
+ free_EvacuationBlock(b);
break;
}
b = next;
@@ -663,6 +662,7 @@ StripeSM::handle_recover_write_dir(int /* event ATS_UNUSED
*/, void * /* data AT
init_info = nullptr;
set_io_not_in_progress();
scan_pos = header->write_pos;
+ ink_assert(this->mutex->thread_holding = this_ethread());
periodic_scan();
SET_HANDLER(&StripeSM::dir_init_done);
return dir_init_done(EVENT_IMMEDIATE, nullptr);
@@ -721,7 +721,7 @@ StripeSM::evacuate_cleanup_blocks(int i)
DDbg(dbg_ctl_cache_evac, "evacuate cleanup free %X offset %d",
(int)b->evac_frags.key.slice32(0), (int)dir_offset(&b->dir));
b = b->link.next;
evacuate[i].remove(x);
- free_EvacuationBlock(x, mutex->thread_holding);
+ free_EvacuationBlock(x);
continue;
}
b = b->link.next;
@@ -778,7 +778,7 @@ StripeSM::force_evacuate_head(Dir const *evac_dir, int
pinned)
}
if (!b) {
- b = new_EvacuationBlock(mutex->thread_holding);
+ b = new_EvacuationBlock();
b->dir = *evac_dir;
DDbg(dbg_ctl_cache_evac, "force: %d, %d", (int)dir_offset(evac_dir),
(int)dir_phase(evac_dir));
evacuate[bucket].push(b);
@@ -904,6 +904,7 @@ StripeSM::aggWriteDone(int event, Event *e)
header->last_write_pos);
ink_assert(header->write_pos == header->agg_pos);
if (header->write_pos + EVACUATION_SIZE > scan_pos) {
+ ink_assert(this->mutex->thread_holding == this_ethread());
periodic_scan();
}
this->_write_buffer.reset_buffer_pos();
@@ -1260,6 +1261,7 @@ StripeSM::agg_wrap()
Metrics::Counter::increment(stripe->cache_vol->vol_rsb.directory_wrap);
Note("Cache volume %d on disk '%s' wraps around",
stripe->cache_vol->vol_number, stripe->hash_text.get());
}
+ ink_assert(this->mutex->thread_holding = this_ethread());
periodic_scan();
}
@@ -1393,6 +1395,7 @@ StripeSM::evacuateDocReadDone(int event, Event *e)
// Cache::open_write).
if (!dir_head(&b->dir) || !dir_compare_tag(&b->dir, &doc->first_key)) {
next_CacheKey(&next_key, &doc->key);
+ ink_assert(this->mutex->thread_holding == this_ethread());
evacuate_fragments(&next_key, &doc_evacuator->earliest_key, !b->readers,
this);
}
return evacuateWrite(doc_evacuator, event, e);
@@ -1415,7 +1418,7 @@ evacuate_fragments(CacheKey *key, CacheKey *earliest_key,
int force, StripeSM *s
}
EvacuationBlock *b = evacuation_block_exists(&dir, stripe);
if (!b) {
- b =
new_EvacuationBlock(stripe->mutex->thread_holding);
+ b = new_EvacuationBlock();
b->dir = dir;
b->evac_frags.key = *key;
b->evac_frags.earliest_key = *earliest_key;