From: Samuel Just Date: Tue, 26 Jul 2022 02:05:28 +0000 (-0700) Subject: crimson/osd/pg_map: add PGShardMapping X-Git-Tag: v18.1.0~639^2~19^2~29 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=25a4612745e02c77afcd9f962cf4ed253a18919c;p=ceph-ci.git crimson/osd/pg_map: add PGShardMapping Signed-off-by: Samuel Just --- diff --git a/src/crimson/osd/pg_map.h b/src/crimson/osd/pg_map.h index c4bd5878a0a..68f85e5f556 100644 --- a/src/crimson/osd/pg_map.h +++ b/src/crimson/osd/pg_map.h @@ -4,18 +4,85 @@ #pragma once #include +#include #include #include #include "include/types.h" #include "crimson/common/type_helpers.h" +#include "crimson/common/smp_helpers.h" #include "crimson/osd/osd_operation.h" #include "osd/osd_types.h" namespace crimson::osd { class PG; +/** + * PGShardMapping + * + * Maps pgs to shards. + */ +class PGShardMapping { +public: + /// Returns mapping if present, NULL_CORE otherwise + core_id_t get_pg_mapping(spg_t pgid) { + auto iter = pg_to_core.find(pgid); + ceph_assert_always(iter == pg_to_core.end() || iter->second != NULL_CORE); + return iter == pg_to_core.end() ? NULL_CORE : iter->second; + } + + /// Returns mapping for pgid, creates new one if it doesn't already exist + core_id_t maybe_create_pg(spg_t pgid) { + auto [insert_iter, inserted] = pg_to_core.emplace(pgid, NULL_CORE); + if (!inserted) { + ceph_assert_always(insert_iter->second != NULL_CORE); + return insert_iter->second; + } else { + ceph_assert_always(core_to_num_pgs.size() > 0); + auto core_iter = std::min_element( + core_to_num_pgs.begin(), + core_to_num_pgs.end(), + [](const auto &left, const auto &right) { + return left.second < right.second; + }); + ceph_assert_always(core_to_num_pgs.end() != core_iter); + insert_iter->second = core_iter->first; + core_iter->second++; + return insert_iter->second; + } + } + + /// Remove pgid + void remove_pg(spg_t pgid) { + auto iter = pg_to_core.find(pgid); + ceph_assert_always(iter != pg_to_core.end()); + ceph_assert_always(iter->second != NULL_CORE); + auto count_iter = core_to_num_pgs.find(iter->second); + ceph_assert_always(count_iter != core_to_num_pgs.end()); + ceph_assert_always(count_iter->second > 0); + --(count_iter->second); + pg_to_core.erase(iter); + } + + /// Map to cores in [min_core_mapping, core_mapping_limit) + PGShardMapping(core_id_t min_core_mapping, core_id_t core_mapping_limit) { + ceph_assert_always(min_core_mapping < core_mapping_limit); + for (auto i = min_core_mapping; i != core_mapping_limit; ++i) { + core_to_num_pgs.emplace(i, 0); + } + } +private: + std::map core_to_num_pgs; + std::map pg_to_core; +}; + +/** + * PGMap + * + * Maps spg_t to PG instance within a shard. Handles dealing with waiting + * on pg creation. + */ class PGMap { struct PGCreationState : BlockerT { static constexpr const char * type_name = "PGCreation";