Skip to content

Commit 0e92c2e

Browse files
sjp38torvalds
authored andcommitted
mm/damon/schemes: account scheme actions that successfully applied
Patch series "mm/damon/schemes: Extend stats for better online analysis and tuning". To help online access pattern analysis and tuning of DAMON-based Operation Schemes (DAMOS), DAMOS provides simple statistics for each scheme. Introduction of DAMOS time/space quota further made the tuning easier by making the risk management easier. However, that also made understanding of the working schemes a little bit more difficult. For an example, progress of a given scheme can now be throttled by not only the aggressiveness of the target access pattern, but also the time/space quotas. So, when a scheme is showing unexpectedly slow progress, it's difficult to know by what the progress of the scheme is throttled, with currently provided statistics. This patchset extends the statistics to contain some metrics that can be helpful for such online schemes analysis and tuning (patches 1-2), exports those to users (patches 3 and 5), and add documents (patches 4 and 6). This patch (of 6): DAMON-based operation schemes (DAMOS) stats provide only the number and the amount of regions that the action of the scheme has tried to be applied. Because the action could be failed for some reasons, the currently provided information is sometimes not useful or convenient enough for schemes profiling and tuning. To improve this situation, this commit extends the DAMOS stats to provide the number and the amount of regions that the action has successfully applied. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: SeongJae Park <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent f4c6d22 commit 0e92c2e

File tree

5 files changed

+53
-33
lines changed

5 files changed

+53
-33
lines changed

include/linux/damon.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,20 @@ struct damos_watermarks {
192192
bool activated;
193193
};
194194

195+
/**
196+
* struct damos_stat - Statistics on a given scheme.
197+
* @nr_tried: Total number of regions that the scheme is tried to be applied.
198+
* @sz_tried: Total size of regions that the scheme is tried to be applied.
199+
* @nr_applied: Total number of regions that the scheme is applied.
200+
* @sz_applied: Total size of regions that the scheme is applied.
201+
*/
202+
struct damos_stat {
203+
unsigned long nr_tried;
204+
unsigned long sz_tried;
205+
unsigned long nr_applied;
206+
unsigned long sz_applied;
207+
};
208+
195209
/**
196210
* struct damos - Represents a Data Access Monitoring-based Operation Scheme.
197211
* @min_sz_region: Minimum size of target regions.
@@ -203,8 +217,7 @@ struct damos_watermarks {
203217
* @action: &damo_action to be applied to the target regions.
204218
* @quota: Control the aggressiveness of this scheme.
205219
* @wmarks: Watermarks for automated (in)activation of this scheme.
206-
* @stat_count: Total number of regions that this scheme is applied.
207-
* @stat_sz: Total size of regions that this scheme is applied.
220+
* @stat: Statistics of this scheme.
208221
* @list: List head for siblings.
209222
*
210223
* For each aggregation interval, DAMON finds regions which fit in the
@@ -235,8 +248,7 @@ struct damos {
235248
enum damos_action action;
236249
struct damos_quota quota;
237250
struct damos_watermarks wmarks;
238-
unsigned long stat_count;
239-
unsigned long stat_sz;
251+
struct damos_stat stat;
240252
struct list_head list;
241253
};
242254

@@ -281,7 +293,8 @@ struct damon_ctx;
281293
* as an integer in [0, &DAMOS_MAX_SCORE].
282294
* @apply_scheme is called from @kdamond when a region for user provided
283295
* DAMON-based operation scheme is found. It should apply the scheme's action
284-
* to the region.
296+
* to the region and return bytes of the region that the action is successfully
297+
* applied.
285298
* @target_valid should check whether the target is still valid for the
286299
* monitoring.
287300
* @cleanup is called from @kdamond just before its termination.
@@ -295,8 +308,9 @@ struct damon_primitive {
295308
int (*get_scheme_score)(struct damon_ctx *context,
296309
struct damon_target *t, struct damon_region *r,
297310
struct damos *scheme);
298-
int (*apply_scheme)(struct damon_ctx *context, struct damon_target *t,
299-
struct damon_region *r, struct damos *scheme);
311+
unsigned long (*apply_scheme)(struct damon_ctx *context,
312+
struct damon_target *t, struct damon_region *r,
313+
struct damos *scheme);
300314
bool (*target_valid)(void *target);
301315
void (*cleanup)(struct damon_ctx *context);
302316
};

mm/damon/core.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ struct damos *damon_new_scheme(
102102
scheme->min_age_region = min_age_region;
103103
scheme->max_age_region = max_age_region;
104104
scheme->action = action;
105-
scheme->stat_count = 0;
106-
scheme->stat_sz = 0;
105+
scheme->stat = (struct damos_stat){};
107106
INIT_LIST_HEAD(&scheme->list);
108107

109108
scheme->quota.ms = quota->ms;
@@ -574,6 +573,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
574573
struct damos_quota *quota = &s->quota;
575574
unsigned long sz = r->ar.end - r->ar.start;
576575
struct timespec64 begin, end;
576+
unsigned long sz_applied = 0;
577577

578578
if (!s->wmarks.activated)
579579
continue;
@@ -627,7 +627,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
627627
damon_split_region_at(c, t, r, sz);
628628
}
629629
ktime_get_coarse_ts64(&begin);
630-
c->primitive.apply_scheme(c, t, r, s);
630+
sz_applied = c->primitive.apply_scheme(c, t, r, s);
631631
ktime_get_coarse_ts64(&end);
632632
quota->total_charged_ns += timespec64_to_ns(&end) -
633633
timespec64_to_ns(&begin);
@@ -641,8 +641,11 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
641641
r->age = 0;
642642

643643
update_stat:
644-
s->stat_count++;
645-
s->stat_sz += sz;
644+
s->stat.nr_tried++;
645+
s->stat.sz_tried += sz;
646+
if (sz_applied)
647+
s->stat.nr_applied++;
648+
s->stat.sz_applied += sz_applied;
646649
}
647650
}
648651

mm/damon/dbgfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static ssize_t sprint_schemes(struct damon_ctx *c, char *buf, ssize_t len)
117117
s->quota.weight_age,
118118
s->wmarks.metric, s->wmarks.interval,
119119
s->wmarks.high, s->wmarks.mid, s->wmarks.low,
120-
s->stat_count, s->stat_sz);
120+
s->stat.nr_tried, s->stat.sz_tried);
121121
if (!rc)
122122
return -ENOMEM;
123123

mm/damon/paddr.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,15 @@ bool damon_pa_target_valid(void *t)
213213
return true;
214214
}
215215

216-
static int damon_pa_apply_scheme(struct damon_ctx *ctx, struct damon_target *t,
217-
struct damon_region *r, struct damos *scheme)
216+
static unsigned long damon_pa_apply_scheme(struct damon_ctx *ctx,
217+
struct damon_target *t, struct damon_region *r,
218+
struct damos *scheme)
218219
{
219-
unsigned long addr;
220+
unsigned long addr, applied;
220221
LIST_HEAD(page_list);
221222

222223
if (scheme->action != DAMOS_PAGEOUT)
223-
return -EINVAL;
224+
return 0;
224225

225226
for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
226227
struct page *page = damon_get_page(PHYS_PFN(addr));
@@ -241,9 +242,9 @@ static int damon_pa_apply_scheme(struct damon_ctx *ctx, struct damon_target *t,
241242
put_page(page);
242243
}
243244
}
244-
reclaim_pages(&page_list);
245+
applied = reclaim_pages(&page_list);
245246
cond_resched();
246-
return 0;
247+
return applied * PAGE_SIZE;
247248
}
248249

249250
static int damon_pa_scheme_score(struct damon_ctx *context,

mm/damon/vaddr.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -572,32 +572,34 @@ bool damon_va_target_valid(void *target)
572572
}
573573

574574
#ifndef CONFIG_ADVISE_SYSCALLS
575-
static int damos_madvise(struct damon_target *target, struct damon_region *r,
576-
int behavior)
575+
static unsigned long damos_madvise(struct damon_target *target,
576+
struct damon_region *r, int behavior)
577577
{
578-
return -EINVAL;
578+
return 0;
579579
}
580580
#else
581-
static int damos_madvise(struct damon_target *target, struct damon_region *r,
582-
int behavior)
581+
static unsigned long damos_madvise(struct damon_target *target,
582+
struct damon_region *r, int behavior)
583583
{
584584
struct mm_struct *mm;
585-
int ret = -ENOMEM;
585+
unsigned long start = PAGE_ALIGN(r->ar.start);
586+
unsigned long len = PAGE_ALIGN(r->ar.end - r->ar.start);
587+
unsigned long applied;
586588

587589
mm = damon_get_mm(target);
588590
if (!mm)
589-
goto out;
591+
return 0;
590592

591-
ret = do_madvise(mm, PAGE_ALIGN(r->ar.start),
592-
PAGE_ALIGN(r->ar.end - r->ar.start), behavior);
593+
applied = do_madvise(mm, start, len, behavior) ? 0 : len;
593594
mmput(mm);
594-
out:
595-
return ret;
595+
596+
return applied;
596597
}
597598
#endif /* CONFIG_ADVISE_SYSCALLS */
598599

599-
static int damon_va_apply_scheme(struct damon_ctx *ctx, struct damon_target *t,
600-
struct damon_region *r, struct damos *scheme)
600+
static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx,
601+
struct damon_target *t, struct damon_region *r,
602+
struct damos *scheme)
601603
{
602604
int madv_action;
603605

@@ -620,7 +622,7 @@ static int damon_va_apply_scheme(struct damon_ctx *ctx, struct damon_target *t,
620622
case DAMOS_STAT:
621623
return 0;
622624
default:
623-
return -EINVAL;
625+
return 0;
624626
}
625627

626628
return damos_madvise(t, r, madv_action);

0 commit comments

Comments
 (0)