From: Yehuda Sadeh Date: Thu, 22 Feb 2018 21:57:33 +0000 (-0800) Subject: rgw: use a single gc io manager for all shards X-Git-Tag: v12.2.13~191^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=234af96ec979b620d3c46b173e95c427c2ea7fe3;p=ceph.git rgw: use a single gc io manager for all shards to allow cross shards concurrency Signed-off-by: Yehuda Sadeh (cherry picked from commit e60404cb18682dcc6dad03ee1806a601d5c8b2e0) --- diff --git a/src/rgw/rgw_gc.cc b/src/rgw/rgw_gc.cc index 00f82aa2831..9ff04b09058 100644 --- a/src/rgw/rgw_gc.cc +++ b/src/rgw/rgw_gc.cc @@ -131,28 +131,27 @@ int RGWGC::list(int *index, string& marker, uint32_t max, bool expired_only, std class RGWGCIOManager { CephContext *cct; RGWGC *gc; - int index; struct IO { librados::AioCompletion *c{nullptr}; string oid; + int index{-1}; string tag; }; list ios; - std::list remove_tags; + map > remove_tags; public: - RGWGCIOManager(CephContext *_cct, RGWGC *_gc, int _index) : cct(_cct), - gc(_gc), - index(_index) {} + RGWGCIOManager(CephContext *_cct, RGWGC *_gc) : cct(_cct), + gc(_gc) {} ~RGWGCIOManager() { for (auto io : ios) { io.c->release(); } } - int schedule_io(IoCtx *ioctx, const string& oid, ObjectWriteOperation *op, const string& tag) { + int schedule_io(IoCtx *ioctx, const string& oid, ObjectWriteOperation *op, int index, const string& tag) { #warning configurable #define MAX_CONCURRENT_IO 5 while (ios.size() > MAX_CONCURRENT_IO) { @@ -167,7 +166,7 @@ public: if (ret < 0) { return ret; } - ios.push_back(IO{c, oid, tag}); + ios.push_back(IO{c, oid, index, tag}); return 0; } @@ -179,6 +178,8 @@ public: int ret = io.c->get_return_value(); io.c->release(); + auto& rt = remove_tags[io.index]; + if (ret == -ENOENT) { ret = 0; } @@ -187,10 +188,10 @@ public: goto done; } - remove_tags.push_back(io.tag); + rt.push_back(io.tag); #define MAX_REMOVE_CHUNK 16 - if (remove_tags.size() > MAX_REMOVE_CHUNK) { - drain_remove_tags(); + if (rt.size() > MAX_REMOVE_CHUNK) { + drain_remove_tags(io.index, rt); } done: ios.pop_front(); @@ -207,19 +208,24 @@ done: drain_remove_tags(); } + void drain_remove_tags(int index, list& rt) { + gc->remove(index, rt); + rt.clear(); + } + void drain_remove_tags() { - gc->remove(index, remove_tags); - remove_tags.clear(); + for (auto iter : remove_tags) { + drain_remove_tags(iter.first, iter.second); + } } }; -int RGWGC::process(int index, int max_secs, bool expired_only) +int RGWGC::process(int index, int max_secs, bool expired_only, + RGWGCIOManager& io_manager) { rados::cls::lock::Lock l(gc_index_lock_name); utime_t end = ceph_clock_now(); - RGWGCIOManager io_manager(store->ctx(), this, index); - /* max_secs should be greater than zero. We don't want a zero max_secs * to be translated as no timeout, since we'd then need to break the * lock and that would require a manual intervention. In this case @@ -288,7 +294,7 @@ int RGWGC::process(int index, int max_secs, bool expired_only) ObjectWriteOperation op; cls_refcount_put(op, info.tag, true); - ret = io_manager.schedule_io(ctx, oid, &op, info.tag); + ret = io_manager.schedule_io(ctx, oid, &op, index, info.tag); if (ret < 0) { ldout(store->ctx(), 0) << "WARNING: failed to schedule deletion for oid=" << oid << dendl; } @@ -299,8 +305,6 @@ int RGWGC::process(int index, int max_secs, bool expired_only) } } while (truncated); - io_manager.drain(); - done: /* we don't drain here, because if we're going down we don't want to hold the system * if backend is unresponsive @@ -319,12 +323,17 @@ int RGWGC::process(bool expired_only) if (ret < 0) return ret; + RGWGCIOManager io_manager(store->ctx(), this); + for (int i = 0; i < max_objs; i++) { int index = (i + start) % max_objs; - int ret = process(index, max_secs, expired_only); + int ret = process(index, max_secs, expired_only, io_manager); if (ret < 0) return ret; } + if (!going_down()) { + io_manager.drain(); + } return 0; } diff --git a/src/rgw/rgw_gc.h b/src/rgw/rgw_gc.h index bab44b7fd34..7eb38711db4 100644 --- a/src/rgw/rgw_gc.h +++ b/src/rgw/rgw_gc.h @@ -16,6 +16,8 @@ #include +class RGWGCIOManager; + class RGWGC { CephContext *cct; RGWRados *store; @@ -55,7 +57,8 @@ public: int list(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated); void list_init(int *index) { *index = 0; } - int process(int index, int process_max_secs, bool expired_only); + int process(int index, int process_max_secs, bool expired_only, + RGWGCIOManager& io_manager); int process(bool expired_only); bool going_down();