Skip to content

Commit 2388ab1

Browse files
committed
crimson/os/seastore/transaction: turn Transaction::read_set into an intrusive set
Fixes: https://tracker.ceph.com/issues/70976 Signed-off-by: Xuehan Xu <[email protected]>
1 parent b35da11 commit 2388ab1

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

src/crimson/os/seastore/cache.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,7 @@ record_t Cache::prepare_record(
12311231
auto trans_src = t.get_src();
12321232
assert(!t.is_weak());
12331233
assert(trans_src != Transaction::src_t::READ);
1234+
assert(t.read_set.size() + t.num_replace_placeholder == t.read_items.size());
12341235

12351236
auto& efforts = get_by_src(stats.committed_efforts_by_src,
12361237
trans_src);
@@ -1247,7 +1248,7 @@ record_t Cache::prepare_record(
12471248
i.ref->get_type()).increment(i.ref->get_length());
12481249
read_stat.increment(i.ref->get_length());
12491250
}
1250-
t.read_set.clear();
1251+
t.clear_read_set();
12511252
t.write_set.clear();
12521253

12531254
record_t record(record_type_t::JOURNAL, trans_src);

src/crimson/os/seastore/cached_extent.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,16 @@ class read_set_item_t {
6767
using set_hook_t = boost::intrusive::set_member_hook<
6868
boost::intrusive::link_mode<
6969
boost::intrusive::auto_unlink>>;
70-
set_hook_t trans_hook;
71-
using set_hook_options = boost::intrusive::member_hook<
70+
set_hook_t trans_hook; // used to attach transactions to extents
71+
set_hook_t extent_hook; // used to attach extents to transactions
72+
using trans_hook_options = boost::intrusive::member_hook<
7273
read_set_item_t,
7374
set_hook_t,
7475
&read_set_item_t::trans_hook>;
76+
using extent_hook_options = boost::intrusive::member_hook<
77+
read_set_item_t,
78+
set_hook_t,
79+
&read_set_item_t::extent_hook>;
7580

7681
public:
7782
struct extent_cmp_t {
@@ -101,9 +106,14 @@ class read_set_item_t {
101106

102107
using trans_set_t = boost::intrusive::set<
103108
read_set_item_t,
104-
set_hook_options,
109+
trans_hook_options,
105110
boost::intrusive::constant_time_size<false>,
106111
boost::intrusive::compare<trans_cmp_t>>;
112+
using extent_set_t = boost::intrusive::set<
113+
read_set_item_t,
114+
extent_hook_options,
115+
boost::intrusive::constant_time_size<false>,
116+
boost::intrusive::compare<extent_cmp_t>>;
107117

108118
T *t = nullptr;
109119
CachedExtentRef ref;
@@ -115,9 +125,7 @@ class read_set_item_t {
115125
};
116126

117127
template <typename T>
118-
using read_extent_set_t = std::set<
119-
read_set_item_t<T>,
120-
typename read_set_item_t<T>::extent_cmp_t>;
128+
using read_extent_set_t = typename read_set_item_t<T>::extent_set_t;
121129

122130
template <typename T>
123131
using read_trans_set_t = typename read_set_item_t<T>::trans_set_t;

src/crimson/os/seastore/transaction.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class Transaction {
126126
add_present_to_retired_set(ref);
127127
}
128128

129+
using extent_cmp_t = read_set_item_t<Transaction>::extent_cmp_t;
129130
void add_present_to_retired_set(CachedExtentRef ref) {
130131
assert(ref->get_paddr().is_real_location());
131132
assert(!is_weak());
@@ -147,7 +148,7 @@ class Transaction {
147148
write_set.erase(*ref);
148149
assert(ref->prior_instance);
149150
retired_set.emplace(ref->prior_instance, trans_id);
150-
assert(read_set.count(ref->prior_instance->get_paddr()));
151+
assert(read_set.count(ref->prior_instance->get_paddr(), extent_cmp_t{}));
151152
ref->prior_instance.reset();
152153
} else {
153154
// && retired_set.count(ref->get_paddr()) == 0
@@ -269,7 +270,7 @@ class Transaction {
269270
assert(ref->get_paddr().is_absolute() ||
270271
ref->get_paddr().is_root());
271272
assert(ref->is_exist_mutation_pending() ||
272-
read_set.count(ref->prior_instance->get_paddr()));
273+
read_set.count(ref->prior_instance->get_paddr(), extent_cmp_t{}));
273274
mutated_block_list.push_back(ref);
274275
if (!ref->is_exist_mutation_pending()) {
275276
write_set.insert(*ref);
@@ -288,12 +289,19 @@ class Transaction {
288289
assert(extent.get_paddr() == placeholder.get_paddr());
289290
assert(extent.get_paddr().is_absolute());
290291
{
291-
auto where = read_set.find(placeholder.get_paddr());
292+
auto where = read_set.find(placeholder.get_paddr(), extent_cmp_t{});
292293
assert(where != read_set.end());
293294
assert(where->ref.get() == &placeholder);
294295
where = read_set.erase(where);
295-
auto it = read_set.emplace_hint(where, this, &extent);
296+
placeholder.read_transactions.erase(
297+
read_trans_set_t<Transaction>::s_iterator_to(*where));
298+
// Note, the retired-placeholder is not removed from read_items after replace.
299+
read_items.emplace_back(this, &extent);
300+
auto it = read_set.insert_before(where, read_items.back());
296301
extent.read_transactions.insert(const_cast<read_set_item_t<Transaction>&>(*it));
302+
#ifndef NDEBUG
303+
num_replace_placeholder++;
304+
#endif
297305
}
298306
{
299307
auto where = retired_set.find(&placeholder);
@@ -428,7 +436,7 @@ class Transaction {
428436
root.reset();
429437
offset = 0;
430438
delayed_temp_offset = 0;
431-
read_set.clear();
439+
read_items.clear();
432440
fresh_backref_extents = 0;
433441
invalidate_clear_write_set();
434442
mutated_block_list.clear();
@@ -587,7 +595,7 @@ class Transaction {
587595
} else if (retired_set.count(addr)) {
588596
return {get_extent_ret::RETIRED, nullptr};
589597
} else if (
590-
auto iter = read_set.find(addr);
598+
auto iter = read_set.find(addr, extent_cmp_t{});
591599
iter != read_set.end()) {
592600
auto ret = iter->ref;
593601
SUBTRACET(seastore_cache, "{} is present in read_set -- {}",
@@ -617,7 +625,8 @@ class Transaction {
617625
return false;
618626
}
619627

620-
auto [iter, inserted] = read_set.emplace(this, ref);
628+
read_items.emplace_back(this, ref);
629+
auto [iter, inserted] = read_set.insert(read_items.back());
621630
ceph_assert(inserted);
622631
ref->read_transactions.insert_before(
623632
it, const_cast<read_set_item_t<Transaction>&>(*iter));
@@ -652,6 +661,10 @@ class Transaction {
652661
* invalidate *this.
653662
*/
654663
read_extent_set_t<Transaction> read_set; ///< set of extents read by paddr
664+
std::list<read_set_item_t<Transaction>> read_items;
665+
#ifndef NDEBUG
666+
size_t num_replace_placeholder = 0;
667+
#endif
655668

656669
uint64_t fresh_backref_extents = 0; // counter of new backref extents
657670

0 commit comments

Comments
 (0)