From fea212bc5a283c954dd6bb6956efef6b7d76c09b Mon Sep 17 00:00:00 2001 From: liubingrun Date: Sun, 3 Sep 2023 14:29:47 -0400 Subject: [PATCH] rgw: improve the efficiency of buffer list utilization of chunk upload Reduced waste of buffer::ptr by receiving multiple chunks and filling them into the buffer AWSv4ComplMulti::recv_body() just receive one chunk and fill it into buffer. Each 4MB buffer is actually only utilizing 64KB, leading to frequent buffer allocations. ~800GB virtual memory consumption has been observed. Signed-off-by: liubingrun (cherry picked from commit e47bb22f69ee83479431994ce6514bb739f5dd98) --- src/rgw/rgw_auth_s3.cc | 17 ++++++++++++++++- src/rgw/rgw_auth_s3.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index 89d3b6659163a..d3e1c3265ec09 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -1111,7 +1111,7 @@ bool AWSv4ComplMulti::is_signature_mismatched() } } -size_t AWSv4ComplMulti::recv_body(char* const buf, const size_t buf_max) +size_t AWSv4ComplMulti::recv_chunk(char* const buf, const size_t buf_max, bool& eof) { /* Buffer stores only parsed stream. Raw values reflect the stream * we're getting from a client. */ @@ -1136,6 +1136,7 @@ size_t AWSv4ComplMulti::recv_body(char* const buf, const size_t buf_max) to_extract); parsing_buf.resize(parsing_buf.size() - (to_extract - received)); if (received == 0) { + eof = true; break; } @@ -1185,6 +1186,7 @@ size_t AWSv4ComplMulti::recv_body(char* const buf, const size_t buf_max) dout(30) << "AWSv4ComplMulti: to_extract=" << to_extract << ", received=" << received << dendl; if (received == 0) { + eof = true; break; } @@ -1199,6 +1201,19 @@ size_t AWSv4ComplMulti::recv_body(char* const buf, const size_t buf_max) return buf_pos; } +size_t AWSv4ComplMulti::recv_body(char* const buf, const size_t buf_max) +{ + bool eof = false; + size_t total = 0; + + while (total < buf_max && !eof) { + const size_t received = recv_chunk(buf + total, buf_max - total, eof); + total += received; + } + dout(20) << "AWSv4ComplMulti: received=" << total << dendl; + return total; +} + void AWSv4ComplMulti::modify_request_state(const DoutPrefixProvider* dpp, req_state* const s_rw) { const char* const decoded_length = \ diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index 00eddc46f30b0..bda14ab1f678e 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -332,6 +332,7 @@ class AWSv4ComplMulti : public rgw::auth::Completer, bool is_signature_mismatched(); std::string calc_chunk_signature(const std::string& payload_hash) const; + size_t recv_chunk(char* buf, size_t max, bool& eof); public: /* We need the constructor to be public because of the std::make_shared that -- 2.39.5