BlueStore::Onode,
boost::intrusive::list_member_hook<>,
&BlueStore::Onode::lru_item> > list_t;
- typedef boost::intrusive::list<
- BlueStore::Onode,
- boost::intrusive::member_hook<
- BlueStore::Onode,
- boost::intrusive::list_member_hook<>,
- &BlueStore::Onode::pin_item> > pin_list_t;
-
list_t lru;
- pin_list_t pin_list;
explicit LruOnodeCacheShard(CephContext *cct) : BlueStore::OnodeCacheShard(cct) {}
void _add(BlueStore::OnodeRef& o, int level) override
{
(level > 0) ? lru.push_front(*o) : lru.push_back(*o);
- o->s = this;
num = lru.size();
}
void _rm(BlueStore::OnodeRef& o) override
{
- o->s = nullptr;
- if (o->pinned) {
- o->pinned = false;
- pin_list.erase(pin_list.iterator_to(*o));
- } else {
- lru.erase(lru.iterator_to(*o));
- }
+ lru.erase(lru.iterator_to(*o));
num = lru.size();
- num_pinned = pin_list.size();
}
void _touch(BlueStore::OnodeRef& o) override
{
- if (o->pinned) {
- return;
- }
lru.erase(lru.iterator_to(*o));
lru.push_front(*o);
num = lru.size();
}
- void _pin(BlueStore::Onode& o) override
- {
- if (o.pinned == true) {
- return;
- }
- lru.erase(lru.iterator_to(o));
- pin_list.push_front(o);
- o.pinned = true;
- num = lru.size();
- num_pinned = pin_list.size();
- dout(30) << __func__ << " " << o.oid << " pinned" << dendl;
-
- }
- void _unpin(BlueStore::Onode& o) override
- {
- if (o.pinned == false) {
- return;
- }
- pin_list.erase(pin_list.iterator_to(o));
- lru.push_front(o);
- o.pinned = false;
- num = lru.size();
- num_pinned = pin_list.size();
- dout(30) << __func__ << " " << o.oid << " unpinned" << dendl;
- }
- void _trim_to(uint64_t new_size) override
+ void _trim_to(uint64_t max) override
{
- if (new_size >= lru.size()) {
+ if (max >= lru.size()) {
return; // don't even try
}
- uint64_t n = lru.size() - new_size;
+ uint64_t n = lru.size() - max;
+
auto p = lru.end();
ceph_assert(p != lru.begin());
--p;
+ int skipped = 0;
+ int max_skipped = g_conf()->bluestore_cache_trim_max_skip_pinned;
while (n > 0) {
BlueStore::Onode *o = &*p;
+ int refs = o->nref.load();
+ if (refs > 1) {
+ dout(20) << __func__ << " " << o->oid << " has " << refs
+ << " refs, skipping" << dendl;
+ if (++skipped >= max_skipped) {
+ dout(20) << __func__ << " maximum skip pinned reached; stopping with "
+ << n << " left to trim" << dendl;
+ break;
+ }
+
+ if (p == lru.begin()) {
+ break;
+ } else {
+ p--;
+ n--;
+ continue;
+ }
+ }
dout(30) << __func__ << " rm " << o->oid << dendl;
if (p != lru.begin()) {
lru.erase(p--);
lru.erase(p);
ceph_assert(n == 1);
}
- o->s = nullptr;
o->get(); // paranoia
o->c->onode_map.remove(o->oid);
o->put();
}
num = lru.size();
}
- void add_stats(uint64_t *onodes, uint64_t *pinned_onodes) override
+ void add_stats(uint64_t *onodes) override
{
- *onodes += num + num_pinned;
- *pinned_onodes += num_pinned;
+ *onodes += num;
}
};
b.add_u64(l_bluestore_onodes, "bluestore_onodes",
"Number of onodes in cache");
- b.add_u64(l_bluestore_pinned_onodes, "bluestore_pinned_onodes",
- "Number of pinned onodes in cache");
b.add_u64_counter(l_bluestore_onode_hits, "bluestore_onode_hits",
"Sum for onode-lookups hit in the cache");
b.add_u64_counter(l_bluestore_onode_misses, "bluestore_onode_misses",
void BlueStore::_update_cache_logger()
{
uint64_t num_onodes = 0;
- uint64_t num_pinned_onodes = 0;
uint64_t num_extents = 0;
uint64_t num_blobs = 0;
uint64_t num_buffers = 0;
uint64_t num_buffer_bytes = 0;
for (auto c : onode_cache_shards) {
- c->add_stats(&num_onodes, &num_pinned_onodes);
+ c->add_stats(&num_onodes);
}
for (auto c : buffer_cache_shards) {
c->add_stats(&num_extents, &num_blobs,
&num_buffers, &num_buffer_bytes);
}
logger->set(l_bluestore_onodes, num_onodes);
- logger->set(l_bluestore_pinned_onodes, num_pinned_onodes);
logger->set(l_bluestore_extents, num_extents);
logger->set(l_bluestore_blobs, num_blobs);
logger->set(l_bluestore_buffers, num_buffers);
l_bluestore_compressed_allocated,
l_bluestore_compressed_original,
l_bluestore_onodes,
- l_bluestore_pinned_onodes,
l_bluestore_onode_hits,
l_bluestore_onode_misses,
l_bluestore_onode_shard_hits,
};
struct OnodeSpace;
- struct OnodeCacheShard;
+
/// an in-memory object
struct Onode {
MEMPOOL_CLASS_HELPERS();
- // Not persisted and updated on cache insertion/removal
- OnodeCacheShard *s;
- bool pinned = false; // Only to be used by the onode cache shard
std::atomic_int nref; ///< reference count
Collection *c;
+
ghobject_t oid;
/// key under PREFIX_OBJ where we are stored
mempool::bluestore_cache_other::string key;
- boost::intrusive::list_member_hook<> lru_item, pin_item;
+ boost::intrusive::list_member_hook<> lru_item;
bluestore_onode_t onode; ///< metadata stored as value in kv store
bool exists; ///< true if object logically exists
Onode(Collection *c, const ghobject_t& o,
const mempool::bluestore_cache_other::string& k)
- : s(nullptr),
- nref(0),
+ : nref(0),
c(c),
oid(o),
key(k),
}
Onode(Collection* c, const ghobject_t& o,
const string& k)
- : s(nullptr),
- nref(0),
+ : nref(0),
c(c),
oid(o),
key(k),
}
Onode(Collection* c, const ghobject_t& o,
const char* k)
- : s(nullptr),
- nref(0),
+ : nref(0),
c(c),
oid(o),
key(k),
void flush();
void get() {
- if (++nref == 2 && s != nullptr) {
- s->pin(*this);
- }
+ ++nref;
}
void put() {
- int n = --nref;
- if (n == 1 && s != nullptr) {
- s->unpin(*this);
- }
- if (n == 0) {
+ if (--nref == 0)
delete this;
- }
}
const string& get_omap_prefix();
return num;
}
- virtual void _trim_to(uint64_t new_size) = 0;
+ virtual void _trim_to(uint64_t max) = 0;
void _trim() {
if (cct->_conf->objectstore_blackhole) {
// do not trim if we are throwing away IOs a layer down
}
_trim_to(max);
}
-
void trim() {
std::lock_guard l(lock);
_trim();
/// A Generic onode Cache Shard
struct OnodeCacheShard : public CacheShard {
- std::atomic<uint64_t> num_pinned = {0};
-
std::array<std::pair<ghobject_t, mono_clock::time_point>, 64> dumped_onodes;
public:
OnodeCacheShard(CephContext* cct) : CacheShard(cct) {}
virtual void _add(OnodeRef& o, int level) = 0;
virtual void _rm(OnodeRef& o) = 0;
virtual void _touch(OnodeRef& o) = 0;
- virtual void _pin(Onode& o) = 0;
- virtual void _unpin(Onode& o) = 0;
-
- void pin(Onode& o) {
- std::lock_guard l(lock);
- _pin(o);
- }
-
- void unpin(Onode& o) {
- std::lock_guard l(lock);
- _unpin(o);
- }
+ virtual void add_stats(uint64_t *onodes) = 0;
- virtual void add_stats(uint64_t *onodes, uint64_t *pinned_onodes) = 0;
bool empty() {
return _get_num() == 0;
}