java-topology/defects/ceph/patch/ceph-0001-osdmap-underfull-set.patch

60 lines
2.6 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000026
diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc
--- a/src/osd/OSDMap.cc
+++ b/src/osd/OSDMap.cc
@@ -5818,6 +5818,8 @@ int OSDMap::calc_pg_upmaps(
while (max--) {
ldout(cct, 30) << "Top of loop #" << max+1 << dendl;
// build overfull and underfull
set<int> overfull;
set<int> more_overfull;
bool using_more_overfull = false;
vector<int> underfull;
vector<int> more_underfull;
fill_overfull_underfull(cct, deviation_osd, max_deviation,
overfull, more_overfull,
underfull, more_underfull);
+ // Pre-build O(1) lookup sets — underfull/more_underfull are read-only in
+ // the scan loops below, so unordered_set avoids O(N×U) std::find calls.
+ std::unordered_set<int> underfull_set(underfull.begin(), underfull.end());
+ std::unordered_set<int> more_underfull_set(more_underfull.begin(), more_underfull.end());
@@ -5979,8 +5981,7 @@ int OSDMap::calc_pg_upmaps(
for (auto& [deviation, osd] : deviation_osd) {
- if (std::find(underfull.begin(), underfull.end(), osd) ==
- underfull.end())
+ if (underfull_set.find(osd) == underfull_set.end())
break;
float target = osd_weight[osd] * pgs_per_weight;
diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc
--- a/src/crush/CrushWrapper.cc
+++ b/src/crush/CrushWrapper.cc
@@ -4118,6 +4118,8 @@ int CrushWrapper::try_remap_rule(
for (int pos = 0; pos < fanout; ++pos) {
if (type > 0) {
// non-leaf: no change
} else {
// leaf
bool replaced = false;
if (overfull.count(*i)) {
+ // Build orig_set once per leaf slot — O(1) membership below
+ std::unordered_set<int> orig_set(orig.begin(), orig.end());
for (auto item : underfull) {
if (used.count(item)) continue;
if (!subtree_contains(from, item)) continue;
- if (std::find(orig.begin(), orig.end(), item) != orig.end()) {
+ if (orig_set.count(item)) {
ldout(cct, 20) << __func__ << " in orig " << orig << dendl;
continue;
}
@@ -4152,8 +4154,6 @@ int CrushWrapper::try_remap_rule(
if (!replaced) {
for (auto item : more_underfull) {
if (used.count(item)) continue;
if (!subtree_contains(from, item)) continue;
- if (std::find(orig.begin(), orig.end(), item) != orig.end()) {
+ if (orig_set.count(item)) {
ldout(cct, 20) << __func__ << " in orig " << orig << dendl;
continue;
}