@@ -67,6 +67,8 @@ PGRecovery::start_recovery_ops(
6767 if (max_to_start > 0 ) {
6868 max_to_start -= start_replica_recovery_ops (trigger, max_to_start, &started);
6969 }
70+ using interruptor =
71+ crimson::interruptible::interruptor<crimson::osd::IOInterruptCondition>;
7072 return interruptor::parallel_for_each (started,
7173 [] (auto && ifut) {
7274 return std::move (ifut);
@@ -108,7 +110,7 @@ PGRecovery::start_recovery_ops(
108110 }
109111 pg->reset_pglog_based_recovery_op ();
110112 }
111- return seastar::make_ready_future<bool >(! done);
113+ return seastar::make_ready_future<bool >(done);
112114 });
113115}
114116
@@ -194,10 +196,10 @@ size_t PGRecovery::start_primary_recovery_ops(
194196 auto it = missing.get_items ().find (head);
195197 assert (it != missing.get_items ().end ());
196198 auto head_need = it->second .need ;
197- out->emplace_back (recover_missing (trigger, head, head_need));
199+ out->emplace_back (recover_missing (trigger, head, head_need, true ));
198200 ++skipped;
199201 } else {
200- out->emplace_back (recover_missing (trigger, soid, item.need ));
202+ out->emplace_back (recover_missing (trigger, soid, item.need , true ));
201203 }
202204 ++started;
203205 }
@@ -304,7 +306,9 @@ size_t PGRecovery::start_replica_recovery_ops(
304306PGRecovery::interruptible_future<>
305307PGRecovery::recover_missing (
306308 RecoveryBackend::RecoveryBlockingEvent::TriggerI& trigger,
307- const hobject_t &soid, eversion_t need)
309+ const hobject_t &soid,
310+ eversion_t need,
311+ bool with_throttle)
308312{
309313 logger ().info (" {} {} v {}" , __func__, soid, need);
310314 auto [recovering, added] = pg->get_recovery_backend ()->add_recovering (soid);
@@ -317,7 +321,9 @@ PGRecovery::recover_missing(
317321 } else {
318322 return recovering.wait_track_blocking (
319323 trigger,
320- pg->get_recovery_backend ()->recover_object (soid, need)
324+ with_throttle
325+ ? recover_object_with_throttle (soid, need)
326+ : recover_object (soid, need)
321327 .handle_exception_interruptible (
322328 [=, this , soid = std::move (soid)] (auto e) {
323329 on_failed_recover ({ pg->get_pg_whoami () }, soid, need);
@@ -365,7 +371,7 @@ RecoveryBackend::interruptible_future<> PGRecovery::prep_object_replica_pushes(
365371 logger ().info (" {} {} v {}, new recovery" , __func__, soid, need);
366372 return recovering.wait_track_blocking (
367373 trigger,
368- pg-> get_recovery_backend ()-> recover_object (soid, need)
374+ recover_object_with_throttle (soid, need)
369375 .handle_exception_interruptible (
370376 [=, this , soid = std::move (soid)] (auto e) {
371377 on_failed_recover ({ pg->get_pg_whoami () }, soid, need);
@@ -514,6 +520,25 @@ void PGRecovery::request_primary_scan(
514520 });
515521}
516522
523+ PGRecovery::interruptible_future<>
524+ PGRecovery::recover_object_with_throttle (
525+ const hobject_t &soid,
526+ eversion_t need)
527+ {
528+ crimson::osd::scheduler::params_t params =
529+ {1 , 0 , crimson::osd::scheduler::scheduler_class_t ::background_best_effort};
530+ auto &ss = pg->get_shard_services ();
531+ logger ().debug (" {} {}" , soid, need);
532+ return ss.with_throttle (
533+ std::move (params),
534+ [this , soid, need] {
535+ logger ().debug (" got throttle: {} {}" , soid, need);
536+ auto backend = pg->get_recovery_backend ();
537+ assert (backend);
538+ return backend->recover_object (soid, need);
539+ });
540+ }
541+
517542void PGRecovery::enqueue_push (
518543 const hobject_t & obj,
519544 const eversion_t & v,
@@ -525,7 +550,7 @@ void PGRecovery::enqueue_push(
525550 if (!added)
526551 return ;
527552 peering_state.prepare_backfill_for_missing (obj, v, peers);
528- std::ignore = pg-> get_recovery_backend ()-> recover_object (obj, v).\
553+ std::ignore = recover_object_with_throttle (obj, v).\
529554 handle_exception_interruptible ([] (auto ) {
530555 ceph_abort_msg (" got exception on backfill's push" );
531556 return seastar::make_ready_future<>();
@@ -603,21 +628,8 @@ void PGRecovery::update_peers_last_backfill(
603628
604629bool PGRecovery::budget_available () const
605630{
606- crimson::osd::scheduler::params_t params =
607- {1 , 0 , crimson::osd::scheduler::scheduler_class_t ::background_best_effort};
608631 auto &ss = pg->get_shard_services ();
609- auto futopt = ss.try_acquire_throttle_now (std::move (params));
610- if (!futopt) {
611- return true ;
612- }
613- std::ignore = interruptor::make_interruptible (std::move (*futopt)
614- ).then_interruptible ([this ] {
615- assert (!backfill_state->is_triggered ());
616- using BackfillState = crimson::osd::BackfillState;
617- backfill_state->process_event (
618- BackfillState::ThrottleAcquired{}.intrusive_from_this ());
619- });
620- return false ;
632+ return ss.throttle_available ();
621633}
622634
623635void PGRecovery::on_pg_clean ()
0 commit comments