@@ -342,9 +342,13 @@ void JournalTrimmerImpl::config_t::validate() const
342342{
343343 ceph_assert (max_journal_bytes <= DEVICE_OFF_MAX);
344344 ceph_assert (max_journal_bytes > target_journal_dirty_bytes);
345+ ceph_assert (target_journal_dirty_bytes >= min_journal_dirty_bytes);
346+ ceph_assert (target_journal_dirty_bytes > rewrite_dirty_bytes_per_cycle);
345347 ceph_assert (max_journal_bytes > target_journal_alloc_bytes);
346- ceph_assert (rewrite_dirty_bytes_per_cycle > 0 );
347- ceph_assert (rewrite_backref_bytes_per_cycle > 0 );
348+ ceph_assert (rewrite_dirty_bytes_per_trans > 0 );
349+ ceph_assert (rewrite_dirty_bytes_per_cycle >=
350+ rewrite_dirty_bytes_per_trans);
351+ ceph_assert (max_backref_bytes_per_cycle > 0 );
348352}
349353
350354JournalTrimmerImpl::config_t
@@ -354,23 +358,28 @@ JournalTrimmerImpl::config_t::get_default(
354358 assert (roll_size);
355359 std::size_t target_dirty_bytes = 0 ;
356360 std::size_t target_alloc_bytes = 0 ;
361+ std::size_t min_dirty_bytes = 0 ;
357362 std::size_t max_journal_bytes = 0 ;
358363 if (type == backend_type_t ::SEGMENTED) {
359- target_dirty_bytes = 12 * roll_size;
364+ min_dirty_bytes = 12 * roll_size;
360365 target_alloc_bytes = 2 * roll_size;
366+ target_dirty_bytes = 14 * roll_size;
361367 max_journal_bytes = 16 * roll_size;
362368 } else {
363369 assert (type == backend_type_t ::RANDOM_BLOCK);
364- target_dirty_bytes = roll_size / 4 ;
370+ min_dirty_bytes = roll_size / 4 ;
365371 target_alloc_bytes = roll_size / 4 ;
372+ target_dirty_bytes = roll_size / 3 ;
366373 max_journal_bytes = roll_size / 2 ;
367374 }
368375 return config_t {
369376 target_dirty_bytes,
370377 target_alloc_bytes,
378+ min_dirty_bytes,
371379 max_journal_bytes,
372- 1 <<17 ,// rewrite_dirty_bytes_per_cycle
373- 1 <<24 // rewrite_backref_bytes_per_cycle
380+ 1 <<26 ,// rewrite_dirty_bytes_per_cycle, 64MB
381+ 1 <<17 ,// rewrite_dirty_bytes_per_trans, 128KB
382+ 1 <<24 // max_backref_bytes_per_cycle, 16MB
374383 };
375384}
376385
@@ -381,23 +390,30 @@ JournalTrimmerImpl::config_t::get_test(
381390 assert (roll_size);
382391 std::size_t target_dirty_bytes = 0 ;
383392 std::size_t target_alloc_bytes = 0 ;
393+ std::size_t min_dirty_bytes = 0 ;
384394 std::size_t max_journal_bytes = 0 ;
385395 if (type == backend_type_t ::SEGMENTED) {
386- target_dirty_bytes = 2 * roll_size;
396+ min_dirty_bytes = 2 * roll_size;
387397 target_alloc_bytes = 2 * roll_size;
398+ target_dirty_bytes = 3 * roll_size;
388399 max_journal_bytes = 4 * roll_size;
389400 } else {
390401 assert (type == backend_type_t ::RANDOM_BLOCK);
391- target_dirty_bytes = roll_size / 36 ;
402+ min_dirty_bytes = roll_size / 36 ;
392403 target_alloc_bytes = roll_size / 4 ;
404+ target_dirty_bytes = roll_size / 24 ;
393405 max_journal_bytes = roll_size / 2 ;
394406 }
395407 return config_t {
396408 target_dirty_bytes,
397409 target_alloc_bytes,
410+ min_dirty_bytes,
398411 max_journal_bytes,
399- 1 <<17 ,// rewrite_dirty_bytes_per_cycle
400- 1 <<24 // rewrite_backref_bytes_per_cycle
412+ (target_dirty_bytes > 1 <<26 )
413+ ? 1 <<25
414+ : target_dirty_bytes / 2 , // rewrite_dirty_bytes_per_cycle
415+ 1 <<17 ,// rewrite_dirty_bytes_per_trans, 128KB
416+ 1 <<24 // max_backref_bytes_per_cycle, 16MB
401417 };
402418}
403419
@@ -514,6 +530,31 @@ journal_seq_t JournalTrimmerImpl::get_tail_limit() const
514530 return ret;
515531}
516532
533+ journal_seq_t JournalTrimmerImpl::get_dirty_tail_min_target () const
534+ {
535+ assert (background_callback->is_ready ());
536+ auto ret = journal_head.add_offset (
537+ backend_type,
538+ -static_cast <device_off_t >(config.min_journal_dirty_bytes ),
539+ roll_start,
540+ roll_size);
541+ return ret;
542+ }
543+
544+ journal_seq_t JournalTrimmerImpl::get_dirty_tail_target_per_cycle () const
545+ {
546+ assert (background_callback->is_ready ());
547+ auto journal_dirty_bytes = get_journal_dirty_bytes ();
548+ assert (journal_dirty_bytes >= get_dirty_bytes_to_trim ());
549+ auto ret = journal_head.add_offset (
550+ backend_type,
551+ -static_cast <device_off_t >(
552+ journal_dirty_bytes - get_dirty_bytes_to_trim ()),
553+ roll_start,
554+ roll_size);
555+ return ret;
556+ }
557+
517558journal_seq_t JournalTrimmerImpl::get_dirty_tail_target () const
518559{
519560 assert (background_callback->is_ready ());
@@ -579,7 +620,7 @@ seastar::future<> JournalTrimmerImpl::trim() {
579620 }
580621 },
581622 [this ] {
582- if (should_trim_dirty ()) {
623+ if (should_start_trim_dirty ()) {
583624 return trim_dirty (
584625 ).handle_error (
585626 crimson::ct_error::assert_all{
@@ -618,7 +659,7 @@ JournalTrimmerImpl::trim_alloc()
618659 return backref_manager.merge_cached_backrefs (
619660 t,
620661 target,
621- config.rewrite_backref_bytes_per_cycle
662+ config.max_backref_bytes_per_cycle
622663 ).si_then ([this , FNAME, &t](auto trim_alloc_to)
623664 -> ExtentCallbackInterface::submit_transaction_direct_iertr::future<>
624665 {
@@ -646,46 +687,55 @@ JournalTrimmerImpl::trim_dirty()
646687
647688 auto & shard_stats = extent_callback->get_shard_stats ();
648689 ++(shard_stats.trim_dirty_num );
649- ++(shard_stats.pending_bg_num );
650690
651- return repeat_eagain ([this , FNAME, &shard_stats] {
652- ++(shard_stats.repeat_trim_dirty_num );
691+ auto target = get_dirty_tail_target_per_cycle ();
692+ return ::crimson::repeat ([this , FNAME, &shard_stats, target] {
693+ if (should_stop_trim_dirty (target)) {
694+ return trim_ertr::make_ready_future<
695+ seastar::stop_iteration>(seastar::stop_iteration::yes);
696+ }
697+ ++(shard_stats.pending_bg_num );
698+ return repeat_eagain ([this , FNAME, &shard_stats, target] {
699+ ++(shard_stats.repeat_trim_dirty_num );
653700
654- return extent_callback->with_transaction_intr (
655- Transaction::src_t ::TRIM_DIRTY,
656- " trim_dirty" ,
657- CACHE_HINT_NOCACHE,
658- [this , FNAME](auto &t)
659- {
660- auto target = get_dirty_tail_target ();
661- DEBUGT ( " start, dirty_tail={} , target={} " ,
662- t, journal_dirty_tail, target);
663- return extent_callback-> get_next_dirty_extents (
664- t ,
665- target,
666- config. rewrite_dirty_bytes_per_cycle
667- ). si_then ([ this , FNAME, &t]( auto dirty_list) {
668- DEBUGT ( " rewrite {} dirty extents " , t, dirty_list. size ());
669- return seastar::do_with (
670- std::move ( dirty_list),
671- [ this , &t]( auto &dirty_list)
672- {
673- return trans_intr::do_for_each (
674- dirty_list,
675- [ this , &t]( auto &e) {
676- return extent_callback-> rewrite_extent (
677- t, e, INIT_GENERATION, NULL_TIME );
678- });
679- });
680- }). si_then ([ this , &t] {
681- return extent_callback-> submit_transaction_direct (t );
701+ return extent_callback->with_transaction_intr (
702+ Transaction::src_t ::TRIM_DIRTY,
703+ " trim_dirty" ,
704+ CACHE_HINT_NOCACHE,
705+ [this , FNAME, target ](auto &t)
706+ {
707+ DEBUGT ( " start, dirty_tail={}, target={} " ,
708+ t, journal_dirty_tail , target);
709+ return extent_callback-> get_next_dirty_extents (
710+ t,
711+ target ,
712+ config. rewrite_dirty_bytes_per_trans
713+ ). si_then ([ this , FNAME, &t]( auto dirty_list) {
714+ DEBUGT ( " rewrite {} dirty extents " , t, dirty_list. size ());
715+ return seastar::do_with (
716+ std::move (dirty_list),
717+ [ this , &t]( auto & dirty_list)
718+ {
719+ return trans_intr::do_for_each (
720+ dirty_list,
721+ [ this , &t]( auto &e) {
722+ return extent_callback-> rewrite_extent (
723+ t, e, INIT_GENERATION, NULL_TIME);
724+ } );
725+ });
726+ }). si_then ([ this , &t] {
727+ return extent_callback-> submit_transaction_direct (t);
728+ } );
682729 });
730+ }).safe_then ([] {
731+ return seastar::stop_iteration::no;
732+ }).finally ([this , FNAME, &shard_stats] {
733+ DEBUG (" finish, dirty_tail={}" , journal_dirty_tail);
734+
735+ assert (shard_stats.pending_bg_num );
736+ --(shard_stats.pending_bg_num );
737+ return seastar::stop_iteration::no;
683738 });
684- }).finally ([this , FNAME, &shard_stats] {
685- DEBUG (" finish, dirty_tail={}" , journal_dirty_tail);
686-
687- assert (shard_stats.pending_bg_num );
688- --(shard_stats.pending_bg_num );
689739 });
690740}
691741
@@ -708,7 +758,7 @@ std::ostream &operator<<(
708758 os << " JournalTrimmer(" ;
709759 if (stats.trimmer .background_callback ->is_ready ()) {
710760 os << " should_block_io_on_trim=" << stats.trimmer .should_block_io_on_trim ()
711- << " , should_(trim_dirty=" << stats.trimmer .should_trim_dirty ()
761+ << " , should_(trim_dirty=" << stats.trimmer .should_start_trim_dirty ()
712762 << " , trim_alloc=" << stats.trimmer .should_trim_alloc () << " )" ;
713763 } else {
714764 os << " not-ready" ;
@@ -719,7 +769,8 @@ std::ostream &operator<<(
719769 << " , dirty_tail=" << stats.trimmer .get_dirty_tail ();
720770 if (stats.trimmer .background_callback ->is_ready ()) {
721771 os << " , alloc_tail_target=" << stats.trimmer .get_alloc_tail_target ()
722- << " , dirty_tail_target=" << stats.trimmer .get_dirty_tail_target ()
772+ << " , dirty_tail_min_target=" << stats.trimmer .get_dirty_tail_min_target ()
773+ << " , dirty_tail_target=" << stats.trimmer .get_dirty_tail_target ()
723774 << " , tail_limit=" << stats.trimmer .get_tail_limit ();
724775 }
725776 }
0 commit comments