remove compact reclamation (#31857)

pull/31864/head
Alisha Nanda 2 years ago committed by GitHub
parent 988e39b5d1
commit 2f05aa8984
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      src/core/lib/resource_quota/memory_quota.cc
  2. 18
      src/core/lib/resource_quota/memory_quota.h

@ -289,37 +289,6 @@ void GrpcMemoryAllocatorImpl::Replenish() {
taken_bytes_.fetch_add(amount, std::memory_order_relaxed);
// Add the taken amount to the free pool.
free_bytes_.fetch_add(amount, std::memory_order_acq_rel);
// See if we can add ourselves as a reclaimer.
MaybeRegisterReclaimer();
}
void GrpcMemoryAllocatorImpl::MaybeRegisterReclaimer() {
// If the reclaimer is already registered, then there's nothing to do.
if (registered_reclaimer_.exchange(true, std::memory_order_relaxed)) {
return;
}
MutexLock lock(&reclaimer_mu_);
if (shutdown_) return;
// Grab references to the things we'll need
auto self = shared_from_this();
std::weak_ptr<EventEngineMemoryAllocatorImpl> self_weak{self};
registered_reclaimer_ = true;
InsertReclaimer(0, [self_weak](absl::optional<ReclamationSweep> sweep) {
if (!sweep.has_value()) return;
auto self = self_weak.lock();
if (self == nullptr) return;
auto* p = static_cast<GrpcMemoryAllocatorImpl*>(self.get());
p->registered_reclaimer_.store(false, std::memory_order_relaxed);
// Figure out how many bytes we can return to the quota.
size_t return_bytes = p->free_bytes_.exchange(0, std::memory_order_acq_rel);
if (return_bytes == 0) return;
p->memory_quota_->MaybeMoveAllocator(p, /*old_free_bytes=*/return_bytes,
/*new_free_bytes=*/0);
// Subtract that from our outstanding balance.
p->taken_bytes_.fetch_sub(return_bytes);
// And return them to the quota.
p->memory_quota_->Return(return_bytes);
});
}
//
@ -371,10 +340,9 @@ void BasicMemoryQuota::Start() {
return std::make_tuple(name, std::move(f));
};
};
return Race(Map(self->reclaimers_[0].Next(), annotate("compact")),
Map(self->reclaimers_[1].Next(), annotate("benign")),
Map(self->reclaimers_[2].Next(), annotate("idle")),
Map(self->reclaimers_[3].Next(), annotate("destructive")));
return Race(Map(self->reclaimers_[0].Next(), annotate("benign")),
Map(self->reclaimers_[1].Next(), annotate("idle")),
Map(self->reclaimers_[2].Next(), annotate("destructive")));
},
[self](
std::tuple<const char*, RefCountedPtr<ReclaimerQueue::Handle>> arg) {

@ -68,26 +68,22 @@ using Vector = grpc_event_engine::experimental::Vector<T>;
// reclaimers. We do this in multiple passes: if there is a less destructive
// operation available, we do that, otherwise we do something more destructive.
enum class ReclamationPass {
// Non-empty reclamation ought to take index 0, but to simplify API we don't
// expose that publicly (it's an internal detail), and hence index zero is
// here unnamed.
// Benign reclamation is intended for reclamation steps that are not
// observable outside of gRPC (besides maybe causing an increase in CPU
// usage).
// Examples of such reclamation would be resizing buffers to fit the current
// load needs, rather than whatever was the peak usage requirement.
kBenign = 1,
kBenign = 0,
// Idle reclamation is intended for reclamation steps that are observable
// outside of gRPC, but do not cause application work to be lost.
// Examples of such reclamation would be dropping channels that are not being
// used.
kIdle = 2,
kIdle = 1,
// Destructive reclamation is our last resort, and is these reclamations are
// allowed to drop work - such as cancelling in flight requests.
kDestructive = 3,
kDestructive = 2,
};
static constexpr size_t kNumReclamationPasses = 4;
static constexpr size_t kNumReclamationPasses = 3;
// For each reclamation function run we construct a ReclamationSweep.
// When this object is finally destroyed (it may be moved several times first),
@ -416,8 +412,6 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
}
size_t new_free = free_bytes_.load(std::memory_order_relaxed);
memory_quota_->MaybeMoveAllocator(this, prev_free, new_free);
if (prev_free != 0) return;
MaybeRegisterReclaimer();
}
// Return all free bytes to quota.
@ -471,9 +465,6 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
// Replenish bytes from the quota, without blocking, possibly entering
// overcommit.
void Replenish();
// If we have not already, register a reclamation function against the quota
// to sweep any free memory back to that quota.
void MaybeRegisterReclaimer() ABSL_LOCKS_EXCLUDED(reclaimer_mu_);
template <typename F>
void InsertReclaimer(size_t pass, F fn)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(reclaimer_mu_) {
@ -492,7 +483,6 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
std::atomic<size_t> taken_bytes_{sizeof(GrpcMemoryAllocatorImpl)};
// Index used to randomly choose shard to return bytes from.
std::atomic<size_t> chosen_shard_idx_{0};
std::atomic<bool> registered_reclaimer_{false};
// We try to donate back some memory periodically to the central quota.
PeriodicUpdate donate_back_{Duration::Seconds(10)};
Mutex reclaimer_mu_;

Loading…
Cancel
Save