Skip to content

Commit 16567b5

Browse files
drobnikrppt
authored andcommitted
memblock tests: Add memblock_alloc_from tests for top down
Add checks for memblock_alloc_from for default allocation direction. The tested scenarios are: - Not enough space to allocate memory at the minimal address - Minimal address parameter is smaller than the start address of the available memory - Minimal address is too close to the available memory Add simple memblock_alloc_from test that can be used to test both allocation directions (minimal address is aligned or misaligned). Signed-off-by: Karolina Drobnik <[email protected]> Signed-off-by: Mike Rapoport <[email protected]> Link: https://lore.kernel.org/r/3dd645f437975fd393010b95b8faa85d2b86490a.1646055639.git.karolinadrobnik@gmail.com
1 parent 0237ee2 commit 16567b5

File tree

4 files changed

+239
-1
lines changed

4 files changed

+239
-1
lines changed

tools/testing/memblock/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ CFLAGS += -I. -I../../include -Wall -O2 -fsanitize=address \
66
-fsanitize=undefined -D CONFIG_PHYS_ADDR_T_64BIT
77
LDFLAGS += -fsanitize=address -fsanitize=undefined
88
TARGETS = main
9-
TEST_OFILES = tests/alloc_api.o tests/basic_api.o tests/common.o
9+
TEST_OFILES = tests/alloc_helpers_api.o tests/alloc_api.o tests/basic_api.o \
10+
tests/common.o
1011
DEP_OFILES = memblock.o lib/slab.o mmzone.o slab.o
1112
OFILES = main.o $(DEP_OFILES) $(TEST_OFILES)
1213
EXTR_SRC = ../../../mm/memblock.c

tools/testing/memblock/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
22
#include "tests/basic_api.h"
33
#include "tests/alloc_api.h"
4+
#include "tests/alloc_helpers_api.h"
45

56
int main(int argc, char **argv)
67
{
78
memblock_basic_checks();
89
memblock_alloc_checks();
10+
memblock_alloc_helpers_checks();
911

1012
return 0;
1113
}
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
#include "alloc_helpers_api.h"
3+
4+
/*
5+
* A simple test that tries to allocate a memory region above a specified,
6+
* aligned address:
7+
*
8+
* +
9+
* | +-----------+ |
10+
* | | rgn | |
11+
* +----------+-----------+---------+
12+
* ^
13+
* |
14+
* Aligned min_addr
15+
*
16+
* Expect to allocate a cleared region at the minimal memory address.
17+
*/
18+
static int alloc_from_simple_generic_check(void)
19+
{
20+
struct memblock_region *rgn = &memblock.reserved.regions[0];
21+
void *allocated_ptr = NULL;
22+
char *b;
23+
24+
phys_addr_t size = SZ_16;
25+
phys_addr_t min_addr;
26+
27+
setup_memblock();
28+
29+
min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES;
30+
31+
allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
32+
b = (char *)allocated_ptr;
33+
34+
assert(allocated_ptr);
35+
assert(*b == 0);
36+
37+
assert(rgn->size == size);
38+
assert(rgn->base == min_addr);
39+
40+
assert(memblock.reserved.cnt == 1);
41+
assert(memblock.reserved.total_size == size);
42+
43+
return 0;
44+
}
45+
46+
/*
47+
* A test that tries to allocate a memory region above a certain address.
48+
* The minimal address here is not aligned:
49+
*
50+
* + +
51+
* | + +---------+ |
52+
* | | | rgn | |
53+
* +------+------+---------+------------+
54+
* ^ ^------.
55+
* | |
56+
* min_addr Aligned address
57+
* boundary
58+
*
59+
* Expect to allocate a cleared region at the closest aligned memory address.
60+
*/
61+
static int alloc_from_misaligned_generic_check(void)
62+
{
63+
struct memblock_region *rgn = &memblock.reserved.regions[0];
64+
void *allocated_ptr = NULL;
65+
char *b;
66+
67+
phys_addr_t size = SZ_32;
68+
phys_addr_t min_addr;
69+
70+
setup_memblock();
71+
72+
/* A misaligned address */
73+
min_addr = memblock_end_of_DRAM() - (SMP_CACHE_BYTES * 2 - 1);
74+
75+
allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
76+
b = (char *)allocated_ptr;
77+
78+
assert(allocated_ptr);
79+
assert(*b == 0);
80+
81+
assert(rgn->size == size);
82+
assert(rgn->base == memblock_end_of_DRAM() - SMP_CACHE_BYTES);
83+
84+
assert(memblock.reserved.cnt == 1);
85+
assert(memblock.reserved.total_size == size);
86+
87+
return 0;
88+
}
89+
90+
/*
91+
* A test that tries to allocate a memory region above an address that is too
92+
* close to the end of the memory:
93+
*
94+
* + +
95+
* | +--------+---+ |
96+
* | | rgn + | |
97+
* +-----------+--------+---+------+
98+
* ^ ^
99+
* | |
100+
* | min_addr
101+
* |
102+
* Aligned address
103+
* boundary
104+
*
105+
* Expect to prioritize granting memory over satisfying the minimal address
106+
* requirement.
107+
*/
108+
static int alloc_from_top_down_high_addr_check(void)
109+
{
110+
struct memblock_region *rgn = &memblock.reserved.regions[0];
111+
void *allocated_ptr = NULL;
112+
113+
phys_addr_t size = SZ_32;
114+
phys_addr_t min_addr;
115+
116+
setup_memblock();
117+
118+
/* The address is too close to the end of the memory */
119+
min_addr = memblock_end_of_DRAM() - SZ_16;
120+
121+
allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
122+
123+
assert(allocated_ptr);
124+
assert(rgn->size == size);
125+
assert(rgn->base == memblock_end_of_DRAM() - SMP_CACHE_BYTES);
126+
127+
assert(memblock.reserved.cnt == 1);
128+
assert(memblock.reserved.total_size == size);
129+
130+
return 0;
131+
}
132+
133+
/*
134+
* A test that tries to allocate a memory region when there is no space
135+
* available above the minimal address above a certain address:
136+
*
137+
* +
138+
* | +---------+-------------|
139+
* | | rgn | |
140+
* +--------+---------+-------------+
141+
* ^
142+
* |
143+
* min_addr
144+
*
145+
* Expect to prioritize granting memory over satisfying the minimal address
146+
* requirement and to allocate next to the previously reserved region. The
147+
* regions get merged into one.
148+
*/
149+
static int alloc_from_top_down_no_space_above_check(void)
150+
{
151+
struct memblock_region *rgn = &memblock.reserved.regions[0];
152+
void *allocated_ptr = NULL;
153+
154+
phys_addr_t r1_size = SZ_64;
155+
phys_addr_t r2_size = SZ_2;
156+
phys_addr_t total_size = r1_size + r2_size;
157+
phys_addr_t min_addr;
158+
159+
setup_memblock();
160+
161+
min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2;
162+
163+
/* No space above this address */
164+
memblock_reserve(min_addr, r2_size);
165+
166+
allocated_ptr = memblock_alloc_from(r1_size, SMP_CACHE_BYTES, min_addr);
167+
168+
assert(allocated_ptr);
169+
assert(rgn->base == min_addr - r1_size);
170+
assert(rgn->size == total_size);
171+
172+
assert(memblock.reserved.cnt == 1);
173+
assert(memblock.reserved.total_size == total_size);
174+
175+
return 0;
176+
}
177+
178+
/*
179+
* A test that tries to allocate a memory region with a minimal address below
180+
* the start address of the available memory. As the allocation is top-down,
181+
* first reserve a region that will force allocation near the start.
182+
* Expect successful allocation and merge of both regions.
183+
*/
184+
static int alloc_from_top_down_min_addr_cap_check(void)
185+
{
186+
struct memblock_region *rgn = &memblock.reserved.regions[0];
187+
void *allocated_ptr = NULL;
188+
189+
phys_addr_t r1_size = SZ_64;
190+
phys_addr_t min_addr;
191+
phys_addr_t start_addr;
192+
193+
setup_memblock();
194+
195+
start_addr = (phys_addr_t)memblock_start_of_DRAM();
196+
min_addr = start_addr - SMP_CACHE_BYTES * 3;
197+
198+
memblock_reserve(start_addr + r1_size, MEM_SIZE - r1_size);
199+
200+
allocated_ptr = memblock_alloc_from(r1_size, SMP_CACHE_BYTES, min_addr);
201+
202+
assert(allocated_ptr);
203+
assert(rgn->base == start_addr);
204+
assert(rgn->size == MEM_SIZE);
205+
206+
assert(memblock.reserved.cnt == 1);
207+
assert(memblock.reserved.total_size == MEM_SIZE);
208+
209+
return 0;
210+
}
211+
212+
int memblock_alloc_helpers_checks(void)
213+
{
214+
reset_memblock_attributes();
215+
dummy_physical_memory_init();
216+
217+
alloc_from_simple_generic_check();
218+
alloc_from_misaligned_generic_check();
219+
alloc_from_top_down_high_addr_check();
220+
alloc_from_top_down_min_addr_cap_check();
221+
alloc_from_top_down_no_space_above_check();
222+
223+
dummy_physical_memory_cleanup();
224+
225+
return 0;
226+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
#ifndef _MEMBLOCK_ALLOC_HELPERS_H
3+
#define _MEMBLOCK_ALLOC_HELPERS_H
4+
5+
#include "common.h"
6+
7+
int memblock_alloc_helpers_checks(void);
8+
9+
#endif

0 commit comments

Comments
 (0)