From c269f352e538b795858b963644a05a65a04b6a8e Mon Sep 17 00:00:00 2001 From: Aishwarya Mathuria Date: Mon, 18 Mar 2024 04:47:06 +0000 Subject: [PATCH] osd/scrubber: Add a function to calculate scrub cost for mClock With mClock scheduler, we need the cost of an operation to represent the size of an operation. This function will calculate the average object size of the PG that needs to be scrubbed and return it as the scrub cost. Signed-off-by: Aishwarya Mathuria --- src/osd/scrubber/pg_scrubber.cc | 34 ++++++++++++++++++++++++++++----- src/osd/scrubber/pg_scrubber.h | 7 ++++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/osd/scrubber/pg_scrubber.cc b/src/osd/scrubber/pg_scrubber.cc index 9266a54d785..43a8d6ee1a9 100644 --- a/src/osd/scrubber/pg_scrubber.cc +++ b/src/osd/scrubber/pg_scrubber.cc @@ -841,8 +841,11 @@ int PgScrubber::get_whoami() const * - m_max_end * - end * - start + * returns: + * - std::nullopt if the range is blocked + * - otherwise, the number of objects in the selected range */ -bool PgScrubber::select_range() +std::optional PgScrubber::select_range() { m_be->new_chunk(); @@ -924,7 +927,7 @@ bool PgScrubber::select_range() // we'll be requeued by whatever made us unavailable for scrub dout(10) << __func__ << ": scrub blocked somewhere in range " << "[" << m_start << ", " << candidate_end << ")" << dendl; - return false; + return std::nullopt; } m_end = candidate_end; @@ -937,9 +940,9 @@ bool PgScrubber::select_range() // debug: be 'blocked' if told so by the 'pg scrub_debug block' asok command if (m_debug_blockrange > 0) { m_debug_blockrange--; - return false; + return std::nullopt; } - return true; + return objects.size(); } void PgScrubber::select_range_n_notify() @@ -950,7 +953,6 @@ void PgScrubber::select_range_n_notify() // the next chunk to handle is not blocked dout(20) << __func__ << ": selection OK" << dendl; m_osds->queue_scrub_chunk_free(m_pg, Scrub::scrub_prio_t::low_priority); - } else { // we will wait for the objects range to become available for scrubbing dout(10) << __func__ << ": selected chunk is busy" << dendl; @@ -959,6 +961,28 @@ void PgScrubber::select_range_n_notify() } } +uint64_t PgScrubber::get_scrub_cost(uint64_t num_chunk_objects) +{ + const auto& conf = m_pg->get_cct()->_conf; + if (op_queue_type_t::WeightedPriorityQueue == m_osds->osd->osd_op_queue_type()) { + // if the osd_op_queue is WPQ, we will use the default osd_scrub_cost value + return conf->osd_scrub_cost; + } + uint64_t cost = 0; + double scrub_metadata_cost = m_osds->get_cost_per_io(); + if (m_is_deep) { + auto pg_avg_object_size = m_pg->get_average_object_size(); + cost = conf->osd_scrub_event_cost + (num_chunk_objects + * (scrub_metadata_cost + pg_avg_object_size)); + dout(20) << fmt::format("{} : deep-scrub cost = {}", __func__, cost) << dendl; + return cost; + } else { + cost = conf->osd_scrub_event_cost + (num_chunk_objects * scrub_metadata_cost); + dout(20) << fmt::format("{} : shallow-scrub cost = {}", __func__, cost) << dendl; + return cost; + } +} + bool PgScrubber::write_blocked_by_scrub(const hobject_t& soid) { if (soid < m_start || soid >= m_end) { diff --git a/src/osd/scrubber/pg_scrubber.h b/src/osd/scrubber/pg_scrubber.h index bcab24cddfa..771524ab78d 100644 --- a/src/osd/scrubber/pg_scrubber.h +++ b/src/osd/scrubber/pg_scrubber.h @@ -729,6 +729,8 @@ class PgScrubber : public ScrubPgIF, /// Returns epoch of current osdmap epoch_t get_osdmap_epoch() const { return get_osdmap()->get_epoch(); } + uint64_t get_scrub_cost(uint64_t num_chunk_objects); + // collected statistics int m_shallow_errors{0}; int m_deep_errors{0}; @@ -793,8 +795,11 @@ class PgScrubber : public ScrubPgIF, * - handling some head/clones issues * * The selected range is set directly into 'm_start' and 'm_end' + * + * Returns std::nullopt if the range is busy otherwise returns the + * number of objects in the range. */ - bool select_range(); + std::optional select_range(); std::list m_callbacks; -- 2.39.5