Skip to content

buffer: separate the BufferFragement release and drain tracker#28770

Merged
ggreenway merged 9 commits intoenvoyproxy:mainfrom
soulxu:fix_fragment_release
Nov 8, 2023
Merged

buffer: separate the BufferFragement release and drain tracker#28770
ggreenway merged 9 commits intoenvoyproxy:mainfrom
soulxu:fix_fragment_release

Conversation

@soulxu
Copy link
Copy Markdown
Member

@soulxu soulxu commented Aug 2, 2023

Commit Message: buffer: separate the BufferFragement release and drain tracker
Additional Description:
There is a requirement for the user space io handle and iouring io handle to move the write buffer to its own buffer and invoke the drain trackers. But becomes an issue for the BufferFragment, the BufferFragement's releasor is invoked by the drain tracker also. After moving with invoke drain trackers, the memory in the BufferFragment will be released too, which leads to the Buffer reference some memory already released.
Risk Level: high
Testing: unittest
Docs Changes: n/a
Release Notes: n/a
Platform Specific Features: n/a
Fixes #28760
Related to issue: #28395

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
@repokitteh-read-only
Copy link
Copy Markdown

As a reminder, PRs marked as draft will not be automatically assigned reviewers,
or be handled by maintainer-oncall triage.

Please mark your PR as ready when you want it to be reviewed!

🐱

Caused by: #28770 was opened by soulxu.

see: more, trace.

soulxu added 2 commits August 2, 2023 07:44
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
@soulxu soulxu marked this pull request as ready for review August 2, 2023 07:59
@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Aug 4, 2023

/wait

I want to give a test with IoUring first.

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Aug 15, 2023

@KBaichoo @yanavlasov This should be ready for the review. I also tested this with #28824, it didn't see any fail related to using the BufferFragment.

@soulxu soulxu mentioned this pull request Aug 17, 2023
@KBaichoo KBaichoo removed the waiting label Aug 22, 2023
Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/wait

would be awesome if we could have a reproduction in an integration test similar to what @roelfdutoit reported in #28760

cc @pianiststickman since this seems like a regression related to your change in #27499

void transferDrainTrackersTo(Slice& destination) {
destination.drain_trackers_.splice(destination.drain_trackers_.end(), drain_trackers_);
ASSERT(drain_trackers_.empty());
destination.releasor_.swap(releasor_);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens with the original releasor that the destination has? Is it fine to toss it as we're doing? ISTM that we don't need to do this especially as the only place transferDrainTrackersTo is called is when we copy the current slice into destination in coalesceOrAddSlice.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you are right, I shouldn't change releasor here.

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Aug 28, 2023

would be awesome if we could have a reproduction in an integration test similar to what @roelfdutoit reported in #28760

I will look at how can I reproduce that in an integration test

Thanks for the review!

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Sep 14, 2023

@KBaichoo I added the tests for UserSpace::IoHandle, would you like take a look this again? thanks in advance!

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Sep 15, 2023

/retest

Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this

/wait

ASSERT(drain_trackers_.empty());
// The releasor needn't to be transferred, and actually if there is releasor, this
// slice can't coalesce. Then there won't be a chance to calling this method.
ASSERT(releasor_ == nullptr);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something on my end but how can we guarantee no slice that we're transferring (copying) has no releasor?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is condition control that

if (other_slice.canCoalesce() && !slices_.empty() && slice_size < CopyThreshold &&
slices_.back().reservableSize() >= slice_size) {
// Copy content of the `other_slice`. The `move` methods which call this method effectively
// drain the source buffer.
addImpl(other_slice.data(), slice_size);
other_slice.transferDrainTrackersTo(slices_.back());

The other_slice.canCoalesce() is false for the Slice created from BufferFragement.

Slice(BufferFragment& fragment)
: capacity_(fragment.size()), storage_(nullptr),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks @soulxu

KBaichoo
KBaichoo previously approved these changes Sep 19, 2023
Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/assign @ggreenway

For additional buffer expertise

ASSERT(drain_trackers_.empty());
// The releasor needn't to be transferred, and actually if there is releasor, this
// slice can't coalesce. Then there won't be a chance to calling this method.
ASSERT(releasor_ == nullptr);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks @soulxu

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Oct 9, 2023

@ggreenway gentle ping :)

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
@KBaichoo
Copy link
Copy Markdown
Contributor

KBaichoo commented Nov 6, 2023

/retest

Copy link
Copy Markdown
Member

@ggreenway ggreenway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay on this. It was marked waiting so it didn't show up my list.

/wait

reservable_ = rhs.reservable_;
drain_trackers_ = std::move(rhs.drain_trackers_);
account_ = std::move(rhs.account_);
releasor_.swap(rhs.releasor_);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think swap is correct in this case. Putting the old releasor into rhs is incorrect, isn't it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, let me fix that

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Nov 7, 2023

/retest

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Nov 7, 2023

Sorry for the delay on this. It was marked waiting so it didn't show up my list.

/wait

no worries! I didn't pay attention on this recently also

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Nov 8, 2023

It seems stuck at DCO test.

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Nov 8, 2023

/retest

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Nov 8, 2023

/retest

@soulxu
Copy link
Copy Markdown
Member Author

soulxu commented Nov 8, 2023

@ggreenway ci is passed, would you think it is ok to merge?

@ggreenway ggreenway merged commit c124a78 into envoyproxy:main Nov 8, 2023
soulxu added a commit to soulxu/envoy that referenced this pull request Nov 9, 2023
soulxu added a commit to soulxu/envoy that referenced this pull request Nov 9, 2023
soulxu added a commit to soulxu/envoy that referenced this pull request Nov 9, 2023
soulxu added a commit to soulxu/envoy that referenced this pull request Nov 17, 2023
phlax pushed a commit that referenced this pull request Nov 17, 2023
Fixes #28760

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
phlax pushed a commit that referenced this pull request Nov 21, 2023
Fixes #28760

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
phlax pushed a commit that referenced this pull request Nov 21, 2023
Fixes #28760

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
phlax pushed a commit that referenced this pull request Nov 21, 2023
Fixes #28760

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
SeanKilleen pushed a commit to SeanKilleen/envoy that referenced this pull request Apr 3, 2024
…proxy#28770)

Fixes envoyproxy#28760

Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: Sean Killeen <SeanKilleen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Envoy 1.27.0: Regression in UserSpace::IoHandleImpl

3 participants