@@ -111,6 +111,8 @@ struct damos *damon_new_scheme(
111111 scheme -> quota .reset_interval = quota -> reset_interval ;
112112 scheme -> quota .charged_sz = 0 ;
113113 scheme -> quota .charged_from = 0 ;
114+ scheme -> quota .charge_target_from = NULL ;
115+ scheme -> quota .charge_addr_from = 0 ;
114116
115117 return scheme ;
116118}
@@ -553,6 +555,37 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
553555 if (quota -> sz && quota -> charged_sz >= quota -> sz )
554556 continue ;
555557
558+ /* Skip previously charged regions */
559+ if (quota -> charge_target_from ) {
560+ if (t != quota -> charge_target_from )
561+ continue ;
562+ if (r == damon_last_region (t )) {
563+ quota -> charge_target_from = NULL ;
564+ quota -> charge_addr_from = 0 ;
565+ continue ;
566+ }
567+ if (quota -> charge_addr_from &&
568+ r -> ar .end <= quota -> charge_addr_from )
569+ continue ;
570+
571+ if (quota -> charge_addr_from && r -> ar .start <
572+ quota -> charge_addr_from ) {
573+ sz = ALIGN_DOWN (quota -> charge_addr_from -
574+ r -> ar .start , DAMON_MIN_REGION );
575+ if (!sz ) {
576+ if (r -> ar .end - r -> ar .start <=
577+ DAMON_MIN_REGION )
578+ continue ;
579+ sz = DAMON_MIN_REGION ;
580+ }
581+ damon_split_region_at (c , t , r , sz );
582+ r = damon_next_region (r );
583+ sz = r -> ar .end - r -> ar .start ;
584+ }
585+ quota -> charge_target_from = NULL ;
586+ quota -> charge_addr_from = 0 ;
587+ }
588+
556589 /* Check the target regions condition */
557590 if (sz < s -> min_sz_region || s -> max_sz_region < sz )
558591 continue ;
@@ -573,6 +606,10 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
573606 }
574607 c -> primitive .apply_scheme (c , t , r , s );
575608 quota -> charged_sz += sz ;
609+ if (quota -> sz && quota -> charged_sz >= quota -> sz ) {
610+ quota -> charge_target_from = t ;
611+ quota -> charge_addr_from = r -> ar .end + 1 ;
612+ }
576613 }
577614 if (s -> action != DAMOS_STAT )
578615 r -> age = 0 ;
0 commit comments