crimson/os/seastore/cache: initial_pending extents also do "set_io_wait/complete_io/wait_io"#62878
crimson/os/seastore/cache: initial_pending extents also do "set_io_wait/complete_io/wait_io"#62878xxhdx1985126 wants to merge 5 commits intoceph:mainfrom
Conversation
|
jenkins test make check |
|
jenkins test api |
913d2bc to
ee2e878
Compare
|
jenkins test make check |
| // stable and visible, see prepare_record(). | ||
| // | ||
| // XXX: It might be good to mark this case as DIRTY from the definition, | ||
| // XXX: It might be good to mark this case as DIRTY/CLEAN from the definition, |
There was a problem hiding this comment.
The major reason is that I think it is inappropriate (and wrong) to expose the pending states that are not from (irrelavent to) this transaction. These states should actually be DIRTY/CLEAN from this transaction's perspective.
This will make things challenging (even worse when initial-pending is also affecting now) as there are lots of different places relying on deciding whether the extent is pending in this transaction.
|
@cyx1231st I've just modified the code as discussed offline, please take a look, thanks:-) |
| // XXX: It might be good to mark this case as DIRTY/CLEAN from the definition, | ||
| // which probably can make things simpler. | ||
| return is_mutation_pending() && is_pending_io(); | ||
| if (is_pending_io()) { |
There was a problem hiding this comment.
I think if needs to be wrapped in DEBUG macro to build conditionally as well, otherwise non-debug build will see an empty if.
There was a problem hiding this comment.
Um, IIUC, the empty if would be optimized by the compiler: https://godbolt.org/z/zd6oz6sbv
|
The essential gap from the discussions is that:
|
|
@cyx1231st It seems that the use cases in which an initial_pending extents might be met are as follows:
Both of the above cases must go through I also added asserts to make sure the seperated steps are only used for initial pending and stable writing extents and prevent other cases from wrongly using the interfaces. Please take a look, thanks:-) |
cyx1231st
left a comment
There was a problem hiding this comment.
Yeah, it makes sense to me that only get_extent_viewable_by_trans() is and will be related to this issue in the near future, and there are proper asserts added.
Can you help to take a look at the paddr type validations in #62938 ?
If possible, I prefer to merge the code consolidation/cleanup work before moving forward.
|
This pull request can no longer be automatically merged: a rebase is needed and changes have to be manually resolved |
0b2430d to
330961a
Compare
|
The test shows this PR intensifies the issue https://tracker.ceph.com/issues/71317, which depends the PR #63218 |
There was a problem hiding this comment.
Regarding to "Assertion `where->ref.get() == &placeholder' failed."
I see further gaps related to retired-placeholer (probably still incomplete):
- retired-placeholder is not added atomically upon get_extent_if_linked(), it is only added later into the cache index
- retired-placeholder is not linked atomically in the lba tree, so it is possible that
- a retired placeholder can be added multiple times repeatedly
- a real extent can be linked in the middle, making the errors looking more confusing
- even after it is linked in the lba tree, there is no logic to handle this case properly (see comments).
Probably we should merge #63218 with this PR to fix the issues together.
Let me know your thoughts.
| touch_extent(*p_extent, &t_src, t.get_cache_hint()); | ||
| if (ret.is_paddr_known) { | ||
| touch_extent(*p_extent, &t_src, t.get_cache_hint()); | ||
| } else { |
There was a problem hiding this comment.
In the else case, validate p_extent must not be a retired-placeholder.
There was a problem hiding this comment.
add assert:
assert(!is_retired_placeholder_type(p_extent->get_type()));
| ++stats.access.cache_lru; | ||
| } | ||
| touch_extent(*p_extent, &t_src, t.get_cache_hint()); | ||
| if (ret.is_paddr_known) { |
There was a problem hiding this comment.
See #63218 (comment), after retired-placeholder is linked in the lba tree, it is possible to see a retired-placeholder here, I think the proper way to handle this is to:
- check if
retis a retired-placeholder. - create a real one (which means we need to know the real type here)
- and replace placeholder by the real one immediately (see Cache::do_get_caching_extent())
There might be asserts needed somewhere to make sure things are working properly, still thinking.
| CachedExtent* p_extent; | ||
| bool needs_step_2 = false; | ||
| bool needs_touch = false; | ||
| if (extent->is_stable()) { |
There was a problem hiding this comment.
After #63218 (comment), and starting from this case, it should be possible to see the extent is a retired-placeholder.
| bool needs_step_2 = false; | ||
| bool needs_touch = false; | ||
| if (extent->is_stable()) { | ||
| p_extent = extent->get_transactional_view(t); |
There was a problem hiding this comment.
I think a retired-placeholder cannot get-transactional-view, might need some adjustments.
| needs_touch = true; | ||
| } | ||
| } else { | ||
| // already exists |
There was a problem hiding this comment.
Must not be a retired-placeholder if already exists.
There was a problem hiding this comment.
add assert:
assert(!is_retired_placeholder_type(p_extent->get_type()));
|
I'll proceed to see if we can merge #62071 first. |
Yeah, will do. |
|
jenkins test api |
| auto it = read_set.emplace_hint(where, this, &extent); | ||
| placeholder.read_transactions.erase( | ||
| read_trans_set_t<Transaction>::s_iterator_to(*where)); | ||
| read_items.emplace_back(this, &extent); |
There was a problem hiding this comment.
Add a comment:
// Note, the retired-placeholder is not removed from read_items after replace.
| touch_extent(*p_extent, &t_src, t.get_cache_hint()); | ||
| if (ret.is_paddr_known) { | ||
| touch_extent(*p_extent, &t_src, t.get_cache_hint()); | ||
| } else { |
There was a problem hiding this comment.
add assert:
assert(!is_retired_placeholder_type(p_extent->get_type()));
| needs_touch = true; | ||
| } | ||
| } else { | ||
| // already exists |
There was a problem hiding this comment.
add assert:
assert(!is_retired_placeholder_type(p_extent->get_type()));
| auto it = read_set.emplace_hint(where, this, &extent); | ||
| placeholder.read_transactions.erase( | ||
| read_trans_set_t<Transaction>::s_iterator_to(*where)); | ||
| read_items.emplace_back(this, &extent); |
There was a problem hiding this comment.
I assume the only changed place is here compared with the last version, right?
|
This pull request can no longer be automatically merged: a rebase is needed and changes have to be manually resolved |
ac52d80 to
4af73bd
Compare
set_io_wait/complete_io/wait_io Fixes: https://tracker.ceph.com/issues/70976 Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
…ntrusive set Fixes: https://tracker.ceph.com/issues/70976 Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
…tion::do_add_to_read_set() The current implementation of Transaction::do_add_to_read_set() can be seperated into two steps: 1. attach the extent to the transaction, i.e. insert the extent into the transaction's read_set 2. attach the transaction to the extent, i.e. insert the transaction into the extent's read_transactions For initial pending and stable writing extents, we need to do the second step before doing "CachedExtent::wait_io()" and to do the first step after "CachedExtent::wait_io()". This commit add interfaces corresponding to those two steps. Fixes: https://tracker.ceph.com/issues/70976 Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com> Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
initial pending and stable writing extents Fixes: https://tracker.ceph.com/issues/70976 Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com> Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
`BaseChildNode::get_parent_node()` to `BaseChildNode::peek_parent_node()` Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
|
closing this PR as its commits have been merged to #63218 |
Fixes: https://tracker.ceph.com/issues/70976
Signed-off-by: Xuehan Xu xuxuehan@qianxin.com
Contribution Guidelines
To sign and title your commits, please refer to Submitting Patches to Ceph.
If you are submitting a fix for a stable branch (e.g. "quincy"), please refer to Submitting Patches to Ceph - Backports for the proper workflow.
When filling out the below checklist, you may click boxes directly in the GitHub web UI. When entering or editing the entire PR message in the GitHub web UI editor, you may also select a checklist item by adding an
xbetween the brackets:[x]. Spaces and capitalization matter when checking off items this way.Checklist
Show available Jenkins commands
jenkins test classic perfJenkins Job | Jenkins Job Definitionjenkins test crimson perfJenkins Job | Jenkins Job Definitionjenkins test signedJenkins Job | Jenkins Job Definitionjenkins test make checkJenkins Job | Jenkins Job Definitionjenkins test make check arm64Jenkins Job | Jenkins Job Definitionjenkins test submodulesJenkins Job | Jenkins Job Definitionjenkins test dashboardJenkins Job | Jenkins Job Definitionjenkins test dashboard cephadmJenkins Job | Jenkins Job Definitionjenkins test apiJenkins Job | Jenkins Job Definitionjenkins test docsReadTheDocs | Github Workflow Definitionjenkins test ceph-volume allJenkins Jobs | Jenkins Jobs Definitionjenkins test windowsJenkins Job | Jenkins Job Definitionjenkins test rook e2eJenkins Job | Jenkins Job Definition