From: Samuel Just Date: Tue, 1 Jul 2014 18:04:51 +0000 (-0700) Subject: OSD: wake_pg_waiters after dropping pg lock X-Git-Tag: v0.84~155^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F2063%2Fhead;p=ceph.git OSD: wake_pg_waiters after dropping pg lock Otherwise, we dispatch_session_waiting while still holding the pg lock, which is obviously wrong. Unfortunately, this places an additional burden on any user of _create_lock_pg, but I think it's unavoidable since that method must atomically add the pg to the map and lock it. Fixes: #8961 Introduced in: 25466839589813047c975e44e67e14f34e32139e ecda2fef8ce982df3581a3b47ba74ae581d82479 Signed-off-by: Samuel Just --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index d3b496f69a6c9..53e88a02abeb2 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -1883,7 +1883,6 @@ PG *OSD::_open_lock_pg( pg->get("PGMap"); // because it's in pg_map service.pg_add_epoch(pg->info.pgid, createmap->get_epoch()); } - wake_pg_waiters(pg, pgid); return pg; } @@ -2169,6 +2168,7 @@ void OSD::load_pgs() epoch_t map_epoch = PG::peek_map_epoch(store, coll_t(pgid), service.infos_oid, &bl); PG *pg = _open_lock_pg(map_epoch == 0 ? osdmap : service.get_map(map_epoch), pgid); + // there can be no waiters here, so we don't call wake_pg_waiters // read pg state, log pg->read_state(store, bl); @@ -2469,6 +2469,7 @@ void OSD::handle_pg_peering_evt( pg->queue_peering_event(evt); pg->unlock(); + wake_pg_waiters(pg, pgid); return; } case RES_SELF: { @@ -2504,6 +2505,7 @@ void OSD::handle_pg_peering_evt( pg->queue_peering_event(evt); pg->unlock(); + wake_pg_waiters(pg, resurrected); return; } case RES_PARENT: { @@ -2545,6 +2547,7 @@ void OSD::handle_pg_peering_evt( //parent->queue_peering_event(evt); parent->queue_null(osdmap->get_epoch(), osdmap->get_epoch()); parent->unlock(); + wake_pg_waiters(parent, resurrected); return; } } @@ -6875,6 +6878,7 @@ void OSD::handle_pg_create(OpRequestRef op) pg->publish_stats_to_osd(); pg->unlock(); num_created++; + wake_pg_waiters(pg, pgid); } dispatch_context(rctx, pg, osdmap); } diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 428f903bb6196..a449c00cc6f40 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -1648,6 +1648,11 @@ protected: }; res_result _try_resurrect_pg( OSDMapRef curmap, spg_t pgid, spg_t *resurrected, PGRef *old_pg_state); + + /** + * After unlocking the pg, the user must ensure that wake_pg_waiters + * is called. + */ PG *_create_lock_pg( OSDMapRef createmap, spg_t pgid,