From: Sage Weil Date: Mon, 12 Mar 2018 14:16:12 +0000 (-0500) Subject: osd: periodically request newer map from mon if waiting peering events X-Git-Tag: v13.1.0~390^2~29 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0e6db5e320f78dc2b53a6ed6738b42b0f8432d70;p=ceph.git osd: periodically request newer map from mon if waiting peering events If we have peering events waiting on a newer map than we have, request it from the mon. Do this periodically in tick so that we normally wait to get it from a peer first. This avoids a deadlock situation where we are, say, waiting for a newer map to create a pg or but do not ever get the map to do it (because the cluster is idle). Signed-off-by: Sage Weil --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 1745f92a6af9..dd42641bf348 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -4779,6 +4779,17 @@ void OSD::tick_without_osd_lock() send_failures(); } map_lock.put_read(); + + epoch_t max_waiting_epoch = 0; + for (auto s : shards) { + max_waiting_epoch = std::max(max_waiting_epoch, + s->get_max_waiting_epoch()); + } + if (max_waiting_epoch > get_osdmap()->get_epoch()) { + dout(20) << __func__ << " max_waiting_epoch " << max_waiting_epoch + << ", requesting new map" << dendl; + osdmap_subscribe(superblock.newest_map + 1, false); + } } if (is_active()) { @@ -9319,6 +9330,18 @@ void OSDShard::wait_min_pg_epoch(epoch_t need) waiting_for_min_pg_epoch = false; } +epoch_t OSDShard::get_max_waiting_epoch() +{ + Mutex::Locker l(sdata_op_ordering_lock); + epoch_t r = 0; + for (auto& i : pg_slots) { + if (!i.second->waiting_peering.empty()) { + r = std::max(r, i.second->waiting_peering.rbegin()->first); + } + } + return r; +} + void OSDShard::consume_map( OSDMapRef& new_osdmap, unsigned *pushes_to_free) diff --git a/src/osd/OSD.h b/src/osd/OSD.h index e9a52fd01117..9fd4ddcf07c5 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -1171,6 +1171,9 @@ struct OSDShard { epoch_t get_min_pg_epoch(); void wait_min_pg_epoch(epoch_t need); + /// return newest epoch we are waiting for + epoch_t get_max_waiting_epoch(); + /// push osdmap into shard void consume_map( OSDMapRef& osdmap,