aboutsummaryrefslogtreecommitdiffstats
path: root/patches/next/mm-damon-Add-debug-code.patch
blob: 2f73d596126cba91f2a52f8a6510ce0ccc4fe1ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 6f1b436575b5fb78c9eb72f9ae3707dea3407b9b Mon Sep 17 00:00:00 2001
From: SeongJae Park <sj@kernel.org>
Date: Sun, 14 Aug 2022 16:08:10 +0000
Subject: [PATCH] mm/damon: Add debug code

This commit adds verification check code.  Those should not be merged in
the final code.  Those are not expected to incur high overhead, though.

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/core.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/mm/damon/core.c b/mm/damon/core.c
index 939ecfcd4641..31ac8e4b1189 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -126,6 +126,12 @@ struct damon_region *damon_new_region(unsigned long start, unsigned long end)
 	if (!region)
 		return NULL;
 
+	if (start >= end) {
+		pr_err("%s called with start %lu and end %lu!\n", __func__,
+				start, end);
+		BUG();
+	}
+
 	region->ar.start = start;
 	region->ar.end = end;
 	region->nr_accesses = 0;
@@ -146,6 +152,10 @@ void damon_add_region(struct damon_region *r, struct damon_target *t)
 
 static void damon_del_region(struct damon_region *r, struct damon_target *t)
 {
+	if (t->nr_regions == 0) {
+		pr_err("nr_regions 0 but damon_del_region called\n");
+		BUG();
+	}
 	list_del(&r->list);
 	t->nr_regions--;
 }
@@ -476,8 +486,27 @@ void damon_destroy_target(struct damon_target *t)
 	damon_free_target(t);
 }
 
+static void damon_nr_regions_verify(struct damon_target *t)
+{
+	struct damon_region *r;
+	unsigned int count = 0;
+	static unsigned called;
+
+	if (called++ % 100)
+		return;
+
+	damon_for_each_region(r, t)
+		count++;
+
+	if (count != t->nr_regions)
+		pr_err("%s expected %u but %u\n", __func__, count, t->nr_regions);
+	BUG_ON(count != t->nr_regions);
+}
+
 unsigned int damon_nr_regions(struct damon_target *t)
 {
+	damon_nr_regions_verify(t);
+
 	return t->nr_regions;
 }
 
@@ -1033,6 +1062,15 @@ static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t,
 					DAMON_MIN_REGION);
 			if (!sz)
 				goto update_stat;
+			if (sz >= damon_sz_region(r)) {
+				pr_err("sz: %lu, region: %lu-%lu (%lu), quota: %lu, charged: %lu\n",
+						sz, r->ar.start,
+						r->ar.end, r->ar.end -
+						r->ar.start,
+						quota->esz,
+						quota->charged_sz);
+				BUG();
+			}
 			damon_split_region_at(t, r, sz);
 		}
 		if (damos_filter_out(c, t, r, s))
@@ -1318,6 +1356,14 @@ static void damon_merge_two_regions(struct damon_target *t,
 	l->nr_accesses_bp = l->nr_accesses * 10000;
 	l->age = (l->age * sz_l + r->age * sz_r) / (sz_l + sz_r);
 	l->ar.end = r->ar.end;
+
+	if (l->ar.start >= l->ar.end) {
+		pr_err("%s made %lu-%lu region\n", __func__, l->ar.start,
+				r->ar.end);
+		pr_err("r: %lu-%lu\n", r->ar.start, r->ar.end);
+		BUG();
+	}
+
 	damon_destroy_region(r, t);
 }
 
@@ -1339,6 +1385,12 @@ static void damon_merge_regions_of(struct damon_target *t, unsigned int thres,
 		else
 			r->age++;
 
+		if (r->nr_accesses != r->nr_accesses_bp / 10000) {
+			pr_err("nr_accesses (%u) != nr_accesses_bp (%u)\n",
+					r->nr_accesses, r->nr_accesses_bp);
+			BUG();
+		}
+
 		if (prev && prev->ar.end == r->ar.start &&
 		    abs(prev->nr_accesses - r->nr_accesses) <= thres &&
 		    damon_sz_region(prev) + damon_sz_region(r) <= sz_limit)
@@ -1379,6 +1431,12 @@ static void damon_split_region_at(struct damon_target *t,
 {
 	struct damon_region *new;
 
+	if (sz_r == 0 || sz_r >= r->ar.end - r->ar.start) {
+		pr_err("%s called with region of %lu-%lu and sz_r %lu!\n",
+				__func__, r->ar.start, r->ar.end, sz_r);
+		BUG();
+	}
+
 	new = damon_new_region(r->ar.start + sz_r, r->ar.end);
 	if (!new)
 		return;
-- 
2.39.2