From ecc168fca30e352ffcad25163a5d7c5565ee6b30 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 10 Jun 2016 09:33:20 -0400 Subject: [PATCH] os/bluestore: make Cache implementation configurable For now we only do "lru" (LRUCache). Signed-off-by: Sage Weil --- src/common/config_opts.h | 1 + src/os/bluestore/BlueStore.cc | 29 +++++++++++------ src/os/bluestore/BlueStore.h | 61 ++++++++++++++++++++++++----------- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index e499cdb5f85..f85c2e38614 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -964,6 +964,7 @@ OPTION(bluestore_compression, OPT_STR, "none") // force|aggressive|passive|none OPTION(bluestore_compression_algorithm, OPT_STR, "snappy") OPTION(bluestore_compression_min_blob_size, OPT_U32, 256*1024) OPTION(bluestore_compression_max_blob_size, OPT_U32, 4*1024*1024) +OPTION(bluestore_cache_type, OPT_STR, "lru") OPTION(bluestore_onode_cache_size, OPT_U32, 16*1024) OPTION(bluestore_buffer_cache_size, OPT_U32, 256*1024*1024) OPTION(bluestore_cache_tails, OPT_BOOL, true) // cache tail blocks in Onode diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index c1ab8e42d2b..08b7dffb22e 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -445,17 +445,26 @@ ostream& operator<<(ostream& out, const BlueStore::Buffer& b) // Cache + +BlueStore::Cache *BlueStore::Cache::create(string type) +{ + if (type == "lru") + return new LRUCache; + assert(0 == "unrecognized cache type"); +} + +// LRUCache #undef dout_prefix -#define dout_prefix *_dout << "bluestore.Cache(" << this << ") " +#define dout_prefix *_dout << "bluestore.LRUCache(" << this << ") " -void BlueStore::Cache::_touch_onode(OnodeRef& o) +void BlueStore::LRUCache::_touch_onode(OnodeRef& o) { auto p = onode_lru.iterator_to(*o); onode_lru.erase(p); onode_lru.push_front(*o); } -void BlueStore::Cache::trim(uint64_t onode_max, uint64_t buffer_max) +void BlueStore::LRUCache::trim(uint64_t onode_max, uint64_t buffer_max) { std::lock_guard l(lock); @@ -463,7 +472,7 @@ void BlueStore::Cache::trim(uint64_t onode_max, uint64_t buffer_max) << " buffers " << buffer_size << " / " << buffer_max << dendl; - _audit_lru("trim start"); + _audit("trim start"); // buffers auto i = buffer_lru.end(); @@ -520,7 +529,7 @@ void BlueStore::Cache::trim(uint64_t onode_max, uint64_t buffer_max) } #ifdef DEBUG_CACHE -void BlueStore::Cache::_audit_lru(const char *when) +void BlueStore::LRUCache::_audit(const char *when) { if (true) { dout(10) << __func__ << " " << when << " start" << dendl; @@ -599,7 +608,7 @@ void BlueStore::BufferSpace::_clear() void BlueStore::BufferSpace::_discard(uint64_t offset, uint64_t length) { - cache->_audit_lru("discard start"); + cache->_audit("discard start"); auto i = _data_lower_bound(offset); uint64_t end = offset + length; while (i != buffer_map.end()) { @@ -621,7 +630,7 @@ void BlueStore::BufferSpace::_discard(uint64_t offset, uint64_t length) } cache->_adjust_buffer_size(b, front - (int64_t)b->length); b->truncate(front); - cache->_audit_lru("discard end 1"); + cache->_audit("discard end 1"); return; } else { // drop tail @@ -647,7 +656,7 @@ void BlueStore::BufferSpace::_discard(uint64_t offset, uint64_t length) _add_buffer(new Buffer(this, b->state, b->seq, end, keep), 0, b); _rm_buffer(i); } - cache->_audit_lru("discard end 2"); + cache->_audit("discard end 2"); return; } } @@ -724,7 +733,7 @@ void BlueStore::BufferSpace::finish_write(uint64_t seq) ++i; } } - cache->_audit_lru("finish_write end"); + cache->_audit("finish_write end"); } // OnodeSpace @@ -2308,7 +2317,7 @@ void BlueStore::set_cache_shards(unsigned num) assert(num >= old); cache_shards.resize(num); for (unsigned i = old; i < num; ++i) { - cache_shards[i] = new Cache; + cache_shards[i] = Cache::create(g_conf->bluestore_cache_type); } } diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index d160f66caea..247fa1afa26 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -212,27 +212,27 @@ public: } void _add_buffer(Buffer *b, int level, Buffer *near) { - cache->_audit_lru("_add_buffer start"); + cache->_audit("_add_buffer start"); buffer_map[b->offset].reset(b); if (b->is_writing()) { writing.push_back(*b); } else { cache->_add_buffer(b, level, near); } - cache->_audit_lru("_add_buffer end"); + cache->_audit("_add_buffer end"); } void _rm_buffer(Buffer *b) { _rm_buffer(buffer_map.find(b->offset)); } void _rm_buffer(map>::iterator p) { - cache->_audit_lru("_rm_buffer start"); + cache->_audit("_rm_buffer start"); if (p->second->is_writing()) { writing.erase(writing.iterator_to(*p->second)); } else { cache->_rm_buffer(p->second.get()); } buffer_map.erase(p); - cache->_audit_lru("_rm_buffer end"); + cache->_audit("_rm_buffer end"); } map>::iterator _data_lower_bound( @@ -498,6 +498,31 @@ public: /// a cache (shard) of onodes and buffers struct Cache { + std::mutex lock; ///< protect lru and other structures + + static Cache *create(string type); + + virtual ~Cache() {} + + virtual void _add_onode(OnodeRef& o, int level) = 0; + virtual void _rm_onode(OnodeRef& o) = 0; + virtual void _touch_onode(OnodeRef& o) = 0; + + virtual void _add_buffer(Buffer *b, int level, Buffer *near) = 0; + virtual void _rm_buffer(Buffer *b) = 0; + virtual void _adjust_buffer_size(Buffer *b, int64_t delta) = 0; + virtual void _touch_buffer(Buffer *b) = 0; + + virtual void trim(uint64_t onode_max, uint64_t buffer_max) = 0; + +#ifdef DEBUG_CACHE + virtual void _audit(const char *s) = 0; +#else + void _audit(const char *s) { /* no-op */ } +#endif + }; + + struct LRUCache : public Cache { private: typedef boost::intrusive::list< Onode, @@ -518,21 +543,19 @@ public: uint64_t buffer_size = 0; public: - std::mutex lock; ///< protect lru and other structures - - void _add_onode(OnodeRef& o, int level) { + void _add_onode(OnodeRef& o, int level) override { if (level > 0) onode_lru.push_front(*o); else onode_lru.push_back(*o); } - void _rm_onode(OnodeRef& o) { + void _rm_onode(OnodeRef& o) override { auto q = onode_lru.iterator_to(*o); onode_lru.erase(q); } - void _touch_onode(OnodeRef& o); + void _touch_onode(OnodeRef& o) override; - void _add_buffer(Buffer *b, int level, Buffer *near) { + void _add_buffer(Buffer *b, int level, Buffer *near) override { if (near) { auto q = buffer_lru.iterator_to(*near); buffer_lru.insert(q, *b); @@ -543,30 +566,29 @@ public: } buffer_size += b->length; } - void _rm_buffer(Buffer *b) { + void _rm_buffer(Buffer *b) override { assert(buffer_size >= b->length); buffer_size -= b->length; auto q = buffer_lru.iterator_to(*b); buffer_lru.erase(q); } - void _adjust_buffer_size(Buffer *b, int64_t delta) { + void _adjust_buffer_size(Buffer *b, int64_t delta) override { assert((int64_t)buffer_size + delta >= 0); buffer_size += delta; } - void _touch_buffer(Buffer *b) { + void _touch_buffer(Buffer *b) override { auto p = buffer_lru.iterator_to(*b); buffer_lru.erase(p); buffer_lru.push_front(*b); - _audit_lru("_touch_buffer end"); + _audit("_touch_buffer end"); } - void trim(uint64_t onode_max, uint64_t buffer_max); + void trim(uint64_t onode_max, uint64_t buffer_max) override; #ifdef DEBUG_CACHE - void _audit_lru(const char *s); -#else - void _audit_lru(const char *s) { /* no-op */ } + void _audit(const char *s) override; #endif + }; struct OnodeSpace { @@ -580,7 +602,8 @@ public: void add(const ghobject_t& oid, OnodeRef o); OnodeRef lookup(const ghobject_t& o); - void rename(OnodeRef& o, const ghobject_t& old_oid, const ghobject_t& new_oid); + void rename(OnodeRef& o, const ghobject_t& old_oid, + const ghobject_t& new_oid); void clear(); /// return true if f true for any item -- 2.39.5