Skip to content

Commit 5058519

Browse files
sjp38torvalds
authored andcommitted
mm/damon/schemes: skip already charged targets and regions
If DAMOS has stopped applying action in the middle of a group of memory regions due to its size quota, it starts the work again from the beginning of the address space in the next charge window. If there is a huge memory region at the beginning of the address space and it fulfills the scheme's target data access pattern always, the action will applied to only the region. This mitigates the case by skipping memory regions that charged in current charge window at the beginning of next charge window. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: SeongJae Park <[email protected]> Cc: Amit Shah <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: David Rientjes <[email protected]> Cc: David Woodhouse <[email protected]> Cc: Greg Thelen <[email protected]> Cc: Jonathan Cameron <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Leonard Foerster <[email protected]> Cc: Marco Elver <[email protected]> Cc: Markus Boehme <[email protected]> Cc: Shakeel Butt <[email protected]> Cc: Shuah Khan <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 2b8a248 commit 5058519

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

include/linux/damon.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ struct damos_quota {
107107
/* private: For charging the quota */
108108
unsigned long charged_sz;
109109
unsigned long charged_from;
110+
struct damon_target *charge_target_from;
111+
unsigned long charge_addr_from;
110112
};
111113

112114
/**
@@ -307,6 +309,9 @@ struct damon_ctx {
307309
#define damon_prev_region(r) \
308310
(container_of(r->list.prev, struct damon_region, list))
309311

312+
#define damon_last_region(t) \
313+
(list_last_entry(&t->regions_list, struct damon_region, list))
314+
310315
#define damon_for_each_region(r, t) \
311316
list_for_each_entry(r, &t->regions_list, list)
312317

mm/damon/core.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)