UPSTREAM: 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/20211210150016.35349-1-sj@kernel.org Link: https://lkml.kernel.org/r/20211210150016.35349-2-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> (cherry picked from commit 0e92c2ee9f459542c5384d9cfab24873c3dd6398) Bug: 228223814 Signed-off-by: Hailong Tu <tuhailong@oppo.com> Change-Id: Iddfe9257cb99091404202576a1addc5cc340cb8b
This commit is contained in:
parent
943c0cd13f
commit
7cecfab158
@ -189,6 +189,20 @@ struct damos_watermarks {
|
|||||||
bool activated;
|
bool activated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct damos_stat - Statistics on a given scheme.
|
||||||
|
* @nr_tried: Total number of regions that the scheme is tried to be applied.
|
||||||
|
* @sz_tried: Total size of regions that the scheme is tried to be applied.
|
||||||
|
* @nr_applied: Total number of regions that the scheme is applied.
|
||||||
|
* @sz_applied: Total size of regions that the scheme is applied.
|
||||||
|
*/
|
||||||
|
struct damos_stat {
|
||||||
|
unsigned long nr_tried;
|
||||||
|
unsigned long sz_tried;
|
||||||
|
unsigned long nr_applied;
|
||||||
|
unsigned long sz_applied;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct damos - Represents a Data Access Monitoring-based Operation Scheme.
|
* struct damos - Represents a Data Access Monitoring-based Operation Scheme.
|
||||||
* @min_sz_region: Minimum size of target regions.
|
* @min_sz_region: Minimum size of target regions.
|
||||||
@ -200,8 +214,7 @@ struct damos_watermarks {
|
|||||||
* @action: &damo_action to be applied to the target regions.
|
* @action: &damo_action to be applied to the target regions.
|
||||||
* @quota: Control the aggressiveness of this scheme.
|
* @quota: Control the aggressiveness of this scheme.
|
||||||
* @wmarks: Watermarks for automated (in)activation of this scheme.
|
* @wmarks: Watermarks for automated (in)activation of this scheme.
|
||||||
* @stat_count: Total number of regions that this scheme is applied.
|
* @stat: Statistics of this scheme.
|
||||||
* @stat_sz: Total size of regions that this scheme is applied.
|
|
||||||
* @list: List head for siblings.
|
* @list: List head for siblings.
|
||||||
*
|
*
|
||||||
* For each aggregation interval, DAMON finds regions which fit in the
|
* For each aggregation interval, DAMON finds regions which fit in the
|
||||||
@ -232,8 +245,7 @@ struct damos {
|
|||||||
enum damos_action action;
|
enum damos_action action;
|
||||||
struct damos_quota quota;
|
struct damos_quota quota;
|
||||||
struct damos_watermarks wmarks;
|
struct damos_watermarks wmarks;
|
||||||
unsigned long stat_count;
|
struct damos_stat stat;
|
||||||
unsigned long stat_sz;
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -278,7 +290,8 @@ struct damon_ctx;
|
|||||||
* as an integer in [0, &DAMOS_MAX_SCORE].
|
* as an integer in [0, &DAMOS_MAX_SCORE].
|
||||||
* @apply_scheme is called from @kdamond when a region for user provided
|
* @apply_scheme is called from @kdamond when a region for user provided
|
||||||
* DAMON-based operation scheme is found. It should apply the scheme's action
|
* DAMON-based operation scheme is found. It should apply the scheme's action
|
||||||
* to the region. This is not used for &DAMON_ARBITRARY_TARGET case.
|
* to the region and return bytes of the region that the action is successfully
|
||||||
|
* applied.
|
||||||
* @target_valid should check whether the target is still valid for the
|
* @target_valid should check whether the target is still valid for the
|
||||||
* monitoring.
|
* monitoring.
|
||||||
* @cleanup is called from @kdamond just before its termination.
|
* @cleanup is called from @kdamond just before its termination.
|
||||||
@ -292,8 +305,9 @@ struct damon_primitive {
|
|||||||
int (*get_scheme_score)(struct damon_ctx *context,
|
int (*get_scheme_score)(struct damon_ctx *context,
|
||||||
struct damon_target *t, struct damon_region *r,
|
struct damon_target *t, struct damon_region *r,
|
||||||
struct damos *scheme);
|
struct damos *scheme);
|
||||||
int (*apply_scheme)(struct damon_ctx *context, struct damon_target *t,
|
unsigned long (*apply_scheme)(struct damon_ctx *context,
|
||||||
struct damon_region *r, struct damos *scheme);
|
struct damon_target *t, struct damon_region *r,
|
||||||
|
struct damos *scheme);
|
||||||
bool (*target_valid)(void *target);
|
bool (*target_valid)(void *target);
|
||||||
void (*cleanup)(struct damon_ctx *context);
|
void (*cleanup)(struct damon_ctx *context);
|
||||||
};
|
};
|
||||||
|
@ -102,8 +102,7 @@ struct damos *damon_new_scheme(
|
|||||||
scheme->min_age_region = min_age_region;
|
scheme->min_age_region = min_age_region;
|
||||||
scheme->max_age_region = max_age_region;
|
scheme->max_age_region = max_age_region;
|
||||||
scheme->action = action;
|
scheme->action = action;
|
||||||
scheme->stat_count = 0;
|
scheme->stat = (struct damos_stat){};
|
||||||
scheme->stat_sz = 0;
|
|
||||||
INIT_LIST_HEAD(&scheme->list);
|
INIT_LIST_HEAD(&scheme->list);
|
||||||
|
|
||||||
scheme->quota.ms = quota->ms;
|
scheme->quota.ms = quota->ms;
|
||||||
@ -574,6 +573,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
|
|||||||
struct damos_quota *quota = &s->quota;
|
struct damos_quota *quota = &s->quota;
|
||||||
unsigned long sz = r->ar.end - r->ar.start;
|
unsigned long sz = r->ar.end - r->ar.start;
|
||||||
struct timespec64 begin, end;
|
struct timespec64 begin, end;
|
||||||
|
unsigned long sz_applied = 0;
|
||||||
|
|
||||||
if (!s->wmarks.activated)
|
if (!s->wmarks.activated)
|
||||||
continue;
|
continue;
|
||||||
@ -627,7 +627,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
|
|||||||
damon_split_region_at(c, t, r, sz);
|
damon_split_region_at(c, t, r, sz);
|
||||||
}
|
}
|
||||||
ktime_get_coarse_ts64(&begin);
|
ktime_get_coarse_ts64(&begin);
|
||||||
c->primitive.apply_scheme(c, t, r, s);
|
sz_applied = c->primitive.apply_scheme(c, t, r, s);
|
||||||
ktime_get_coarse_ts64(&end);
|
ktime_get_coarse_ts64(&end);
|
||||||
quota->total_charged_ns += timespec64_to_ns(&end) -
|
quota->total_charged_ns += timespec64_to_ns(&end) -
|
||||||
timespec64_to_ns(&begin);
|
timespec64_to_ns(&begin);
|
||||||
@ -641,8 +641,11 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
|
|||||||
r->age = 0;
|
r->age = 0;
|
||||||
|
|
||||||
update_stat:
|
update_stat:
|
||||||
s->stat_count++;
|
s->stat.nr_tried++;
|
||||||
s->stat_sz += sz;
|
s->stat.sz_tried += sz;
|
||||||
|
if (sz_applied)
|
||||||
|
s->stat.nr_applied++;
|
||||||
|
s->stat.sz_applied += sz_applied;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ static ssize_t sprint_schemes(struct damon_ctx *c, char *buf, ssize_t len)
|
|||||||
s->quota.weight_age,
|
s->quota.weight_age,
|
||||||
s->wmarks.metric, s->wmarks.interval,
|
s->wmarks.metric, s->wmarks.interval,
|
||||||
s->wmarks.high, s->wmarks.mid, s->wmarks.low,
|
s->wmarks.high, s->wmarks.mid, s->wmarks.low,
|
||||||
s->stat_count, s->stat_sz);
|
s->stat.nr_tried, s->stat.sz_tried);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -213,14 +213,15 @@ bool damon_pa_target_valid(void *t)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int damon_pa_apply_scheme(struct damon_ctx *ctx, struct damon_target *t,
|
static unsigned long damon_pa_apply_scheme(struct damon_ctx *ctx,
|
||||||
struct damon_region *r, struct damos *scheme)
|
struct damon_target *t, struct damon_region *r,
|
||||||
|
struct damos *scheme)
|
||||||
{
|
{
|
||||||
unsigned long addr;
|
unsigned long addr, applied;
|
||||||
LIST_HEAD(page_list);
|
LIST_HEAD(page_list);
|
||||||
|
|
||||||
if (scheme->action != DAMOS_PAGEOUT)
|
if (scheme->action != DAMOS_PAGEOUT)
|
||||||
return -EINVAL;
|
return 0;
|
||||||
|
|
||||||
for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
|
for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
|
||||||
struct page *page = damon_get_page(PHYS_PFN(addr));
|
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,
|
|||||||
put_page(page);
|
put_page(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reclaim_pages(&page_list);
|
applied = reclaim_pages(&page_list);
|
||||||
cond_resched();
|
cond_resched();
|
||||||
return 0;
|
return applied * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int damon_pa_scheme_score(struct damon_ctx *context,
|
static int damon_pa_scheme_score(struct damon_ctx *context,
|
||||||
|
@ -571,32 +571,34 @@ bool damon_va_target_valid(void *target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_ADVISE_SYSCALLS
|
#ifndef CONFIG_ADVISE_SYSCALLS
|
||||||
static int damos_madvise(struct damon_target *target, struct damon_region *r,
|
static unsigned long damos_madvise(struct damon_target *target,
|
||||||
int behavior)
|
struct damon_region *r, int behavior)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int damos_madvise(struct damon_target *target, struct damon_region *r,
|
static unsigned long damos_madvise(struct damon_target *target,
|
||||||
int behavior)
|
struct damon_region *r, int behavior)
|
||||||
{
|
{
|
||||||
struct mm_struct *mm;
|
struct mm_struct *mm;
|
||||||
int ret = -ENOMEM;
|
unsigned long start = PAGE_ALIGN(r->ar.start);
|
||||||
|
unsigned long len = PAGE_ALIGN(r->ar.end - r->ar.start);
|
||||||
|
unsigned long applied;
|
||||||
|
|
||||||
mm = damon_get_mm(target);
|
mm = damon_get_mm(target);
|
||||||
if (!mm)
|
if (!mm)
|
||||||
goto out;
|
return 0;
|
||||||
|
|
||||||
ret = do_madvise(mm, PAGE_ALIGN(r->ar.start),
|
applied = do_madvise(mm, start, len, behavior) ? 0 : len;
|
||||||
PAGE_ALIGN(r->ar.end - r->ar.start), behavior);
|
|
||||||
mmput(mm);
|
mmput(mm);
|
||||||
out:
|
|
||||||
return ret;
|
return applied;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ADVISE_SYSCALLS */
|
#endif /* CONFIG_ADVISE_SYSCALLS */
|
||||||
|
|
||||||
static int damon_va_apply_scheme(struct damon_ctx *ctx, struct damon_target *t,
|
static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx,
|
||||||
struct damon_region *r, struct damos *scheme)
|
struct damon_target *t, struct damon_region *r,
|
||||||
|
struct damos *scheme)
|
||||||
{
|
{
|
||||||
int madv_action;
|
int madv_action;
|
||||||
|
|
||||||
@ -619,7 +621,7 @@ static int damon_va_apply_scheme(struct damon_ctx *ctx, struct damon_target *t,
|
|||||||
case DAMOS_STAT:
|
case DAMOS_STAT:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return damos_madvise(t, r, madv_action);
|
return damos_madvise(t, r, madv_action);
|
||||||
|
Loading…
Reference in New Issue
Block a user