]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/osd/pg_map: add PGShardMapping
authorSamuel Just <sjust@redhat.com>
Tue, 26 Jul 2022 02:05:28 +0000 (19:05 -0700)
committerSamuel Just <sjust@redhat.com>
Tue, 27 Sep 2022 02:31:13 +0000 (19:31 -0700)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/osd/pg_map.h

index c4bd5878a0a90b9f8d52d75558fb862f56d12edb..68f85e5f556b6152877cdba04062ffd070253026 100644 (file)
@@ -4,18 +4,85 @@
 #pragma once
 
 #include <map>
+#include <algorithm>
 
 #include <seastar/core/future.hh>
 #include <seastar/core/shared_future.hh>
 
 #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_id_t, unsigned> core_to_num_pgs;
+  std::map<spg_t, core_id_t> 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<PGCreationState> {
     static constexpr const char * type_name = "PGCreation";