Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

SslStream - Linux Solving it all in 4 lines (and deleting 2) - #25646

Merged
stephentoub merged 6 commits into
dotnet:masterfrom
Drawaes:TestSkipDeleteErrors
Dec 2, 2017
Merged

SslStream - Linux Solving it all in 4 lines (and deleting 2)#25646
stephentoub merged 6 commits into
dotnet:masterfrom
Drawaes:TestSkipDeleteErrors

Conversation

@Drawaes

@Drawaes Drawaes commented Dec 1, 2017

Copy link
Copy Markdown

Well, I sat, I thought, ... I read some c.. and I think I figured it out..

Basically the problem is if another bit of code that used this thread didn't clean up after itself (bad manners if you ask me but you can't control everyone).

The errors are just a queue and we can "peek_last_error" but the problem is that we are calling Ssl_Get_Error.

Ssl_Get_Error is a about 100 lines of code that does a bunch of other things than just check the error queue (checks internal bio states for async needs read/write etc).

So we can't change that, and we can't change that it needs the error code of the latest error. And we can't change that it looks at the "first" item in the queue.

The current solution is to clear the error queue before each encrypt/decrypt but that hits the evil global lock and causes all the grief. And removing the clear of course causes potentially the wrong item at the top of the error queue.

However the clear is on the hot path, and what isn't on the hot path is the "Ssl_Get_Error" mostly because SslStream ensures sending of complete frames to OpenSSL so we don't rely on the "Needs Read/Write" in hot situations. We will get these for an actual error, but then that is now a slow path anyway.

To get to it, my solution is not to do the clear, but when we are in the error state, just makesure the queues first and last error number are the same with a Peek of the first and last (the only operations I have other than get). If they aren't the same then do a get to pop one off the queue and repeat until they equal.

Master ~200k rps
Throttle ~400k rps
Throttle with ProcCount/2 ~580k rps
With my error change

713021.51

This is my preferred solution over #25187

@Drawaes

Drawaes commented Dec 1, 2017

Copy link
Copy Markdown
Author

@Drawaes

Drawaes commented Dec 1, 2017

Copy link
Copy Markdown
Author

The best bit, no throttle, no PAL crazy, so so simple.


extern "C" int32_t CryptoNative_SslGetError(SSL* ssl, int32_t ret)
{
while(ERR_peek_error() != ERR_peek_last_error())

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 think this needs some code comments explaining what is happening (and why)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good idea, added

@benaadams

Copy link
Copy Markdown
Member

@dotnet-bot test Outerloop Linux x64 Debug Build please
@dotnet-bot test Outerloop Linux x64 Release Build please

@stephentoub

Copy link
Copy Markdown
Member

If @bartonjs is happy with it, I am, too.

@benaadams

benaadams commented Dec 2, 2017

Copy link
Copy Markdown
Member

RedHat seg fault in regular release

Output: Discovering: System.Net.Http.Functional.Tests
Output: Discovered:  System.Net.Http.Functional.Tests
Output: Starting:    System.Net.Http.Functional.Tests
Output: /home/helixbot/dotnetbuild/work/bfe57023-f46d-466f-95f0-add96a0cd0a9/Work/35f9d9c3-7fe6-43ee-9f89-bbfe45adfa8b/Unzip/RunTests.sh: 
 line 91:   869 Segmentation fault      (core dumped) $RUNTIME_PATH/dotnet xunit.console.netcore.exe System.Net.Http.Functional.Tests.dll 
 -xml testResults.xml -notrait category=nonnetcoreapptests -notrait category=nonlinuxtests -notrait category=failing
Output: Trying to find crash dumps for project: System.Net.Http.Functional.Tests
Output: No new dump file was found in /home/helixbot/dotnetbuild/work/bfe57023-f46d-466f-95f0-add96a0cd0a9/Work/35f9d9c3-7fe6-43ee-9f89-bbfe45adfa8b/Unzip
Output: ~/dotnetbuild/work/bfe57023-f46d-466f-95f0-add96a0cd0a9/Work/35f9d9c3-7fe6-43ee-9f89-bbfe45adfa8b/Unzip
Output: Finished running tests. End time=16:39:39. Return value was 139
Exit Code: 139
ERROR: scriptrunner(87): _main: Error: No exception thrown, but XUnit results not created

@dotnet-bot test Linux x64 Release Build please

@benaadams

Copy link
Copy Markdown
Member

fedora.25.amd64.Open:Debug-x64 Outerloop issue, same place

Output: Discovering: System.Net.Http.Functional.Tests
Output: Discovered:  System.Net.Http.Functional.Tests
Output: Starting:    System.Net.Http.Functional.Tests
Output: /home/helixbot/dotnetbuild/work/bfe57023-f46d-466f-95f0-add96a0cd0a9/Work/35f9d9c3-7fe6-43ee-9f89-bbfe45adfa8b/Unzip/RunTests.sh:
 line 91:   869 Segmentation fault      (core dumped) $RUNTIME_PATH/dotnet xunit.console.netcore.exe System.Net.Http.Functional.Tests.dll
 -xml testResults.xml -notrait category=nonnetcoreapptests -notrait category=nonlinuxtests -notrait category=failing
Output: Trying to find crash dumps for project: System.Net.Http.Functional.Tests
Output: No new dump file was found in /home/helixbot/dotnetbuild/work/bfe57023-f46d-466f-95f0-add96a0cd0a9/Work/35f9d9c3-7fe6-43ee-9f89-bbfe45adfa8b/Unzip
Output: ~/dotnetbuild/work/bfe57023-f46d-466f-95f0-add96a0cd0a9/Work/35f9d9c3-7fe6-43ee-9f89-bbfe45adfa8b/Unzip
Output: Finished running tests. End time=16:39:39. Return value was 139
Exit Code: 139
ERROR: scriptrunner(87): _main: Error: No exception thrown, but XUnit results not created

@bartonjs bartonjs left a comment

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'm having trouble deciding if this is bad or not. I can't immediately think of a reason why it would be bad, but it's not obviously not-bad, either.

I guess you can always revert it when people start reporting nonsense errors.

// This pops off "old" errors left by other operations
// until the first and last error are the same
// this should be looked at again when OpenSsl 1.1 is migrated to
while(ERR_peek_error() != ERR_peek_last_error())

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.

Please run clang-format -i on this file. (At least accepting any changes in this function)

// This pops off "old" errors left by other operations
// until the first and last error are the same
// this should be looked at again when OpenSsl 1.1 is migrated to
while(ERR_peek_error() != ERR_peek_last_error())

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.

Technically this will stop if there's a repeat value. And the error could be stale.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yeah the stale is an issue, let me try a couple of things and see the perf.

@Drawaes Drawaes changed the title SslStream - Linux Solving it all in 4 lines (and deleting 2) [WIP] SslStream - Linux Solving it all in 4 lines (and deleting 2) Dec 2, 2017
@Drawaes

Drawaes commented Dec 2, 2017

Copy link
Copy Markdown
Author

@dotnet-bot test Linux x64 Release Build please

@Drawaes

Drawaes commented Dec 2, 2017

Copy link
Copy Markdown
Author

@dotnet-bot test Outerloop Linux x64 Debug Build please
@dotnet-bot test Outerloop Linux x64 Release Build please

1 similar comment
@benaadams

Copy link
Copy Markdown
Member

@dotnet-bot test Outerloop Linux x64 Debug Build please
@dotnet-bot test Outerloop Linux x64 Release Build please

// This pops off "old" errors left by other operations
// until the first and last error are the same
// this should be looked at again when OpenSsl 1.1 is migrated to
while(ERR_peek_error() != ERR_peek_last_error())

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.

This should be while<space>(. Please run clang-format -i against this file.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done

@Drawaes Drawaes changed the title [WIP] SslStream - Linux Solving it all in 4 lines (and deleting 2) SslStream - Linux Solving it all in 4 lines (and deleting 2) Dec 2, 2017
@Drawaes

Drawaes commented Dec 2, 2017

Copy link
Copy Markdown
Author

@dotnet-bot test Outerloop Linux x64 Debug Build please
@dotnet-bot test Outerloop Linux x64 Release Build please

@stephentoub stephentoub left a comment

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.

As long as @bartonjs says it's sound, this is certainly a better approach than the manual throttling.

@stephentoub
stephentoub merged commit 03c7617 into dotnet:master Dec 2, 2017
@Drawaes
Drawaes deleted the TestSkipDeleteErrors branch December 2, 2017 21:00
@karelz karelz added this to the 2.1.0 milestone Dec 4, 2017
Priya91 pushed a commit to Priya91/corefx-1 that referenced this pull request Dec 22, 2017
@pjanotti

Copy link
Copy Markdown
Contributor

@Drawaes what did you use in your benchmark? I would like to keep tracking the perf status of this while we do some more work to ensure no errors are left on the queue.

@Drawaes

Drawaes commented Apr 19, 2018 via email

Copy link
Copy Markdown
Author

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…corefx#25646)

* Change get error to remove all but the last.

* Remove clear errors

* Added code comment

* Try peeking at the errors before clearing

* Make sure the error queue is cleared if there were multiple errors during Ssl_GetError

* Format with clang


Commit migrated from dotnet/corefx@03c7617
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants