alloc_helpers_api.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include "alloc_helpers_api.h"
  3. /*
  4. * A simple test that tries to allocate a memory region above a specified,
  5. * aligned address:
  6. *
  7. * +
  8. * | +-----------+ |
  9. * | | rgn | |
  10. * +----------+-----------+---------+
  11. * ^
  12. * |
  13. * Aligned min_addr
  14. *
  15. * Expect to allocate a cleared region at the minimal memory address.
  16. */
  17. static int alloc_from_simple_generic_check(void)
  18. {
  19. struct memblock_region *rgn = &memblock.reserved.regions[0];
  20. void *allocated_ptr = NULL;
  21. phys_addr_t size = SZ_16;
  22. phys_addr_t min_addr;
  23. PREFIX_PUSH();
  24. setup_memblock();
  25. min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES;
  26. allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
  27. ASSERT_NE(allocated_ptr, NULL);
  28. ASSERT_MEM_EQ(allocated_ptr, 0, size);
  29. ASSERT_EQ(rgn->size, size);
  30. ASSERT_EQ(rgn->base, min_addr);
  31. ASSERT_EQ(memblock.reserved.cnt, 1);
  32. ASSERT_EQ(memblock.reserved.total_size, size);
  33. test_pass_pop();
  34. return 0;
  35. }
  36. /*
  37. * A test that tries to allocate a memory region above a certain address.
  38. * The minimal address here is not aligned:
  39. *
  40. * + +
  41. * | + +---------+ |
  42. * | | | rgn | |
  43. * +------+------+---------+------------+
  44. * ^ ^------.
  45. * | |
  46. * min_addr Aligned address
  47. * boundary
  48. *
  49. * Expect to allocate a cleared region at the closest aligned memory address.
  50. */
  51. static int alloc_from_misaligned_generic_check(void)
  52. {
  53. struct memblock_region *rgn = &memblock.reserved.regions[0];
  54. void *allocated_ptr = NULL;
  55. phys_addr_t size = SZ_32;
  56. phys_addr_t min_addr;
  57. PREFIX_PUSH();
  58. setup_memblock();
  59. /* A misaligned address */
  60. min_addr = memblock_end_of_DRAM() - (SMP_CACHE_BYTES * 2 - 1);
  61. allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
  62. ASSERT_NE(allocated_ptr, NULL);
  63. ASSERT_MEM_EQ(allocated_ptr, 0, size);
  64. ASSERT_EQ(rgn->size, size);
  65. ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - SMP_CACHE_BYTES);
  66. ASSERT_EQ(memblock.reserved.cnt, 1);
  67. ASSERT_EQ(memblock.reserved.total_size, size);
  68. test_pass_pop();
  69. return 0;
  70. }
  71. /*
  72. * A test that tries to allocate a memory region above an address that is too
  73. * close to the end of the memory:
  74. *
  75. * + +
  76. * | +--------+---+ |
  77. * | | rgn + | |
  78. * +-----------+--------+---+------+
  79. * ^ ^
  80. * | |
  81. * | min_addr
  82. * |
  83. * Aligned address
  84. * boundary
  85. *
  86. * Expect to prioritize granting memory over satisfying the minimal address
  87. * requirement.
  88. */
  89. static int alloc_from_top_down_high_addr_check(void)
  90. {
  91. struct memblock_region *rgn = &memblock.reserved.regions[0];
  92. void *allocated_ptr = NULL;
  93. phys_addr_t size = SZ_32;
  94. phys_addr_t min_addr;
  95. PREFIX_PUSH();
  96. setup_memblock();
  97. /* The address is too close to the end of the memory */
  98. min_addr = memblock_end_of_DRAM() - SZ_16;
  99. allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
  100. ASSERT_NE(allocated_ptr, NULL);
  101. ASSERT_EQ(rgn->size, size);
  102. ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - SMP_CACHE_BYTES);
  103. ASSERT_EQ(memblock.reserved.cnt, 1);
  104. ASSERT_EQ(memblock.reserved.total_size, size);
  105. test_pass_pop();
  106. return 0;
  107. }
  108. /*
  109. * A test that tries to allocate a memory region when there is no space
  110. * available above the minimal address above a certain address:
  111. *
  112. * +
  113. * | +---------+-------------|
  114. * | | rgn | |
  115. * +--------+---------+-------------+
  116. * ^
  117. * |
  118. * min_addr
  119. *
  120. * Expect to prioritize granting memory over satisfying the minimal address
  121. * requirement and to allocate next to the previously reserved region. The
  122. * regions get merged into one.
  123. */
  124. static int alloc_from_top_down_no_space_above_check(void)
  125. {
  126. struct memblock_region *rgn = &memblock.reserved.regions[0];
  127. void *allocated_ptr = NULL;
  128. phys_addr_t r1_size = SZ_64;
  129. phys_addr_t r2_size = SZ_2;
  130. phys_addr_t total_size = r1_size + r2_size;
  131. phys_addr_t min_addr;
  132. PREFIX_PUSH();
  133. setup_memblock();
  134. min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2;
  135. /* No space above this address */
  136. memblock_reserve_kern(min_addr, r2_size);
  137. allocated_ptr = memblock_alloc_from(r1_size, SMP_CACHE_BYTES, min_addr);
  138. ASSERT_NE(allocated_ptr, NULL);
  139. ASSERT_EQ(rgn->base, min_addr - r1_size);
  140. ASSERT_EQ(rgn->size, total_size);
  141. ASSERT_EQ(memblock.reserved.cnt, 1);
  142. ASSERT_EQ(memblock.reserved.total_size, total_size);
  143. test_pass_pop();
  144. return 0;
  145. }
  146. /*
  147. * A test that tries to allocate a memory region with a minimal address below
  148. * the start address of the available memory. As the allocation is top-down,
  149. * first reserve a region that will force allocation near the start.
  150. * Expect successful allocation and merge of both regions.
  151. */
  152. static int alloc_from_top_down_min_addr_cap_check(void)
  153. {
  154. struct memblock_region *rgn = &memblock.reserved.regions[0];
  155. void *allocated_ptr = NULL;
  156. phys_addr_t r1_size = SZ_64;
  157. phys_addr_t min_addr;
  158. phys_addr_t start_addr;
  159. PREFIX_PUSH();
  160. setup_memblock();
  161. start_addr = (phys_addr_t)memblock_start_of_DRAM();
  162. min_addr = start_addr - SMP_CACHE_BYTES * 3;
  163. memblock_reserve_kern(start_addr + r1_size, MEM_SIZE - r1_size);
  164. allocated_ptr = memblock_alloc_from(r1_size, SMP_CACHE_BYTES, min_addr);
  165. ASSERT_NE(allocated_ptr, NULL);
  166. ASSERT_EQ(rgn->base, start_addr);
  167. ASSERT_EQ(rgn->size, MEM_SIZE);
  168. ASSERT_EQ(memblock.reserved.cnt, 1);
  169. ASSERT_EQ(memblock.reserved.total_size, MEM_SIZE);
  170. test_pass_pop();
  171. return 0;
  172. }
  173. /*
  174. * A test that tries to allocate a memory region above an address that is too
  175. * close to the end of the memory:
  176. *
  177. * +
  178. * |-----------+ + |
  179. * | rgn | | |
  180. * +-----------+--------------+-----+
  181. * ^ ^
  182. * | |
  183. * Aligned address min_addr
  184. * boundary
  185. *
  186. * Expect to prioritize granting memory over satisfying the minimal address
  187. * requirement. Allocation happens at beginning of the available memory.
  188. */
  189. static int alloc_from_bottom_up_high_addr_check(void)
  190. {
  191. struct memblock_region *rgn = &memblock.reserved.regions[0];
  192. void *allocated_ptr = NULL;
  193. phys_addr_t size = SZ_32;
  194. phys_addr_t min_addr;
  195. PREFIX_PUSH();
  196. setup_memblock();
  197. /* The address is too close to the end of the memory */
  198. min_addr = memblock_end_of_DRAM() - SZ_8;
  199. allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
  200. ASSERT_NE(allocated_ptr, NULL);
  201. ASSERT_EQ(rgn->size, size);
  202. ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
  203. ASSERT_EQ(memblock.reserved.cnt, 1);
  204. ASSERT_EQ(memblock.reserved.total_size, size);
  205. test_pass_pop();
  206. return 0;
  207. }
  208. /*
  209. * A test that tries to allocate a memory region when there is no space
  210. * available above the minimal address above a certain address:
  211. *
  212. * +
  213. * |-----------+ +-------------------|
  214. * | rgn | | |
  215. * +-----------+----+-------------------+
  216. * ^
  217. * |
  218. * min_addr
  219. *
  220. * Expect to prioritize granting memory over satisfying the minimal address
  221. * requirement and to allocate at the beginning of the available memory.
  222. */
  223. static int alloc_from_bottom_up_no_space_above_check(void)
  224. {
  225. struct memblock_region *rgn = &memblock.reserved.regions[0];
  226. void *allocated_ptr = NULL;
  227. phys_addr_t r1_size = SZ_64;
  228. phys_addr_t min_addr;
  229. phys_addr_t r2_size;
  230. PREFIX_PUSH();
  231. setup_memblock();
  232. min_addr = memblock_start_of_DRAM() + SZ_128;
  233. r2_size = memblock_end_of_DRAM() - min_addr;
  234. /* No space above this address */
  235. memblock_reserve(min_addr - SMP_CACHE_BYTES, r2_size);
  236. allocated_ptr = memblock_alloc_from(r1_size, SMP_CACHE_BYTES, min_addr);
  237. ASSERT_NE(allocated_ptr, NULL);
  238. ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
  239. ASSERT_EQ(rgn->size, r1_size);
  240. ASSERT_EQ(memblock.reserved.cnt, 2);
  241. ASSERT_EQ(memblock.reserved.total_size, r1_size + r2_size);
  242. test_pass_pop();
  243. return 0;
  244. }
  245. /*
  246. * A test that tries to allocate a memory region with a minimal address below
  247. * the start address of the available memory. Expect to allocate a region
  248. * at the beginning of the available memory.
  249. */
  250. static int alloc_from_bottom_up_min_addr_cap_check(void)
  251. {
  252. struct memblock_region *rgn = &memblock.reserved.regions[0];
  253. void *allocated_ptr = NULL;
  254. phys_addr_t r1_size = SZ_64;
  255. phys_addr_t min_addr;
  256. phys_addr_t start_addr;
  257. PREFIX_PUSH();
  258. setup_memblock();
  259. start_addr = (phys_addr_t)memblock_start_of_DRAM();
  260. min_addr = start_addr - SMP_CACHE_BYTES * 3;
  261. allocated_ptr = memblock_alloc_from(r1_size, SMP_CACHE_BYTES, min_addr);
  262. ASSERT_NE(allocated_ptr, NULL);
  263. ASSERT_EQ(rgn->base, start_addr);
  264. ASSERT_EQ(rgn->size, r1_size);
  265. ASSERT_EQ(memblock.reserved.cnt, 1);
  266. ASSERT_EQ(memblock.reserved.total_size, r1_size);
  267. test_pass_pop();
  268. return 0;
  269. }
  270. /* Test case wrappers */
  271. static int alloc_from_simple_check(void)
  272. {
  273. test_print("\tRunning %s...\n", __func__);
  274. run_top_down(alloc_from_simple_generic_check);
  275. run_bottom_up(alloc_from_simple_generic_check);
  276. return 0;
  277. }
  278. static int alloc_from_misaligned_check(void)
  279. {
  280. test_print("\tRunning %s...\n", __func__);
  281. run_top_down(alloc_from_misaligned_generic_check);
  282. run_bottom_up(alloc_from_misaligned_generic_check);
  283. return 0;
  284. }
  285. static int alloc_from_high_addr_check(void)
  286. {
  287. test_print("\tRunning %s...\n", __func__);
  288. memblock_set_bottom_up(false);
  289. alloc_from_top_down_high_addr_check();
  290. memblock_set_bottom_up(true);
  291. alloc_from_bottom_up_high_addr_check();
  292. return 0;
  293. }
  294. static int alloc_from_no_space_above_check(void)
  295. {
  296. test_print("\tRunning %s...\n", __func__);
  297. memblock_set_bottom_up(false);
  298. alloc_from_top_down_no_space_above_check();
  299. memblock_set_bottom_up(true);
  300. alloc_from_bottom_up_no_space_above_check();
  301. return 0;
  302. }
  303. static int alloc_from_min_addr_cap_check(void)
  304. {
  305. test_print("\tRunning %s...\n", __func__);
  306. memblock_set_bottom_up(false);
  307. alloc_from_top_down_min_addr_cap_check();
  308. memblock_set_bottom_up(true);
  309. alloc_from_bottom_up_min_addr_cap_check();
  310. return 0;
  311. }
  312. int memblock_alloc_helpers_checks(void)
  313. {
  314. const char *func_testing = "memblock_alloc_from";
  315. prefix_reset();
  316. prefix_push(func_testing);
  317. test_print("Running %s tests...\n", func_testing);
  318. reset_memblock_attributes();
  319. dummy_physical_memory_init();
  320. alloc_from_simple_check();
  321. alloc_from_misaligned_check();
  322. alloc_from_high_addr_check();
  323. alloc_from_no_space_above_check();
  324. alloc_from_min_addr_cap_check();
  325. dummy_physical_memory_cleanup();
  326. prefix_pop();
  327. return 0;
  328. }