From 8920f417bf71af98e9dd89613e39ddc140c2123c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 23 Oct 2012 09:20:35 -0700 Subject: [PATCH] osdc/ObjectCacher: make trim() trim Objects Pull unpinned objects off the LRU in trim(). This never happens currently due to all the explicit calls to close_object()... Signed-off-by: Sage Weil --- src/client/Client.cc | 1 + src/common/config_opts.h | 1 + src/librbd/ImageCtx.cc | 1 + src/osdc/ObjectCacher.cc | 34 ++++++++++++++++++++++------------ src/osdc/ObjectCacher.h | 11 ++++++++--- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index de9475f91743c..e7b14dea30c6f 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -158,6 +158,7 @@ Client::Client(Messenger *m, MonClient *mc) client_flush_set_callback, // all commit callback (void*)this, cct->_conf->client_oc_size, + cct->_conf->client_oc_max_objects, cct->_conf->client_oc_max_dirty, cct->_conf->client_oc_target_dirty, cct->_conf->client_oc_max_dirty_age); diff --git a/src/common/config_opts.h b/src/common/config_opts.h index c95af92b58b54..6bb37be338b2e 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -172,6 +172,7 @@ OPTION(client_oc_size, OPT_INT, 1024*1024* 200) // MB * n OPTION(client_oc_max_dirty, OPT_INT, 1024*1024* 100) // MB * n (dirty OR tx.. bigish) OPTION(client_oc_target_dirty, OPT_INT, 1024*1024* 8) // target dirty (keep this smallish) OPTION(client_oc_max_dirty_age, OPT_DOUBLE, 5.0) // max age in cache before writeback +OPTION(client_oc_max_objects, OPT_INT, 1000) // max objects in cache // note: the max amount of "in flight" dirty data is roughly (max - target) OPTION(fuse_use_invalidate_cb, OPT_BOOL, false) // use fuse 2.8+ invalidate callback to keep page cache consistent OPTION(fuse_big_writes, OPT_BOOL, true) diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index 403908af51c40..273aa6eb392be 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -73,6 +73,7 @@ namespace librbd { object_cacher = new ObjectCacher(cct, pname, *writeback_handler, cache_lock, NULL, NULL, cct->_conf->rbd_cache_size, + cct->_conf->rbd_cache_size / (4 << 20) * 2 + 10, cct->_conf->rbd_cache_max_dirty, cct->_conf->rbd_cache_target_dirty, cct->_conf->rbd_cache_max_dirty_age); diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index c5a08e681c1bb..e4a7e3195ed98 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -425,10 +425,12 @@ void ObjectCacher::Object::discard(loff_t off, loff_t len) ObjectCacher::ObjectCacher(CephContext *cct_, string name, WritebackHandler& wb, Mutex& l, flush_set_callback_t flush_callback, void *flush_callback_arg, - uint64_t max_size, uint64_t max_dirty, uint64_t target_dirty, double max_dirty_age) + uint64_t max_bytes, uint64_t max_objects, + uint64_t max_dirty, uint64_t target_dirty, double max_dirty_age) : perfcounter(NULL), cct(cct_), writeback_handler(wb), name(name), lock(l), - max_dirty(max_dirty), target_dirty(target_dirty), max_size(max_size), + max_dirty(max_dirty), target_dirty(target_dirty), + max_size(max_bytes), max_objects(max_objects), flush_set_callback(flush_callback), flush_set_callback_arg(flush_callback_arg), flusher_stop(false), flusher_thread(this), stat_clean(0), stat_dirty(0), stat_rx(0), stat_tx(0), stat_missing(0), @@ -815,22 +817,25 @@ void ObjectCacher::flush(loff_t amount) } -void ObjectCacher::trim(loff_t max_bytes, loff_t max_objects) +void ObjectCacher::trim(loff_t max_bytes, loff_t max_ob) { - if (max < 0) - max = max_size; + if (max_bytes < 0) + max_bytes = max_size; + if (max_ob < 0) + max_ob = max_objects; ldout(cct, 10) << "trim start: bytes: max " << max_bytes << " clean " << get_stat_clean() - << ", objects: max " << max_objects << " current " << ob_lru.get_lru_size() + << ", objects: max " << max_ob << " current " << ob_lru.lru_get_size() << dendl; while (get_stat_clean() > max_bytes) { BufferHead *bh = (BufferHead*) bh_lru_rest.lru_expire(); - if (!bh) break; - + if (!bh) + break; + ldout(cct, 10) << "trim trimming " << *bh << dendl; assert(bh->is_clean()); - + Object *ob = bh->ob; bh_remove(ob, bh); delete bh; @@ -841,12 +846,17 @@ void ObjectCacher::trim(loff_t max_bytes, loff_t max_objects) } } - while (ob_lru.lru_get_size() > max_objects) { - // ... + while (ob_lru.lru_get_size() > max_ob) { + Object *ob = (Object*)ob_lru.lru_expire(); + if (!ob) + break; + + ldout(cct, 10) << "trim trimming " << *ob << dendl; + close_object(ob); } ldout(cct, 10) << "trim finish: max " << max_bytes << " clean " << get_stat_clean() - << ", objects: max " << max_objects << " current " << ob_lru.get_lru_size() + << ", objects: max " << max_ob << " current " << ob_lru.lru_get_size() << dendl; } diff --git a/src/osdc/ObjectCacher.h b/src/osdc/ObjectCacher.h index ac17c4f8daca8..ff0676f6e2b96 100644 --- a/src/osdc/ObjectCacher.h +++ b/src/osdc/ObjectCacher.h @@ -325,7 +325,7 @@ class ObjectCacher { string name; Mutex& lock; - int64_t max_dirty, target_dirty, max_size; + int64_t max_dirty, target_dirty, max_size, max_objects; utime_t max_dirty_age; flush_set_callback_t flush_set_callback; @@ -416,7 +416,7 @@ class ObjectCacher { void bh_read(BufferHead *bh); void bh_write(BufferHead *bh); - void trim(loff_t max=-1); + void trim(loff_t max_bytes=-1, loff_t max_objects=-1); void flush(loff_t amount=0); /** @@ -501,7 +501,8 @@ class ObjectCacher { ObjectCacher(CephContext *cct_, string name, WritebackHandler& wb, Mutex& l, flush_set_callback_t flush_callback, void *flush_callback_arg, - uint64_t max_size, uint64_t max_dirty, uint64_t target_dirty, double max_age); + uint64_t max_bytes, uint64_t max_objects, + uint64_t max_dirty, uint64_t target_dirty, double max_age); ~ObjectCacher(); void start() { @@ -583,6 +584,10 @@ public: void set_max_dirty_age(double a) { max_dirty_age.set_from_double(a); } + void set_max_objects(int64_t v) { + max_objects = v; + } + // file functions -- 2.39.5