we should release the osdmap reference once we are done with it,
otherwise we might need to wait very long to update that reference with
a newer osdmap ref. this appears to be an OSDMap leak: it is held by an
quiet OSD::Session forever.
the osdmap is not reset in OSD::session_notify_pg_create(), because its
only caller is wake_pg_waiters(), which will call
dispatch_session_waiting() later. and dispatch_session_waiting() will
check the session->osdmap, and will also reset the osdmap if
session->waiting_for_pg.empty().
Fixes: http://tracker.ceph.com/issues/13990
Signed-off-by: Kefu Chai <kchai@redhat.com>
(cherry picked from commit
82b0af7cedc3071cd83ee53479f834c23c62b7d0)
} else {
register_session_waiting_on_map(session);
}
+ session->maybe_reset_osdmap();
}
assert(session->session_dispatch_lock.is_locked());
update_waiting_for_pg(session, osdmap);
session->waiting_for_pg.erase(pgid);
+ session->maybe_reset_osdmap();
clear_session_waiting_on_pg(session, pgid);
}
sent_epoch_lock("Session::sent_epoch_lock"), last_sent_epoch(0),
received_map_lock("Session::received_map_lock"), received_map_epoch(0)
{}
-
-
+ void maybe_reset_osdmap() {
+ if (waiting_for_pg.empty()) {
+ osdmap.reset();
+ }
+ }
};
void update_waiting_for_pg(Session *session, OSDMapRef osdmap);
void session_notify_pg_create(Session *session, OSDMapRef osdmap, spg_t pgid);
*/
session->waiting_on_map.clear();
session->waiting_for_pg.clear();
+ session->osdmap.reset();
}
void register_session_waiting_on_pg(Session *session, spg_t pgid) {
Mutex::Locker l(session_waiting_lock);