Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mem limiter #368

Merged
merged 79 commits into from
Nov 21, 2023
Merged

Mem limiter #368

merged 79 commits into from
Nov 21, 2023

Conversation

DmitriyMusatkin
Copy link
Contributor

@DmitriyMusatkin DmitriyMusatkin commented Nov 9, 2023

Issue #, if available:
aws/aws-sdk-java-v2#4034

Description of changes:

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_client.c Outdated Show resolved Hide resolved
include/aws/s3/private/s3_buffer_pool.h Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
Copy link
Contributor

@graebm graebm left a comment

Choose a reason for hiding this comment

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

I didn't get very far, so some comments may be uninformed. I'll continue tomorrow...

include/aws/s3/s3_client.h Outdated Show resolved Hide resolved
include/aws/s3/private/s3_buffer_pool.h Outdated Show resolved Hide resolved
include/aws/s3/private/s3_buffer_pool.h Outdated Show resolved Hide resolved
include/aws/s3/private/s3_meta_request_impl.h Outdated Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented Nov 10, 2023

Codecov Report

Merging #368 (a6c69c2) into main (5fe1c3b) will increase coverage by 0.09%.
The diff coverage is 91.05%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #368      +/-   ##
==========================================
+ Coverage   88.45%   88.55%   +0.09%     
==========================================
  Files          19       20       +1     
  Lines        5120     5348     +228     
==========================================
+ Hits         4529     4736     +207     
- Misses        591      612      +21     
Files Coverage Δ
source/s3.c 95.65% <ø> (ø)
source/s3_auto_ranged_put.c 92.70% <100.00%> (+0.09%) ⬆️
source/s3_chunk_stream.c 76.87% <100.00%> (ø)
source/s3_meta_request.c 92.82% <100.00%> (-0.10%) ⬇️
source/s3_platform_info.c 45.33% <ø> (ø)
source/s3_request.c 95.25% <100.00%> (+0.04%) ⬆️
source/s3_auto_ranged_get.c 97.61% <80.00%> (-0.64%) ⬇️
source/s3_client.c 88.91% <84.61%> (-0.09%) ⬇️
source/s3_buffer_pool.c 91.82% <91.82%> (ø)

... and 1 file with indirect coverage changes

include/aws/s3/private/s3_request.h Outdated Show resolved Hide resolved
include/aws/s3/private/s3_request.h Outdated Show resolved Hide resolved
source/s3_auto_ranged_get.c Outdated Show resolved Hide resolved
source/s3_auto_ranged_get.c Outdated Show resolved Hide resolved
source/s3_auto_ranged_get.c Outdated Show resolved Hide resolved
source/s3_client.c Outdated Show resolved Hide resolved
source/s3_client.c Outdated Show resolved Hide resolved
source/s3_client.c Show resolved Hide resolved
source/s3_client.c Show resolved Hide resolved
source/s3_client.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
include/aws/s3/private/s3_buffer_pool.h Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_buffer_pool.c Outdated Show resolved Hide resolved
source/s3_client.c Outdated Show resolved Hide resolved
source/s3_client.c Outdated Show resolved Hide resolved
source/s3_client.c Show resolved Hide resolved
source/s3_client.c Show resolved Hide resolved
Comment on lines 1201 to 1203
aws_s3_client_lock_synced_data(client);
client->synced_data.trim_buffer_pool_task_scheduled = false;
aws_s3_client_unlock_synced_data(client);
Copy link
Contributor

Choose a reason for hiding this comment

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

we could move trim_buffer_pool_task_scheduled from synced_data to threaded_data and not bother with locks here, right? we only ever schedule this and run it from the client-work-thread?

Copy link
Contributor

@graebm graebm left a comment

Choose a reason for hiding this comment

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

fix & ship

Comment on lines 203 to 213
struct aws_s3_buffer_pool_ticket *aws_s3_buffer_pool_reserve(struct aws_s3_buffer_pool *buffer_pool, size_t size) {
AWS_PRECONDITION(buffer_pool);

if (buffer_pool->has_reservation_hold) {
return NULL;
}

if (size == 0) {
AWS_LOGF_ERROR(AWS_LS_S3_CLIENT, "Could not reserve from buffer pool. 0 is not a valid size.");
aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
return NULL;
Copy link
Contributor

Choose a reason for hiding this comment

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

Real code never checks the error-code from aws_s3_buffer_pool_reserve(). Real code assumes it failed due to the memory limit being temporarily exceeded.

  • so if size was 0, the meta-request would get stuck perpetually trying to acquire a ticket
  • similarly, if size > mem_limit the meta-request would be stuck perpetually trying to acquire a ticket. I realize you adjusted the client's max_part_size to make this impossible, but it might be worth an ASSERT or FATAL_ASSERT here in case client code changes in the future and something slips through

Anyway, we should probably do one of these things:

  1. real code calling aws_s3_buffer_pool_reserve() continues to assume that it can only fail when the mem limit is temporarily exceeded. And the reserve() function here FATAL_ASSERTs that the size is legal (not 0, not exceeding mem_limit)
  2. OR real code calling aws_s3_buffer_pool_reserve() checks to differentiate the expected "waiting for memory" from other errors that terminate the meta-request

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, good point. size == 0 or > mem_lim is really an indication that something wrong went on before, so for simplicity sake, i think fatal assert makes more sense.

source/s3_client.c Outdated Show resolved Hide resolved
source/s3_client.c Show resolved Hide resolved
@DmitriyMusatkin DmitriyMusatkin merged commit f961971 into main Nov 21, 2023
30 checks passed
@DmitriyMusatkin DmitriyMusatkin deleted the mem_ticket branch November 21, 2023 21:44
@DmitriyMusatkin DmitriyMusatkin changed the title (WIP) Mem limiter Mem limiter Nov 21, 2023
graebm added a commit that referenced this pull request May 9, 2024
… limit (#429)

**Issue:**
`aws_s3_meta_request_write()` must write to a buffer immediately if the data is less than part-size. Currently, it uses a buffer hooked up the to default allocator ([code here](https://github.com/awslabs/aws-c-s3/blob/cc06c419448b40417caa7b587f61bb4d8b4c08c1/source/s3_meta_request.c#L2260-L2262)). We'd like to get these buffers from the [buffer-pool](#368), to reduce memory fragmentation and resident set size (RSS).

The problem is: the buffer-pool maintains strict memory limits, and won't allow further allocations when that limit is hit. But `aws_s3_meta_request_write()` MUST get a buffer immediately, or else the system can deadlock (see description in PR #418)

**Description of changes:**
Add `aws_s3_buffer_pool_acquire_forced_buffer()`. These buffers can be created even if they exceed the memory limit.

**Future work:**
Modify `aws_s3_meta_request_write()` to use this new function

**Additional thoughts:**
- Anyone using `aws_s3_meta_request_write()` should limit the total number of uploads like: `max-uploads = memory-limit / part-size`. That was the case even before this PR.
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.

5 participants