]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test/osd: add perf test for calc_pg_upmaps with mutual overfull upmap pairs 53891/head
authorKefu Chai <k.chai@proxmox.com>
Wed, 6 May 2026 03:32:03 +0000 (11:32 +0800)
committerKefu Chai <k.chai@proxmox.com>
Wed, 6 May 2026 04:33:58 +0000 (12:33 +0800)
Reproduces the scenario from https://tracker.ceph.com/issues/63137: 500
cohort OSDs all at deviation +2, linked by pg_upmap_items rings with R=5
pairs each.  Before the fix, every incoming pair triggered a test_change
call that got rejected -- calc_pg_upmaps took ~11 minutes.  After, it
exits in ~200ms.

Signed-off-by: Kefu Chai <k.chai@proxmox.com>
src/test/osd/TestOSDMap.cc

index db9a3c2100242b6e0aa1e475b5743bc5063bd6f5..a804bc99322eea3648f2fb8bbf95874cdd0e54fc 100644 (file)
@@ -1925,6 +1925,84 @@ TEST_F(OSDMapTest, TryDropRemapOverfullBothOverfull) {
   }
 }
 
+TEST_F(OSDMapTest, BUG_63137_calc_pg_upmaps_perf) {
+  // https://tracker.ceph.com/issues/63137
+  //
+  // try_drop_remap_overfull used to call test_change (full stddev recompute
+  // over all OSDs) for every incoming pg_upmap_items pair that cannot improve
+  // distribution.  With R incoming pairs per cohort OSD, that is O(n_cohort*R)
+  // wasted test_change calls.
+  //
+  // Setup (size=1, n_osds=600, pg_num=6000, target=10 per OSD):
+  //   cohort OSDs 0..499: 12 PGs each (deviation +2)
+  //   sink   OSDs 500..599: 0 PGs each (deviation -10)
+  //
+  //   pg_upmap:       pg(i*12+j) -> osd.i   for i in 0..499, j in 0..11
+  //   pg_upmap_items: pg(i*12+k) [osd.i -> osd.(i+k)%500]   k in 1..R
+  //
+  // After all upmaps each cohort OSD has (12-R) natural + R incoming = 12 PGs.
+  // When processing overfull osd.i, there are R incoming ring pairs with
+  // um_from also at deviation +2. Old code tried dropping each and paid
+  // test_change; new code skips them with the um_from overload check.
+  const int n_cohort = 500;
+  const int n_sink = 100;
+  const int n_osds = n_cohort + n_sink;
+  const int pgs_per_cohort = 12;
+  const int total_pgs = n_cohort * pgs_per_cohort;
+  const int R = 5;
+
+  set_up_map(n_osds, true);
+
+  int pool_id;
+  {
+    OSDMap::Incremental pending_inc(osdmap.get_epoch() + 1);
+    pending_inc.new_pool_max = osdmap.get_pool_max();
+    pool_id = ++pending_inc.new_pool_max;
+    pg_pool_t empty;
+    auto p = pending_inc.get_new_pool(pool_id, &empty);
+    p->size = 1;
+    p->min_size = 1;
+    p->set_pg_num(total_pgs);
+    p->set_pgp_num(total_pgs);
+    p->type = pg_pool_t::TYPE_REPLICATED;
+    p->crush_rule = 0;
+    p->set_flag(pg_pool_t::FLAG_HASHPSPOOL);
+    pending_inc.new_pool_names[pool_id] = "perf_pool";
+    osdmap.apply_incremental(pending_inc);
+    ASSERT_TRUE(osdmap.have_pg_pool(pool_id));
+  }
+
+  // pg_upmap: assign all PGs for cohort OSD i to osd.i
+  // pg_upmap_items ring: pg(i*12+k) [osd.i -> osd.(i+k)%n_cohort]
+  {
+    OSDMap::Incremental inc(osdmap.get_epoch() + 1);
+    for (int i = 0; i < n_cohort; ++i) {
+      for (int j = 0; j < pgs_per_cohort; ++j) {
+        pg_t pg = osdmap.raw_pg_to_pg(pg_t(i * pgs_per_cohort + j, pool_id));
+        inc.new_pg_upmap[pg] = mempool::osdmap::vector<int32_t>{i};
+      }
+      for (int k = 1; k <= R; ++k) {
+        pg_t pg = osdmap.raw_pg_to_pg(pg_t(i * pgs_per_cohort + k, pool_id));
+        int um_to = (i + k) % n_cohort;
+        inc.new_pg_upmap_items[pg] =
+          mempool::osdmap::vector<pair<int32_t,int32_t>>{{i, um_to}};
+      }
+    }
+    osdmap.apply_incremental(inc);
+  }
+
+  {
+    set<int64_t> only_pools = {pool_id};
+    OSDMap::Incremental pending_inc(osdmap.get_epoch() + 1);
+    auto start = mono_clock::now();
+    osdmap.calc_pg_upmaps(g_ceph_context, 1, 10000, only_pools, &pending_inc);
+    auto latency = mono_clock::now() - start;
+    std::cout << "calc_pg_upmaps (63137 scenario, n_cohort=" << n_cohort
+              << " R=" << R << ") latency: " << timespan_str(latency)
+              << std::endl;
+  }
+}
+
 TEST_F(OSDMapTest, BUG_42052) {
   // https://tracker.ceph.com/issues/42052
   set_up_map(6, true);