diff options
Diffstat (limited to 'src/common/PriorityCache.h')
-rw-r--r-- | src/common/PriorityCache.h | 161 |
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 |