Uh oh!
There was an error while loading. Please reload this page.
tls: Reduce memory copying and number of BIO buffer allocations - #31499
tls: Reduce memory copying and number of BIO buffer allocations#31499rustyconover wants to merge 3 commits into
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
fb6ee33 to
4b4ee85Comparenodejs-github-bot
commented
Jan 24, 2020
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
nodejs-github-bot
commented
Jan 26, 2020
nodejs-github-bot
commented
Jan 26, 2020
rustyconover
commented
Jan 26, 2020
How do I request this also get landed in v12.x? |
Trott
commented
Jan 26, 2020
Benchmark results: confidence improvement accuracy (*) (**) (***) tls/throughput.js size=1024 type='asc' dur=5 1.53 % ±2.08% ±2.79% ±3.68% tls/throughput.js size=1024 type='buf' dur=5 1.84 % ±2.18% ±2.93% ±3.88% tls/throughput.js size=1024 type='utf' dur=5 1.11 % ±2.09% ±2.78% ±3.62% tls/throughput.js size=1048576 type='asc' dur=5 *** 3.62 % ±1.47% ±1.96% ±2.56% tls/throughput.js size=1048576 type='buf' dur=5 *** 3.95 % ±1.39% ±1.85% ±2.40% tls/throughput.js size=1048576 type='utf' dur=5 1.44 % ±1.72% ±2.28% ±2.97% tls/throughput.js size=16777216 type='asc' dur=5 * 5.40 % ±4.25% ±5.71% ±7.55% tls/throughput.js size=16777216 type='buf' dur=5 *** 9.64 % ±1.23% ±1.64% ±2.14% tls/throughput.js size=16777216 type='utf' dur=5 *** 6.09 % ±1.59% ±2.11% ±2.76% tls/throughput.js size=2 type='asc' dur=5 1.23 % ±2.28% ±3.05% ±3.98% tls/throughput.js size=2 type='buf' dur=5 0.43 % ±1.59% ±2.13% ±2.79% tls/throughput.js size=2 type='utf' dur=5 -2.19 % ±4.88% ±6.57% ±8.71% tls/throughput.js size=4194304 type='asc' dur=5 *** 6.62 % ±1.26% ±1.68% ±2.20% tls/throughput.js size=4194304 type='buf' dur=5 *** 7.55 % ±0.93% ±1.24% ±1.62% tls/throughput.js size=4194304 type='utf' dur=5 *** 4.21 % ±1.65% ±2.20% ±2.86%Be aware that when doing many comparisons the risk of a false-positiveresult increases. In this case there are 15 comparisons, you can thusexpect the following amount of false-positive results: 0.75 false positives, when considering a 5% risk acceptance (*, **, ***), 0.15 false positives, when considering a 1% risk acceptance (**, ***), 0.01 false positives, when considering a 0.1% risk acceptance (***) |
Interestingly and completely believably, this seems to cause sequential/test-https-keep-alive-large-write to fail on Windows. |
Trott
commented
Jan 26, 2020
Welcome @rustyconover and thanks for the great pull request! Things that land on the master branch that are performance improvements (and not breaking changes) tend to get pulled into the LTS Active release (which is what 12.x is right now). So there's no need to do anything special. |
rustyconover
commented
Jan 26, 2020
So I think I can explain that test failure. TLSWrap::EncOut() will only try to write kSimultaneousBufferCount buffers at a time. My PR has changed the BIO buffer scheme such that a single BIO buffer could be the entire length of the write (due to the allocation hint). This means rather than doing 10 ~16k TLS segments per call, there could be just big call which may complete before the timeout will be issued. So the test is trying to make a guarantee that that write could be interrupted and timeout signaled mid-buffer, which seems dubious to me. |
Trott
commented
Jan 27, 2020
@nodejs/http Thoughts on the validity of sequential/test-https-keep-alive-large-write? |
Trott
commented
Jan 27, 2020
/ping @nodejs/testing too. |
bnoordhuis
commented
Jan 27, 2020
After looking at the test I agree it's based on a flawed assumption / inherently race-y. It looks to have worked by accident until now, but throw a fast enough machine at it and I'm sure it'll start failing even without this PR. I'm okay with removing it. |
rustyconover
commented
Jan 27, 2020
Should I amend the commit to remove the test? |
addaleax
commented
Jan 27, 2020
I think it’s fine to remove it in a separate commit (e.g. |
jasnell
commented
Jan 27, 2020
For the removed test, it would be good to document what the flawed assumption is in the commit message. |
nodejs-github-bot
commented
Feb 26, 2020
rustyconover
commented
Feb 26, 2020
@addaleax The changes to the test worked, now it seems there is some flakiness in an unrelated test on a Raspberry Pi in the CI. How can I try to run the CI tests again to see if it will resolve? |
rustyconover
commented
Feb 26, 2020
This #31966 seems to be causing the problem in getting the CI tests to pass. |
nodejs-github-bot
commented
Feb 26, 2020
nodejs-github-bot
commented
Feb 26, 2020
nodejs-github-bot
commented
Feb 27, 2020
Trott
commented
Feb 27, 2020
That fix landed a few minutes ago so it hopefully won't be a problem anymore. Did a full CI rebuild for this PR. Hopefully things will go easier/better this time.... |
rustyconover
commented
Feb 28, 2020
@Trott Thanks for your help triggering the new CI, it seems that there is an unrelated failure in HTTP2 now. I wasn't setting this error before: It doesn't seem to be directly related to the PR at hand. Can we try it one more time? |
nodejs-github-bot
commented
Feb 28, 2020
rustyconover
commented
Feb 28, 2020
@Trott seems like the CI passed ✨ . Thank you! Could you complete your review with the new test change? |
Trott
commented
Feb 29, 2020
Landed in 3d894d0...8b1efe0 |
Remove a test that made a flawed assumption that a single large buffer write can be interrupted by a timeout event. PR-URL: nodejs#31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Change the test to not be sensitive to the buffer size causing TCP resets to be received by the client causing the test to fail. The test now reads the entire expected buffer and then checks for the expected event to fire. PR-URL: nodejs#31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Avoid copying buffers before passing to SSL_write if there are zero length buffers involved. Only copy the data when the buffer has a non zero length. Send a memory allocation hint to the crypto BIO about how much memory will likely be needed to be allocated by the next call to SSL_write. This makes a single allocation rather than the BIO allocating a buffer for each 16k TLS segment written. This solves a problem with large buffers written over TLS triggering V8's GC. PR-URL: nodejs#31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Remove a test that made a flawed assumption that a single large buffer write can be interrupted by a timeout event. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Change the test to not be sensitive to the buffer size causing TCP resets to be received by the client causing the test to fail. The test now reads the entire expected buffer and then checks for the expected event to fire. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Avoid copying buffers before passing to SSL_write if there are zero length buffers involved. Only copy the data when the buffer has a non zero length. Send a memory allocation hint to the crypto BIO about how much memory will likely be needed to be allocated by the next call to SSL_write. This makes a single allocation rather than the BIO allocating a buffer for each 16k TLS segment written. This solves a problem with large buffers written over TLS triggering V8's GC. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Remove a test that made a flawed assumption that a single large buffer write can be interrupted by a timeout event. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Change the test to not be sensitive to the buffer size causing TCP resets to be received by the client causing the test to fail. The test now reads the entire expected buffer and then checks for the expected event to fire. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Avoid copying buffers before passing to SSL_write if there are zero length buffers involved. Only copy the data when the buffer has a non zero length. Send a memory allocation hint to the crypto BIO about how much memory will likely be needed to be allocated by the next call to SSL_write. This makes a single allocation rather than the BIO allocating a buffer for each 16k TLS segment written. This solves a problem with large buffers written over TLS triggering V8's GC. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Remove a test that made a flawed assumption that a single large buffer write can be interrupted by a timeout event. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Change the test to not be sensitive to the buffer size causing TCP resets to be received by the client causing the test to fail. The test now reads the entire expected buffer and then checks for the expected event to fire. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Avoid copying buffers before passing to SSL_write if there are zero length buffers involved. Only copy the data when the buffer has a non zero length. Send a memory allocation hint to the crypto BIO about how much memory will likely be needed to be allocated by the next call to SSL_write. This makes a single allocation rather than the BIO allocating a buffer for each 16k TLS segment written. This solves a problem with large buffers written over TLS triggering V8's GC. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Remove a test that made a flawed assumption that a single large buffer write can be interrupted by a timeout event. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Change the test to not be sensitive to the buffer size causing TCP resets to be received by the client causing the test to fail. The test now reads the entire expected buffer and then checks for the expected event to fire. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Avoid copying buffers before passing to SSL_write if there are zero length buffers involved. Only copy the data when the buffer has a non zero length. Send a memory allocation hint to the crypto BIO about how much memory will likely be needed to be allocated by the next call to SSL_write. This makes a single allocation rather than the BIO allocating a buffer for each 16k TLS segment written. This solves a problem with large buffers written over TLS triggering V8's GC. PR-URL: #31499 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Avoid copying buffers before passing to SSL_write if there
are zero length buffers involved. Only copy the data when
the buffer has a non zero length.
Send a memory allocation hint to the crypto BIO about how much
memory will likely be needed to be allocated by the next call
to SSL_write. This makes a single allocation rather than the BIO
allocating a buffer for each 16k TLS segment written. This
solves a problem with large buffers written over TLS triggering
V8's GC.
make -j4 test(UNIX), orvcbuild test(Windows) passes