Skip to content

Commit 1f1180d

Browse files
drobnikrppt
authored andcommitted
memblock tests: Add memblock_add tests
Add checks for adding a new region in different scenarios: - The region does not overlap with existing entries - The region overlaps with one of the previous entries: from the top (its end address is bigger than the base of the existing region) or from the bottom (its base address is smaller than the end address of one of the regions) - The region is within an already defined region - The same region is added twice to the collection of available memory regions Add checks for memblock initialization to verify it sets memblock data structures to expected values. Signed-off-by: Karolina Drobnik <[email protected]> Signed-off-by: Mike Rapoport <[email protected]> Link: https://lore.kernel.org/r/b6c26525025bccec0bf7419473d4d1293eb82b3b.1643796665.git.karolinadrobnik@gmail.com
1 parent f3252a2 commit 1f1180d

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed

tools/testing/memblock/tests/basic_api.c

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
22
#include <string.h>
33
#include <linux/memblock.h>
4+
#include <linux/sizes.h>
45
#include "basic_api.h"
56

67
#define EXPECTED_MEMBLOCK_REGIONS 128
@@ -25,8 +26,222 @@ static int memblock_initialization_check(void)
2526
return 0;
2627
}
2728

29+
/*
30+
* A simple test that adds a memory block of a specified base address
31+
* and size to the collection of available memory regions (memblock.memory).
32+
* It checks if a new entry was created and if region counter and total memory
33+
* were correctly updated.
34+
*/
35+
static int memblock_add_simple_check(void)
36+
{
37+
struct memblock_region *rgn;
38+
39+
rgn = &memblock.memory.regions[0];
40+
41+
struct region r = {
42+
.base = SZ_1G,
43+
.size = SZ_4M
44+
};
45+
46+
reset_memblock();
47+
memblock_add(r.base, r.size);
48+
49+
assert(rgn->base == r.base);
50+
assert(rgn->size == r.size);
51+
52+
assert(memblock.memory.cnt == 1);
53+
assert(memblock.memory.total_size == r.size);
54+
55+
return 0;
56+
}
57+
58+
/*
59+
* A test that tries to add two memory blocks that don't overlap with one
60+
* another. It checks if two correctly initialized entries were added to the
61+
* collection of available memory regions (memblock.memory) and if this
62+
* change was reflected in memblock.memory's total size and region counter.
63+
*/
64+
static int memblock_add_disjoint_check(void)
65+
{
66+
struct memblock_region *rgn1, *rgn2;
67+
68+
rgn1 = &memblock.memory.regions[0];
69+
rgn2 = &memblock.memory.regions[1];
70+
71+
struct region r1 = {
72+
.base = SZ_1G,
73+
.size = SZ_8K
74+
};
75+
struct region r2 = {
76+
.base = SZ_1G + SZ_16K,
77+
.size = SZ_8K
78+
};
79+
80+
reset_memblock();
81+
memblock_add(r1.base, r1.size);
82+
memblock_add(r2.base, r2.size);
83+
84+
assert(rgn1->base == r1.base);
85+
assert(rgn1->size == r1.size);
86+
87+
assert(rgn2->base == r2.base);
88+
assert(rgn2->size == r2.size);
89+
90+
assert(memblock.memory.cnt == 2);
91+
assert(memblock.memory.total_size == r1.size + r2.size);
92+
93+
return 0;
94+
}
95+
96+
/*
97+
* A test that tries to add two memory blocks, where the second one overlaps
98+
* with the beginning of the first entry (that is r1.base < r2.base + r2.size).
99+
* After this, it checks if two entries are merged into one region that starts
100+
* at r2.base and has size of two regions minus their intersection. It also
101+
* verifies the reported total size of the available memory and region counter.
102+
*/
103+
static int memblock_add_overlap_top_check(void)
104+
{
105+
struct memblock_region *rgn;
106+
phys_addr_t total_size;
107+
108+
rgn = &memblock.memory.regions[0];
109+
110+
struct region r1 = {
111+
.base = SZ_512M,
112+
.size = SZ_1G
113+
};
114+
struct region r2 = {
115+
.base = SZ_256M,
116+
.size = SZ_512M
117+
};
118+
119+
total_size = (r1.base - r2.base) + r1.size;
120+
121+
reset_memblock();
122+
memblock_add(r1.base, r1.size);
123+
memblock_add(r2.base, r2.size);
124+
125+
assert(rgn->base == r2.base);
126+
assert(rgn->size == total_size);
127+
128+
assert(memblock.memory.cnt == 1);
129+
assert(memblock.memory.total_size == total_size);
130+
131+
return 0;
132+
}
133+
134+
/*
135+
* A test that tries to add two memory blocks, where the second one overlaps
136+
* with the end of the first entry (that is r2.base < r1.base + r1.size).
137+
* After this, it checks if two entries are merged into one region that starts
138+
* at r1.base and has size of two regions minus their intersection. It verifies
139+
* that memblock can still see only one entry and has a correct total size of
140+
* the available memory.
141+
*/
142+
static int memblock_add_overlap_bottom_check(void)
143+
{
144+
struct memblock_region *rgn;
145+
phys_addr_t total_size;
146+
147+
rgn = &memblock.memory.regions[0];
148+
149+
struct region r1 = {
150+
.base = SZ_128M,
151+
.size = SZ_512M
152+
};
153+
struct region r2 = {
154+
.base = SZ_256M,
155+
.size = SZ_1G
156+
};
157+
158+
total_size = (r2.base - r1.base) + r2.size;
159+
160+
reset_memblock();
161+
memblock_add(r1.base, r1.size);
162+
memblock_add(r2.base, r2.size);
163+
164+
assert(rgn->base == r1.base);
165+
assert(rgn->size == total_size);
166+
167+
assert(memblock.memory.cnt == 1);
168+
assert(memblock.memory.total_size == total_size);
169+
170+
return 0;
171+
}
172+
173+
/*
174+
* A test that tries to add two memory blocks, where the second one is
175+
* within the range of the first entry (that is r1.base < r2.base &&
176+
* r2.base + r2.size < r1.base + r1.size). It checks if two entries are merged
177+
* into one region that stays the same. The counter and total size of available
178+
* memory are expected to not be updated.
179+
*/
180+
static int memblock_add_within_check(void)
181+
{
182+
struct memblock_region *rgn;
183+
184+
rgn = &memblock.memory.regions[0];
185+
186+
struct region r1 = {
187+
.base = SZ_8M,
188+
.size = SZ_32M
189+
};
190+
struct region r2 = {
191+
.base = SZ_16M,
192+
.size = SZ_1M
193+
};
194+
195+
reset_memblock();
196+
memblock_add(r1.base, r1.size);
197+
memblock_add(r2.base, r2.size);
198+
199+
assert(rgn->base == r1.base);
200+
assert(rgn->size == r1.size);
201+
202+
assert(memblock.memory.cnt == 1);
203+
assert(memblock.memory.total_size == r1.size);
204+
205+
return 0;
206+
}
207+
208+
/*
209+
* A simple test that tries to add the same memory block twice. The counter
210+
* and total size of available memory are expected to not be updated.
211+
*/
212+
static int memblock_add_twice_check(void)
213+
{
214+
struct region r = {
215+
.base = SZ_16K,
216+
.size = SZ_2M
217+
};
218+
219+
reset_memblock();
220+
221+
memblock_add(r.base, r.size);
222+
memblock_add(r.base, r.size);
223+
224+
assert(memblock.memory.cnt == 1);
225+
assert(memblock.memory.total_size == r.size);
226+
227+
return 0;
228+
}
229+
230+
static int memblock_add_checks(void)
231+
{
232+
memblock_add_simple_check();
233+
memblock_add_disjoint_check();
234+
memblock_add_overlap_top_check();
235+
memblock_add_overlap_bottom_check();
236+
memblock_add_within_check();
237+
memblock_add_twice_check();
238+
239+
return 0;
240+
}
241+
28242
int memblock_basic_checks(void)
29243
{
30244
memblock_initialization_check();
245+
memblock_add_checks();
31246
return 0;
32247
}

0 commit comments

Comments
 (0)