summaryrefslogtreecommitdiffstats
path: root/src/common/PriorityCache.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/PriorityCache.h')
-rw-r--r--src/common/PriorityCache.h161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/common/PriorityCache.h b/src/common/PriorityCache.h
new file mode 100644
index 000000000..8233d0ecf
--- /dev/null
+++ b/src/common/PriorityCache.h
@@ -0,0 +1,161 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2018 Red Hat
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_PRIORITY_CACHE_H
+#define CEPH_PRIORITY_CACHE_H
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <memory>
+#include <unordered_map>
+#include "common/perf_counters.h"
+#include "include/ceph_assert.h"
+
+namespace PriorityCache {
+ // Reserve 16384 slots for PriorityCache perf counters
+ const int PERF_COUNTER_LOWER_BOUND = 1073741824;
+ const int PERF_COUNTER_MAX_BOUND = 1073758208;
+
+ enum MallocStats {
+ M_FIRST = PERF_COUNTER_LOWER_BOUND,
+ M_TARGET_BYTES,
+ M_MAPPED_BYTES,
+ M_UNMAPPED_BYTES,
+ M_HEAP_BYTES,
+ M_CACHE_BYTES,
+ M_LAST,
+ };
+
+ enum Priority {
+ PRI0,
+ PRI1,
+ PRI2,
+ PRI3,
+ PRI4,
+ PRI5,
+ PRI6,
+ PRI7,
+ PRI8,
+ PRI9,
+ PRI10,
+ PRI11,
+ LAST = PRI11,
+ };
+
+ enum Extra {
+ E_RESERVED = Priority::LAST+1,
+ E_COMMITTED,
+ E_LAST = E_COMMITTED,
+ };
+
+ int64_t get_chunk(uint64_t usage, uint64_t total_bytes);
+
+ struct PriCache {
+ virtual ~PriCache();
+
+ /* Ask the cache to request memory for the given priority. Note that the
+ * cache may ultimately be allocated less memory than it requests here.
+ */
+ virtual int64_t request_cache_bytes(PriorityCache::Priority pri, uint64_t total_cache) const = 0;
+
+ // Get the number of bytes currently allocated to the given priority.
+ virtual int64_t get_cache_bytes(PriorityCache::Priority pri) const = 0;
+
+ // Get the number of bytes currently allocated to all priorities.
+ virtual int64_t get_cache_bytes() const = 0;
+
+ // Allocate bytes for a given priority.
+ virtual void set_cache_bytes(PriorityCache::Priority pri, int64_t bytes) = 0;
+
+ // Allocate additional bytes for a given priority.
+ virtual void add_cache_bytes(PriorityCache::Priority pri, int64_t bytes) = 0;
+
+ /* Commit the current number of bytes allocated to the cache. Space is
+ * allocated in chunks based on the allocation size and current total size
+ * of memory available for caches. */
+ virtual int64_t commit_cache_size(uint64_t total_cache) = 0;
+
+ /* Get the current number of bytes allocated to the cache. this may be
+ * larger than the value returned by get_cache_bytes as it includes extra
+ * space for future growth. */
+ virtual int64_t get_committed_size() const = 0;
+
+ // Get the ratio of available memory this cache should target.
+ virtual double get_cache_ratio() const = 0;
+
+ // Set the ratio of available memory this cache should target.
+ virtual void set_cache_ratio(double ratio) = 0;
+
+ // Get the name of this cache.
+ virtual std::string get_cache_name() const = 0;
+
+ // Rotate the bins
+ virtual void shift_bins() = 0;
+
+ // Import user bins (from PRI1 to LAST-1)
+ virtual void import_bins(const std::vector<uint64_t> &bins) = 0;
+
+ // Set bins (PRI0 and LAST should be ignored)
+ virtual void set_bins(PriorityCache::Priority pri, uint64_t end_bin) = 0;
+
+ // Get bins
+ virtual uint64_t get_bins(PriorityCache::Priority pri) const = 0;
+ };
+
+ class Manager {
+ CephContext* cct = nullptr;
+ PerfCounters* logger;
+ std::unordered_map<std::string, PerfCounters*> loggers;
+ std::unordered_map<std::string, std::vector<int>> indexes;
+ std::unordered_map<std::string, std::shared_ptr<PriCache>> caches;
+
+ // Start perf counter slots after the malloc stats.
+ int cur_index = MallocStats::M_LAST;
+
+ uint64_t min_mem = 0;
+ uint64_t max_mem = 0;
+ uint64_t target_mem = 0;
+ uint64_t tuned_mem = 0;
+ bool reserve_extra;
+ std::string name;
+ public:
+ Manager(CephContext *c, uint64_t min, uint64_t max, uint64_t target,
+ bool reserve_extra, const std::string& name = std::string());
+ ~Manager();
+ void set_min_memory(uint64_t min) {
+ min_mem = min;
+ }
+ void set_max_memory(uint64_t max) {
+ max_mem = max;
+ }
+ void set_target_memory(uint64_t target) {
+ target_mem = target;
+ }
+ uint64_t get_tuned_mem() const {
+ return tuned_mem;
+ }
+ void insert(const std::string& name, const std::shared_ptr<PriCache> c,
+ bool enable_perf_counters);
+ void erase(const std::string& name);
+ void clear();
+ void tune_memory();
+ void balance();
+ void shift_bins();
+ private:
+ void balance_priority(int64_t *mem_avail, Priority pri);
+ };
+}
+
+#endif