crimson/osd/osd_operations/snaptrim_event: lifetime fixes#54513
crimson/osd/osd_operations/snaptrim_event: lifetime fixes#54513
Conversation
Sanitized backtrace:
```
DEBUG 2023-11-14 15:23:50,871 [shard 0] osd - snaptrim_event(id=10610, detail=SnapTrimEvent(pgid=16.1a snapid=a needs_pause=0)): interrupted crimson::common::actingset_changed (acting set changed)
#0 0x5653c613c071 in seastar::shared_mutex::unlock() (/usr/bin/ceph-osd+0x1ed27071)
#1 0x5653c8670acf in auto seastar::futurize_invoke<crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::ExitBarrier<crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::BlockingEvent::Trigger<crimson::osd::SnapTrimEvent> >::exit()::{lambda()#1}&>(crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::ExitBarrier<crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::BlockingEvent::Trigger<crimson::osd::SnapTrimEvent> >::exit()::{lambda()#1}&) (/usr/bin/ceph-osd+0x2125bacf)
#2 0x5653c8670e22 in _ZN7seastar20noncopyable_functionIFNS_6futureIvEEvEE17direct_vtable_forIZNS2_4thenIZN7crimson23OrderedConcurrentPhaseTINS7_3osd13SnapTrimEvent9WaitSubopEE11ExitBarrierINSC_13BlockingEvent7TriggerISA_EEE4exitEvEUlvE_S2_EET0_OT_EUlDpOT_E_E4callEPKS4_ (/usr/bin/ceph-osd+0x2125be22)
freed by thread T1 here:
#0 0x7f10628b73cf in operator delete(void*, unsigned long) (/lib64/libasan.so.6+0xb73cf)
#1 0x5653c8794bff in crimson::osd::SnapTrimEvent::~SnapTrimEvent() (/usr/bin/ceph-osd+0x2137fbff)
previously allocated by thread T1 here:
#0 0x7f10628b6367 in operator new(unsigned long) (/lib64/libasan.so.6+0xb6367)
SUMMARY: AddressSanitizer: heap-use-after-free (/usr/bin/ceph-osd+0x1ed27071) in seastar::shared_mutex::unlock()
```
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
3fb3838 to
787226f
Compare
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
```
// SnapTrimEvent is a background operation,
// it's lifetime is not guarnteed since the caller
// returned future is being ignored. We should capture
// a self reference thourhgout the entire execution
// progress (not only on finally() continuations).
// See: PG::on_active_actmap()
```
Sanitized backtrace:
```
DEBUG 2023-11-16 08:42:48,441 [shard 0] osd - snaptrim_event(id=21122, detail=SnapTrimEvent(pgid=3.1 snapid=3cb needs_pause=1)): interrupted crimson::common::actingset_changed (acting set changed
kernel callstack:
#0 0x55e310e0ace7 in seastar::shared_mutex::unlock() (/usr/bin/ceph-osd+0x1edd0ce7)
#1 0x55e313325d9c in auto seastar::futurize_invoke<crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::ExitBarrier<crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::BlockingEvent::Trigger<crimson::osd::SnapTrimEvent> >::exit()::{lambda()#1}&>(crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::ExitBarrier<crimson::OrderedConcurrentPhaseT<crimson::osd::SnapTrimEvent::WaitSubop>::BlockingEvent::Trigger<crimson::osd::SnapTrimEvent> >::exit()::{lambda()#1}&) (/usr/bin/ceph-osd+0x212ebd9c)
#2 0x55e3133260ef in _ZN7seastar20noncopyable_functionIFNS_6futureIvEEvEE17direct_vtable_forIZNS2_4thenIZN7crimson23OrderedConcurrentPhaseTINS7_3osd13SnapTrimEvent9WaitSubopEE11ExitBarrierINSC_13BlockingEvent7TriggerISA_EEE4exitEvEUlvE_S2_EET0_OT_EUlDpOT_E_E4callEPKS4_ (/usr/bin/ceph-osd+0x212ec0ef)
0x61500013365c is located 92 bytes inside of 472-byte region [0x615000133600,0x6150001337d8)
freed by thread T2 here:
#0 0x7fb345ab73cf in operator delete(void*, unsigned long) (/lib64/libasan.so.6+0xb73cf)
#1 0x55e313474863 in crimson::osd::SnapTrimEvent::~SnapTrimEvent() (/usr/bin/ceph-osd+0x2143a863)
previously allocated by thread T2 here:
#0 0x7fb345ab6367 in operator new(unsigned long) (/lib64/libasan.so.6+0xb6367)
#1 0x55e31183ac18 in auto crimson::OperationRegistryI::create_operation<crimson::osd::SnapTrimEvent, crimson::osd::PG*, SnapMapper&, snapid_t const&, bool const&>(crimson::osd::PG*&&, SnapMapper&, snapid_t const&, bool const&) (/usr/bin/ceph-osd+0x1f800c18)
SUMMARY: AddressSanitizer: heap-use-after-free (/usr/bin/ceph-osd+0x1edd0ce7) in seastar::shared_mutex::unlock()
```
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
787226f to
abceb16
Compare
| }); | ||
| }); | ||
| }, [this](std::exception_ptr eptr) -> snap_trim_ertr::future<seastar::stop_iteration> { | ||
| }, [this, ref] |
There was a problem hiding this comment.
Does the issue disappear after this commit?
But my understanding is that capturing ref in the finally() continuation below should make it unnecessary to capture ref in the middle continuations from this commit.
There was a problem hiding this comment.
The backtrace in this commit (abceb16) occurred based on the commit that captured ref in the finaly() continuation below (84c5b6c).
Build: https://github.com/ceph/ceph-ci/commits/wip-matanb-crimson-testing-11-15
Commit: a72569d
Does the issue disappear after this commit?
According to the last round, yes.
There was a problem hiding this comment.
IIUC, the capture here should be different that usual because we ignore the future returned.
void PG::on_active_actmap()
{
std::ignore = seastar::do_until(
[this] {...},
[this] {
return seastar::repeat([to_trim, needs_pause, this] {
return shard_services.start_operation<SnapTrimEvent>(...)
There was a problem hiding this comment.
I'm still wondering that capturing ref in finally() (L207) should extend its life until finally() is called, which implies that capturing in the previous chained continuations (L100, L204) before finally() are unnecessary.
(IIUC the std::ignore above is unrelated to this internal chaining.)
According to the last round, yes.
I'm still feeling skeptical here, but anyway, it'd be fine to go ahead and watch the future tests.
There was a problem hiding this comment.
I'm still feeling skeptical here, but anyway, it'd be fine to go ahead and watch the future tests.
I run 20 thrash test (with snapshot activity) which had the crashes mentioned here, it seems that we no longer crash on these test (19/20, 1 unrelated).
https://pulpito.ceph.com/matan-2023-11-20_10:00:00-crimson-rados-wip-matanb-crimson-testing-11-19-distro-crimson-smithi/
| logger().debug("{}: interrupted {}", *this, eptr); | ||
| return crimson::ct_error::eagain::make(); | ||
| }, pg).finally([this] { | ||
| }, pg).finally([this, ref] { |
There was a problem hiding this comment.
Does the issue disappear after this fix?
See https://github.com/ceph/ceph/blob/main/src/crimson/osd/shard_services.h#L164-L169
IIUC there is no difference with this change because the life of op is already extended by its caller above.
There was a problem hiding this comment.
start_operation_may_interrupt is called with SnapTrimObjSubEvent ops. The fix here is for SnapTrimEvent ops. Did I understand you correctly?
There was a problem hiding this comment.
Ah, sorry about refering to an irrelavent logic.
Please refer to https://github.com/ceph/ceph/blob/main/src/crimson/osd/shard_services.h#L142-L147 instead, which should be the caller of SnapTrimObjEvent::start() and has already extended its life to finally() IIUC.
|
Looks the issue https://tracker.ceph.com/issues/63299 still persists, refer to: https://pulpito.ceph.com/yingxin-2023-11-27_02:15:02-crimson-rados-wip-yingxin-crimson-improve-mempool5-distro-default-smithi/ --- see case 7467449 and 7467459 --- failures are: seastar::shared_mutex::unlock() after ~SnapTrimEvent(). The testing branch is https://github.com/ceph/ceph-ci/commits/wip-yingxin-crimson-improve-mempool5, which should have included this PR. |
@cyx1231st, opened a tracker: https://tracker.ceph.com/issues/63647 |
Sanitized backtraces attached to each commit.
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 retest this pleasejenkins test classic perfjenkins test crimson perfjenkins test signedjenkins test make checkjenkins test make check arm64jenkins test submodulesjenkins test dashboardjenkins test dashboard cephadmjenkins test apijenkins test docsjenkins render docsjenkins test ceph-volume alljenkins test ceph-volume toxjenkins test windowsjenkins test rook e2e