From: Sage Weil Date: Wed, 25 Nov 2015 19:39:08 +0000 (-0500) Subject: osd/ReplicatedPG: fix promotion recency logic X-Git-Tag: v10.0.3~161^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=180c8743addc5ae2f1db9c58cd2996ca6e7ac18b;p=ceph.git osd/ReplicatedPG: fix promotion recency logic Recency is defined as how many of the last N hitsets an object must appear in in order to be promoted. The previous logic did nothing of the sort... it checked for the object in any one of the last N hitsets, which led to way to many promotions and killed any chance of the cache performing properly. While we are here, we can simplify the code to drop the max_in_* fields (no longer necessary). Note that we may still want a notion of 'temperature' that does tolerate the object missing in one of the recent hitsets.. but that would be different than recency, and should probably be modeled after the eviction temperature model. Backport: infernalis, hammer Reported-by: Nick Fisk Signed-off-by: Sage Weil --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 64c77a4850b..1b1f5c5df83 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -2254,33 +2254,28 @@ bool ReplicatedPG::maybe_promote(ObjectContextRef obc, } break; default: - if (in_hit_set) { - promote_object(obc, missing_oid, oloc, promote_op); - } else { - // Check if in other hit sets - map::iterator itor; - bool in_other_hit_sets = false; - unsigned max_in_memory_read = pool.info.min_read_recency_for_promote > 0 ? pool.info.min_read_recency_for_promote - 1 : 0; - unsigned max_in_memory_write = pool.info.min_write_recency_for_promote > 0 ? pool.info.min_write_recency_for_promote - 1 : 0; - unsigned max_in_memory = MAX(max_in_memory_read, max_in_memory_write); - for (itor = agent_state->hit_set_map.begin(); itor != agent_state->hit_set_map.end() && max_in_memory--; ++itor) { - if (obc.get()) { - if (obc->obs.oi.soid != hobject_t() && itor->second->contains(obc->obs.oi.soid)) { - in_other_hit_sets = true; - break; - } - } else { - if (missing_oid != hobject_t() && itor->second->contains(missing_oid)) { - in_other_hit_sets = true; - break; - } - } + { + unsigned count = (int)in_hit_set; + if (count) { + // Check if in other hit sets + const hobject_t& oid = obc.get() ? obc->obs.oi.soid : missing_oid; + for (map::iterator itor = agent_state->hit_set_map.begin(); + itor != agent_state->hit_set_map.end(); + ++itor) { + if (!itor->second->contains(oid)) { + break; + } + ++count; + if (count >= recency) { + break; + } + } } - if (in_other_hit_sets) { - promote_object(obc, missing_oid, oloc, promote_op); + if (count >= recency) { + promote_object(obc, missing_oid, oloc, promote_op); } else { // not promoting - return false; + return false; } } break;