From: Kefu Chai Date: Wed, 20 May 2026 02:22:24 +0000 (+0800) Subject: crimson/osd: wake pgs_creating waiters in PGMap::pg_loaded() X-Git-Tag: v21.0.1~134^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F69019%2Fhead;p=ceph.git crimson/osd: wake pgs_creating waiters in PGMap::pg_loaded() wait_for_pg() parks callers on pgs_creating[pgid] when the PG isn't in pgs yet. pg_created() wakes those waiters; pg_loaded() didn't. An op that races ahead of a PG load hangs indefinitely at CreateOrWaitPG. Add the symmetric wake-up in pg_loaded() with a conditional find -- unlike pg_created(), a loaded PG may have no waiters at all. See-also: e6c6de335b6a Signed-off-by: Kefu Chai --- diff --git a/src/crimson/osd/pg_map.cc b/src/crimson/osd/pg_map.cc index 6c6552f07cd..3fce70fe9cb 100644 --- a/src/crimson/osd/pg_map.cc +++ b/src/crimson/osd/pg_map.cc @@ -328,6 +328,16 @@ void PGMap::pg_loaded(spg_t pgid, Ref pg) { ceph_assert(!pgs.count(pgid)); pgs.emplace(pgid, pg); + // An op may have called wait_for_pg() before this PG finished loading + // from local store, parking on pgs_creating[pgid].promise. Wake any + // such waiters now -- pg_created() does the same on the create path, + // but the load path was missing the symmetric notification. + if (auto creating_iter = pgs_creating.find(pgid); + creating_iter != pgs_creating.end()) { + auto promise = std::move(creating_iter->second.promise); + pgs_creating.erase(creating_iter); + promise.set_value(pg); + } } void PGMap::pg_creation_canceled(spg_t pgid)