snap_sleep_lock("OSDService::snap_sleep_lock"),
snap_sleep_timer(
osd->client_messenger->cct, snap_sleep_lock, false /* relax locking */),
+ scrub_sleep_lock("OSDService::scrub_sleep_lock"),
+ scrub_sleep_timer(
+ osd->client_messenger->cct, scrub_sleep_lock, false /* relax locking */),
snap_reserver(&reserver_finisher,
cct->_conf->osd_max_trimming_pgs),
map_cache_lock("OSDService::map_lock"),
snap_sleep_timer.shutdown();
}
+ {
+ Mutex::Locker l(scrub_sleep_lock);
+ scrub_sleep_timer.shutdown();
+ }
+
osdmap = OSDMapRef();
next_osdmap = OSDMapRef();
}
watch_timer.init();
agent_timer.init();
snap_sleep_timer.init();
+ scrub_sleep_timer.init();
agent_thread.create("osd_srv_agent");
}
return pg;
}
+PG *OSD::lookup_lock_pg(spg_t pgid)
+{
+ return _lookup_lock_pg(pgid);
+}
+
PG *OSD::_lookup_pg(spg_t pgid)
{
Mutex snap_sleep_lock;
SafeTimer snap_sleep_timer;
+
+ Mutex scrub_sleep_lock;
+ SafeTimer scrub_sleep_timer;
+
AsyncReserver<spg_t> snap_reserver;
void queue_for_scrub(PG *pg) {
bool _have_pg(spg_t pgid);
PG *_lookup_lock_pg_with_map_lock_held(spg_t pgid);
PG *_lookup_lock_pg(spg_t pgid);
+public:
+ PG *lookup_lock_pg(spg_t pgid);
+
+protected:
PG *_lookup_pg(spg_t pgid);
PG *_open_lock_pg(OSDMapRef createmap,
spg_t pg, bool no_lockdep_check=false);
acting_features(CEPH_FEATURES_SUPPORTED_DEFAULT),
upacting_features(CEPH_FEATURES_SUPPORTED_DEFAULT),
do_sort_bitwise(false),
- last_epoch(0),
- scrub_sleep_lock("PG::scrub_sleep_lock"),
- scrub_sleep_timer(o->cct, scrub_sleep_lock, false /* relax locking */)
+ last_epoch(0)
{
#ifdef PG_DEBUG_REFS
osd->add_pgid(p, this);
PG::~PG()
{
- Mutex::Locker l(scrub_sleep_lock);
- scrub_sleep_timer.shutdown();
#ifdef PG_DEBUG_REFS
osd->remove_pgid(info.pgid, this);
#endif
dirty_info = true;
dirty_big_info = true;
write_if_dirty(*t);
-
- scrub_sleep_timer.init();
}
#pragma GCC diagnostic ignored "-Wpragmas"
{
if (g_conf->osd_scrub_sleep > 0 &&
(scrubber.state == PG::Scrubber::NEW_CHUNK ||
- scrubber.state == PG::Scrubber::INACTIVE) && scrubber.needs_sleep) {
+ scrubber.state == PG::Scrubber::INACTIVE) &&
+ scrubber.needs_sleep) {
ceph_assert(!scrubber.sleeping);
dout(20) << __func__ << " state is INACTIVE|NEW_CHUNK, sleeping" << dendl;
+
// Do an async sleep so we don't block the op queue
- auto scrub_requeue_callback = new FunctionContext([this](int r) {
- lock();
- scrubber.sleeping = false;
- scrubber.needs_sleep = false;
- dout(20) << __func__ << " slept for "
- << ceph_clock_now() - scrubber.sleep_start
- << ", re-queuing scrub" << dendl;
- scrub_queued = false;
- requeue_scrub();
- scrubber.sleep_start = utime_t();
- unlock();
- });
- Mutex::Locker l(scrub_sleep_lock);
- scrub_sleep_timer.add_event_after(cct->_conf->osd_scrub_sleep, scrub_requeue_callback);
+ OSDService *osds = osd;
+ spg_t pgid = get_pgid();
+ int state = scrubber.state;
+ auto scrub_requeue_callback =
+ new FunctionContext([osds, pgid, state](int r) {
+ PG *pg = osds->osd->lookup_lock_pg(pgid);
+ if (pg == nullptr) {
+ lgeneric_dout(osds->osd->cct, 20)
+ << "scrub_requeue_callback: Could not find "
+ << "PG " << pgid << " can't complete scrub requeue after sleep"
+ << dendl;
+ return;
+ }
+ pg->scrubber.sleeping = false;
+ pg->scrubber.needs_sleep = false;
+ lgeneric_dout(pg->cct, 20)
+ << "scrub_requeue_callback: slept for "
+ << ceph_clock_now(pg->cct) - pg->scrubber.sleep_start
+ << ", re-queuing scrub with state " << state << dendl;
+ pg->scrub_queued = false;
+ pg->requeue_scrub();
+ pg->scrubber.sleep_start = utime_t();
+ pg->unlock();
+ });
+ Mutex::Locker l(osd->scrub_sleep_lock);
+ osd->scrub_sleep_timer.add_event_after(cct->_conf->osd_scrub_sleep,
+ scrub_requeue_callback);
scrubber.sleeping = true;
- scrubber.sleep_start = ceph_clock_now();
+ scrubber.sleep_start = ceph_clock_now(cct);
return;
}
if (pg_has_reset_since(queued)) {