mm/damon/sysfs: check DAMOS regions update progress from before_terminate()
[platform/kernel/linux-rpi.git] / mm / damon / core.c
index eb95809..bcd2bd9 100644 (file)
@@ -878,6 +878,66 @@ static void damos_update_stat(struct damos *s,
        s->stat.sz_applied += sz_applied;
 }
 
+static bool __damos_filter_out(struct damon_ctx *ctx, struct damon_target *t,
+               struct damon_region *r, struct damos_filter *filter)
+{
+       bool matched = false;
+       struct damon_target *ti;
+       int target_idx = 0;
+       unsigned long start, end;
+
+       switch (filter->type) {
+       case DAMOS_FILTER_TYPE_TARGET:
+               damon_for_each_target(ti, ctx) {
+                       if (ti == t)
+                               break;
+                       target_idx++;
+               }
+               matched = target_idx == filter->target_idx;
+               break;
+       case DAMOS_FILTER_TYPE_ADDR:
+               start = ALIGN_DOWN(filter->addr_range.start, DAMON_MIN_REGION);
+               end = ALIGN_DOWN(filter->addr_range.end, DAMON_MIN_REGION);
+
+               /* inside the range */
+               if (start <= r->ar.start && r->ar.end <= end) {
+                       matched = true;
+                       break;
+               }
+               /* outside of the range */
+               if (r->ar.end <= start || end <= r->ar.start) {
+                       matched = false;
+                       break;
+               }
+               /* start before the range and overlap */
+               if (r->ar.start < start) {
+                       damon_split_region_at(t, r, start - r->ar.start);
+                       matched = false;
+                       break;
+               }
+               /* start inside the range */
+               damon_split_region_at(t, r, end - r->ar.start);
+               matched = true;
+               break;
+       default:
+               break;
+       }
+
+       return matched == filter->matching;
+}
+
+static bool damos_filter_out(struct damon_ctx *ctx, struct damon_target *t,
+               struct damon_region *r, struct damos *s)
+{
+       struct damos_filter *filter;
+
+       damos_for_each_filter(filter, s) {
+               if (__damos_filter_out(ctx, t, r, filter))
+                       return true;
+       }
+       return false;
+}
+
 static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t,
                struct damon_region *r, struct damos *s)
 {
@@ -895,6 +955,8 @@ static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t,
                                goto update_stat;
                        damon_split_region_at(t, r, sz);
                }
+               if (damos_filter_out(c, t, r, s))
+                       return;
                ktime_get_coarse_ts64(&begin);
                if (c->callback.before_damos_apply)
                        err = c->callback.before_damos_apply(c, t, r, s);