Skip to content

Commit e31058a

Browse files
committed
crimson/os/seastore/cache: monitor dirty cache by extent and trans
Signed-off-by: Yingxin Cheng <[email protected]>
1 parent f7e4f0d commit e31058a

File tree

3 files changed

+91
-25
lines changed

3 files changed

+91
-25
lines changed

src/crimson/os/seastore/cache.cc

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -742,10 +742,12 @@ void Cache::mark_dirty(CachedExtentRef ref)
742742

743743
lru.remove_from_lru(*ref);
744744
ref->state = CachedExtent::extent_state_t::DIRTY;
745-
add_to_dirty(ref);
745+
add_to_dirty(ref, nullptr);
746746
}
747747

748-
void Cache::add_to_dirty(CachedExtentRef ref)
748+
void Cache::add_to_dirty(
749+
CachedExtentRef ref,
750+
const Transaction::src_t* p_src)
749751
{
750752
assert(ref->is_dirty());
751753
assert(!ref->primary_ref_list_hook.is_linked());
@@ -756,23 +758,53 @@ void Cache::add_to_dirty(CachedExtentRef ref)
756758
// also see CachedExtent::is_stable_writting()
757759
intrusive_ptr_add_ref(&*ref);
758760
dirty.push_back(*ref);
759-
stats.dirty_bytes += ref->get_length();
761+
762+
auto extent_length = ref->get_length();
763+
stats.dirty_bytes += extent_length;
764+
get_by_ext(
765+
stats.dirty_sizes_by_ext,
766+
ref->get_type()
767+
).account_in(extent_length);
768+
if (p_src != nullptr) {
769+
assert(!is_root_type(ref->get_type()));
770+
get_by_ext(
771+
get_by_src(stats.dirty_io_by_src_ext, *p_src),
772+
ref->get_type()
773+
).in_sizes.account_in(extent_length);
774+
}
760775
}
761776

762-
void Cache::remove_from_dirty(CachedExtentRef ref)
777+
void Cache::remove_from_dirty(
778+
CachedExtentRef ref,
779+
const Transaction::src_t* p_src)
763780
{
764781
assert(ref->is_dirty());
765782
ceph_assert(ref->primary_ref_list_hook.is_linked());
766783
assert(ref->is_fully_loaded());
767784

768-
stats.dirty_bytes -= ref->get_length();
785+
auto extent_length = ref->get_length();
786+
stats.dirty_bytes -= extent_length;
787+
get_by_ext(
788+
stats.dirty_sizes_by_ext,
789+
ref->get_type()
790+
).account_out(extent_length);
791+
if (p_src != nullptr) {
792+
assert(!is_root_type(ref->get_type()));
793+
auto& dirty_stats = get_by_ext(
794+
get_by_src(stats.dirty_io_by_src_ext, *p_src),
795+
ref->get_type());
796+
dirty_stats.out_sizes.account_in(extent_length);
797+
dirty_stats.out_versions += ref->get_version();
798+
}
799+
769800
dirty.erase(dirty.s_iterator_to(*ref));
770801
intrusive_ptr_release(&*ref);
771802
}
772803

773804
void Cache::replace_dirty(
774805
CachedExtentRef next,
775-
CachedExtentRef prev)
806+
CachedExtentRef prev,
807+
const Transaction::src_t& src)
776808
{
777809
assert(prev->is_dirty());
778810
ceph_assert(prev->primary_ref_list_hook.is_linked());
@@ -790,6 +822,10 @@ void Cache::replace_dirty(
790822
assert(!is_root_type(next->get_type()));
791823
assert(prev->get_type() == next->get_type());
792824

825+
get_by_ext(
826+
get_by_src(stats.dirty_io_by_src_ext, src),
827+
next->get_type()).num_replace += 1;
828+
793829
auto prev_it = dirty.iterator_to(*prev);
794830
dirty.insert(prev_it, *next);
795831
dirty.erase(prev_it);
@@ -805,18 +841,26 @@ void Cache::clear_dirty()
805841
ceph_assert(ptr->primary_ref_list_hook.is_linked());
806842
assert(ptr->is_fully_loaded());
807843

808-
stats.dirty_bytes -= ptr->get_length();
844+
auto extent_length = ptr->get_length();
845+
stats.dirty_bytes -= extent_length;
846+
get_by_ext(
847+
stats.dirty_sizes_by_ext,
848+
ptr->get_type()
849+
).account_out(extent_length);
850+
809851
dirty.erase(i++);
810852
intrusive_ptr_release(ptr);
811853
}
812854
assert(stats.dirty_bytes == 0);
813855
}
814856

815-
void Cache::remove_extent(CachedExtentRef ref)
857+
void Cache::remove_extent(
858+
CachedExtentRef ref,
859+
const Transaction::src_t* p_src)
816860
{
817861
assert(ref->is_valid());
818862
if (ref->is_dirty()) {
819-
remove_from_dirty(ref);
863+
remove_from_dirty(ref, p_src);
820864
} else if (!ref->is_placeholder()) {
821865
lru.remove_from_lru(*ref);
822866
}
@@ -827,7 +871,8 @@ void Cache::commit_retire_extent(
827871
Transaction& t,
828872
CachedExtentRef ref)
829873
{
830-
remove_extent(ref);
874+
const auto t_src = t.get_src();
875+
remove_extent(ref, &t_src);
831876

832877
ref->dirty_from_or_retired_at = JOURNAL_SEQ_NULL;
833878
invalidate_extent(t, *ref);
@@ -842,19 +887,20 @@ void Cache::commit_replace_extent(
842887
assert(next->version == prev->version + 1);
843888
extents.replace(*next, *prev);
844889

890+
const auto t_src = t.get_src();
845891
if (is_root_type(prev->get_type())) {
846892
assert(prev->is_stable_clean()
847893
|| prev->primary_ref_list_hook.is_linked());
848894
if (prev->is_dirty()) {
849895
// add the new dirty root to front
850-
remove_from_dirty(prev);
896+
remove_from_dirty(prev, nullptr/* exclude root */);
851897
}
852-
add_to_dirty(next);
898+
add_to_dirty(next, nullptr/* exclude root */);
853899
} else if (prev->is_dirty()) {
854-
replace_dirty(next, prev);
900+
replace_dirty(next, prev, t_src);
855901
} else {
856902
lru.remove_from_lru(*prev);
857-
add_to_dirty(next);
903+
add_to_dirty(next, &t_src);
858904
}
859905

860906
next->on_replace_prior();
@@ -1374,7 +1420,7 @@ record_t Cache::prepare_record(
13741420
}
13751421
assert(i->state == CachedExtent::extent_state_t::DIRTY);
13761422
assert(i->version > 0);
1377-
remove_from_dirty(i);
1423+
remove_from_dirty(i, &trans_src);
13781424
// set the version to zero because the extent state is now clean
13791425
// in order to handle this transparently
13801426
i->version = 0;
@@ -1725,10 +1771,10 @@ void Cache::complete_commit(
17251771
i->get_type(),
17261772
start_seq));
17271773
add_extent(i);
1774+
const auto t_src = t.get_src();
17281775
if (i->is_dirty()) {
1729-
add_to_dirty(i);
1776+
add_to_dirty(i, &t_src);
17301777
} else {
1731-
const auto t_src = t.get_src();
17321778
touch_extent(*i, &t_src);
17331779
}
17341780
}
@@ -1750,7 +1796,7 @@ void Cache::init()
17501796
if (root) {
17511797
// initial creation will do mkfs followed by mount each of which calls init
17521798
DEBUG("remove extent -- prv_root={}", *root);
1753-
remove_extent(root);
1799+
remove_extent(root, nullptr);
17541800
root = nullptr;
17551801
}
17561802
root = new RootBlock();
@@ -1892,15 +1938,15 @@ Cache::replay_delta(
18921938
if (is_root_type(delta.type)) {
18931939
TRACE("replay root delta at {} {}, remove extent ... -- {}, prv_root={}",
18941940
journal_seq, record_base, delta, *root);
1895-
remove_extent(root);
1941+
remove_extent(root, nullptr);
18961942
root->apply_delta_and_adjust_crc(record_base, delta.bl);
18971943
root->dirty_from_or_retired_at = journal_seq;
18981944
root->state = CachedExtent::extent_state_t::DIRTY;
18991945
DEBUG("replayed root delta at {} {}, add extent -- {}, root={}",
19001946
journal_seq, record_base, delta, *root);
19011947
root->set_modify_time(modify_time);
19021948
add_extent(root);
1903-
add_to_dirty(root);
1949+
add_to_dirty(root, nullptr);
19041950
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
19051951
std::make_pair(true, root));
19061952
} else {

src/crimson/os/seastore/cache.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,7 @@ class Cache {
11691169
).si_then([this, FNAME, &t, e](bool is_alive) {
11701170
if (!is_alive) {
11711171
SUBDEBUGT(seastore_cache, "extent is not alive, remove extent -- {}", t, *e);
1172-
remove_extent(e);
1172+
remove_extent(e, nullptr);
11731173
e->set_invalid(t);
11741174
} else {
11751175
SUBDEBUGT(seastore_cache, "extent is alive -- {}", t, *e);
@@ -1602,7 +1602,11 @@ class Cache {
16021602
counter_by_src_t<invalid_trans_efforts_t> invalidated_efforts_by_src;
16031603
counter_by_src_t<query_counters_t> cache_query_by_src;
16041604
success_read_trans_efforts_t success_read_efforts;
1605+
16051606
uint64_t dirty_bytes = 0;
1607+
counter_by_extent_t<cache_size_stats_t> dirty_sizes_by_ext;
1608+
counter_by_src_t<counter_by_extent_t<dirty_io_stats_t> >
1609+
dirty_io_by_src_ext;
16061610

16071611
uint64_t onode_tree_depth = 0;
16081612
int64_t onode_tree_extents_num = 0;
@@ -1685,18 +1689,27 @@ class Cache {
16851689
void mark_dirty(CachedExtentRef ref);
16861690

16871691
/// Add dirty extent to dirty list
1688-
void add_to_dirty(CachedExtentRef ref);
1692+
void add_to_dirty(
1693+
CachedExtentRef ref,
1694+
const Transaction::src_t* p_src);
16891695

16901696
/// Replace the prev dirty extent by next
1691-
void replace_dirty(CachedExtentRef next, CachedExtentRef prev);
1697+
void replace_dirty(
1698+
CachedExtentRef next,
1699+
CachedExtentRef prev,
1700+
const Transaction::src_t& src);
16921701

16931702
/// Remove from dirty list
1694-
void remove_from_dirty(CachedExtentRef ref);
1703+
void remove_from_dirty(
1704+
CachedExtentRef ref,
1705+
const Transaction::src_t* p_src);
16951706

16961707
void clear_dirty();
16971708

16981709
/// Remove extent from extents handling dirty and refcounting
1699-
void remove_extent(CachedExtentRef ref);
1710+
void remove_extent(
1711+
CachedExtentRef ref,
1712+
const Transaction::src_t* p_src);
17001713

17011714
/// Retire extent
17021715
void commit_retire_extent(Transaction& t, CachedExtentRef ref);

src/crimson/os/seastore/seastore_types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,6 +2654,13 @@ struct cache_stats_t {
26542654
}
26552655
};
26562656

2657+
struct dirty_io_stats_t {
2658+
cache_size_stats_t in_sizes;
2659+
uint64_t num_replace = 0;
2660+
cache_size_stats_t out_sizes;
2661+
uint64_t out_versions = 0;
2662+
};
2663+
26572664
}
26582665

26592666
WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::seastore_meta_t)

0 commit comments

Comments
 (0)