@@ -493,64 +493,64 @@ xfs_try_open_zone(
493493 return oz ;
494494}
495495
496+ enum xfs_zone_alloc_score {
497+ /* Any open zone will do it, we're desperate */
498+ XFS_ZONE_ALLOC_ANY = 0 ,
499+
500+ /* It better fit somehow */
501+ XFS_ZONE_ALLOC_OK = 1 ,
502+
503+ /* Only reuse a zone if it fits really well. */
504+ XFS_ZONE_ALLOC_GOOD = 2 ,
505+ };
506+
496507/*
497- * For data with short or medium lifetime, try to colocated it into an
498- * already open zone with a matching temperature .
508+ * Life time hint co-location matrix. Fields not set default to 0
509+ * aka XFS_ZONE_ALLOC_ANY .
499510 */
500- static bool
501- xfs_colocate_eagerly (
502- enum rw_hint file_hint )
503- {
504- switch (file_hint ) {
505- case WRITE_LIFE_MEDIUM :
506- case WRITE_LIFE_SHORT :
507- case WRITE_LIFE_NONE :
508- return true;
509- default :
510- return false;
511- }
512- }
513-
514- static bool
515- xfs_good_hint_match (
516- struct xfs_open_zone * oz ,
517- enum rw_hint file_hint )
518- {
519- switch (oz -> oz_write_hint ) {
520- case WRITE_LIFE_LONG :
521- case WRITE_LIFE_EXTREME :
522- /* colocate long and extreme */
523- if (file_hint == WRITE_LIFE_LONG ||
524- file_hint == WRITE_LIFE_EXTREME )
525- return true;
526- break ;
527- case WRITE_LIFE_MEDIUM :
528- /* colocate medium with medium */
529- if (file_hint == WRITE_LIFE_MEDIUM )
530- return true;
531- break ;
532- case WRITE_LIFE_SHORT :
533- case WRITE_LIFE_NONE :
534- case WRITE_LIFE_NOT_SET :
535- /* colocate short and none */
536- if (file_hint <= WRITE_LIFE_SHORT )
537- return true;
538- break ;
539- }
540- return false;
541- }
511+ static const unsigned int
512+ xfs_zoned_hint_score [WRITE_LIFE_HINT_NR ][WRITE_LIFE_HINT_NR ] = {
513+ [WRITE_LIFE_NOT_SET ] = {
514+ [WRITE_LIFE_NOT_SET ] = XFS_ZONE_ALLOC_OK ,
515+ [WRITE_LIFE_NONE ] = XFS_ZONE_ALLOC_OK ,
516+ [WRITE_LIFE_SHORT ] = XFS_ZONE_ALLOC_OK ,
517+ },
518+ [WRITE_LIFE_NONE ] = {
519+ [WRITE_LIFE_NOT_SET ] = XFS_ZONE_ALLOC_OK ,
520+ [WRITE_LIFE_NONE ] = XFS_ZONE_ALLOC_GOOD ,
521+ [WRITE_LIFE_SHORT ] = XFS_ZONE_ALLOC_GOOD ,
522+ },
523+ [WRITE_LIFE_SHORT ] = {
524+ [WRITE_LIFE_NOT_SET ] = XFS_ZONE_ALLOC_GOOD ,
525+ [WRITE_LIFE_NONE ] = XFS_ZONE_ALLOC_GOOD ,
526+ [WRITE_LIFE_SHORT ] = XFS_ZONE_ALLOC_GOOD ,
527+ },
528+ [WRITE_LIFE_MEDIUM ] = {
529+ [WRITE_LIFE_MEDIUM ] = XFS_ZONE_ALLOC_GOOD ,
530+ },
531+ [WRITE_LIFE_LONG ] = {
532+ [WRITE_LIFE_LONG ] = XFS_ZONE_ALLOC_OK ,
533+ [WRITE_LIFE_EXTREME ] = XFS_ZONE_ALLOC_OK ,
534+ },
535+ [WRITE_LIFE_EXTREME ] = {
536+ [WRITE_LIFE_LONG ] = XFS_ZONE_ALLOC_OK ,
537+ [WRITE_LIFE_EXTREME ] = XFS_ZONE_ALLOC_OK ,
538+ },
539+ };
542540
543541static bool
544542xfs_try_use_zone (
545543 struct xfs_zone_info * zi ,
546544 enum rw_hint file_hint ,
547545 struct xfs_open_zone * oz ,
548- bool lowspace )
546+ unsigned int goodness )
549547{
550548 if (oz -> oz_allocated == rtg_blocks (oz -> oz_rtg ))
551549 return false;
552- if (!lowspace && !xfs_good_hint_match (oz , file_hint ))
550+
551+ if (xfs_zoned_hint_score [oz -> oz_write_hint ][file_hint ] < goodness )
553552 return false;
553+
554554 if (!atomic_inc_not_zero (& oz -> oz_ref ))
555555 return false;
556556
@@ -581,14 +581,14 @@ static struct xfs_open_zone *
581581xfs_select_open_zone_lru (
582582 struct xfs_zone_info * zi ,
583583 enum rw_hint file_hint ,
584- bool lowspace )
584+ unsigned int goodness )
585585{
586586 struct xfs_open_zone * oz ;
587587
588588 lockdep_assert_held (& zi -> zi_open_zones_lock );
589589
590590 list_for_each_entry (oz , & zi -> zi_open_zones , oz_entry )
591- if (xfs_try_use_zone (zi , file_hint , oz , lowspace ))
591+ if (xfs_try_use_zone (zi , file_hint , oz , goodness ))
592592 return oz ;
593593
594594 cond_resched_lock (& zi -> zi_open_zones_lock );
@@ -651,9 +651,11 @@ xfs_select_zone_nowait(
651651 * data.
652652 */
653653 spin_lock (& zi -> zi_open_zones_lock );
654- if (xfs_colocate_eagerly (write_hint ))
655- oz = xfs_select_open_zone_lru (zi , write_hint , false);
656- else if (pack_tight )
654+ oz = xfs_select_open_zone_lru (zi , write_hint , XFS_ZONE_ALLOC_GOOD );
655+ if (oz )
656+ goto out_unlock ;
657+
658+ if (pack_tight )
657659 oz = xfs_select_open_zone_mru (zi , write_hint );
658660 if (oz )
659661 goto out_unlock ;
@@ -667,16 +669,16 @@ xfs_select_zone_nowait(
667669 goto out_unlock ;
668670
669671 /*
670- * Try to colocate cold data with other cold data if we failed to open a
671- * new zone for it.
672+ * Try to find an zone that is an ok match to colocate data with.
673+ */
674+ oz = xfs_select_open_zone_lru (zi , write_hint , XFS_ZONE_ALLOC_OK );
675+ if (oz )
676+ goto out_unlock ;
677+
678+ /*
679+ * Pick the least recently used zone, regardless of hint match
672680 */
673- if (write_hint != WRITE_LIFE_NOT_SET &&
674- !xfs_colocate_eagerly (write_hint ))
675- oz = xfs_select_open_zone_lru (zi , write_hint , false);
676- if (!oz )
677- oz = xfs_select_open_zone_lru (zi , WRITE_LIFE_NOT_SET , false);
678- if (!oz )
679- oz = xfs_select_open_zone_lru (zi , WRITE_LIFE_NOT_SET , true);
681+ oz = xfs_select_open_zone_lru (zi , write_hint , XFS_ZONE_ALLOC_ANY );
680682out_unlock :
681683 spin_unlock (& zi -> zi_open_zones_lock );
682684 return oz ;
0 commit comments