Skip to content

Commit 83787a8

Browse files
drobnikrppt
authored andcommitted
memblock tests: Add memblock_reserve tests
Add checks for marking a region as reserved 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 marked as reserved twice Signed-off-by: Karolina Drobnik <[email protected]> Signed-off-by: Mike Rapoport <[email protected]> Link: https://lore.kernel.org/r/cac867d2b6c17e53d9e977b5d6cd88cc4e9453b6.1643796665.git.karolinadrobnik@gmail.com
1 parent 1f1180d commit 83787a8

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed

tools/testing/memblock/tests/basic_api.c

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,226 @@ static int memblock_add_checks(void)
239239
return 0;
240240
}
241241

242+
/*
243+
* A simple test that marks a memory block of a specified base address
244+
* and size as reserved and to the collection of reserved memory regions
245+
* (memblock.reserved). It checks if a new entry was created and if region
246+
* counter and total memory size were correctly updated.
247+
*/
248+
static int memblock_reserve_simple_check(void)
249+
{
250+
struct memblock_region *rgn;
251+
252+
rgn = &memblock.reserved.regions[0];
253+
254+
struct region r = {
255+
.base = SZ_2G,
256+
.size = SZ_128M
257+
};
258+
259+
reset_memblock();
260+
memblock_reserve(r.base, r.size);
261+
262+
assert(rgn->base == r.base);
263+
assert(rgn->size == r.size);
264+
265+
return 0;
266+
}
267+
268+
/*
269+
* A test that tries to mark two memory blocks that don't overlap as reserved
270+
* and checks if two entries were correctly added to the collection of reserved
271+
* memory regions (memblock.reserved) and if this change was reflected in
272+
* memblock.reserved's total size and region counter.
273+
*/
274+
static int memblock_reserve_disjoint_check(void)
275+
{
276+
struct memblock_region *rgn1, *rgn2;
277+
278+
rgn1 = &memblock.reserved.regions[0];
279+
rgn2 = &memblock.reserved.regions[1];
280+
281+
struct region r1 = {
282+
.base = SZ_256M,
283+
.size = SZ_16M
284+
};
285+
struct region r2 = {
286+
.base = SZ_512M,
287+
.size = SZ_512M
288+
};
289+
290+
reset_memblock();
291+
memblock_reserve(r1.base, r1.size);
292+
memblock_reserve(r2.base, r2.size);
293+
294+
assert(rgn1->base == r1.base);
295+
assert(rgn1->size == r1.size);
296+
297+
assert(rgn2->base == r2.base);
298+
assert(rgn2->size == r2.size);
299+
300+
assert(memblock.reserved.cnt == 2);
301+
assert(memblock.reserved.total_size == r1.size + r2.size);
302+
303+
return 0;
304+
}
305+
306+
/*
307+
* A test that tries to mark two memory blocks as reserved, where the
308+
* second one overlaps with the beginning of the first (that is
309+
* r1.base < r2.base + r2.size).
310+
* It checks if two entries are merged into one region that starts at r2.base
311+
* and has size of two regions minus their intersection. The test also verifies
312+
* that memblock can still see only one entry and has a correct total size of
313+
* the reserved memory.
314+
*/
315+
static int memblock_reserve_overlap_top_check(void)
316+
{
317+
struct memblock_region *rgn;
318+
phys_addr_t total_size;
319+
320+
rgn = &memblock.reserved.regions[0];
321+
322+
struct region r1 = {
323+
.base = SZ_1G,
324+
.size = SZ_1G
325+
};
326+
struct region r2 = {
327+
.base = SZ_128M,
328+
.size = SZ_1G
329+
};
330+
331+
total_size = (r1.base - r2.base) + r1.size;
332+
333+
reset_memblock();
334+
memblock_reserve(r1.base, r1.size);
335+
memblock_reserve(r2.base, r2.size);
336+
337+
assert(rgn->base == r2.base);
338+
assert(rgn->size == total_size);
339+
340+
assert(memblock.reserved.cnt == 1);
341+
assert(memblock.reserved.total_size == total_size);
342+
343+
return 0;
344+
}
345+
346+
/*
347+
* A test that tries to mark two memory blocks as reserved, where the
348+
* second one overlaps with the end of the first entry (that is
349+
* r2.base < r1.base + r1.size).
350+
* It checks if two entries are merged into one region that starts at r1.base
351+
* and has size of two regions minus their intersection. It verifies that
352+
* memblock can still see only one entry and has a correct total size of the
353+
* reserved memory.
354+
*/
355+
static int memblock_reserve_overlap_bottom_check(void)
356+
{
357+
struct memblock_region *rgn;
358+
phys_addr_t total_size;
359+
360+
rgn = &memblock.reserved.regions[0];
361+
362+
struct region r1 = {
363+
.base = SZ_2K,
364+
.size = SZ_128K
365+
};
366+
struct region r2 = {
367+
.base = SZ_128K,
368+
.size = SZ_128K
369+
};
370+
371+
total_size = (r2.base - r1.base) + r2.size;
372+
373+
reset_memblock();
374+
memblock_reserve(r1.base, r1.size);
375+
memblock_reserve(r2.base, r2.size);
376+
377+
assert(rgn->base == r1.base);
378+
assert(rgn->size == total_size);
379+
380+
assert(memblock.reserved.cnt == 1);
381+
assert(memblock.reserved.total_size == total_size);
382+
383+
return 0;
384+
}
385+
386+
/*
387+
* A test that tries to mark two memory blocks as reserved, where the second
388+
* one is within the range of the first entry (that is
389+
* (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
390+
* It checks if two entries are merged into one region that stays the
391+
* same. The counter and total size of available memory are expected to not be
392+
* updated.
393+
*/
394+
static int memblock_reserve_within_check(void)
395+
{
396+
struct memblock_region *rgn;
397+
398+
rgn = &memblock.reserved.regions[0];
399+
400+
struct region r1 = {
401+
.base = SZ_1M,
402+
.size = SZ_8M
403+
};
404+
struct region r2 = {
405+
.base = SZ_2M,
406+
.size = SZ_64K
407+
};
408+
409+
reset_memblock();
410+
memblock_reserve(r1.base, r1.size);
411+
memblock_reserve(r2.base, r2.size);
412+
413+
assert(rgn->base == r1.base);
414+
assert(rgn->size == r1.size);
415+
416+
assert(memblock.reserved.cnt == 1);
417+
assert(memblock.reserved.total_size == r1.size);
418+
419+
return 0;
420+
}
421+
422+
/*
423+
* A simple test that tries to reserve the same memory block twice.
424+
* The region counter and total size of reserved memory are expected to not
425+
* be updated.
426+
*/
427+
static int memblock_reserve_twice_check(void)
428+
{
429+
struct region r = {
430+
.base = SZ_16K,
431+
.size = SZ_2M
432+
};
433+
434+
reset_memblock();
435+
436+
memblock_reserve(r.base, r.size);
437+
memblock_reserve(r.base, r.size);
438+
439+
assert(memblock.reserved.cnt == 1);
440+
assert(memblock.reserved.total_size == r.size);
441+
442+
return 0;
443+
}
444+
445+
static int memblock_reserve_checks(void)
446+
{
447+
memblock_reserve_simple_check();
448+
memblock_reserve_disjoint_check();
449+
memblock_reserve_overlap_top_check();
450+
memblock_reserve_overlap_bottom_check();
451+
memblock_reserve_within_check();
452+
memblock_reserve_twice_check();
453+
454+
return 0;
455+
}
456+
242457
int memblock_basic_checks(void)
243458
{
244459
memblock_initialization_check();
245460
memblock_add_checks();
461+
memblock_reserve_checks();
462+
246463
return 0;
247464
}

0 commit comments

Comments
 (0)