@@ -209,16 +209,183 @@ static int alloc_from_top_down_min_addr_cap_check(void)
209
209
return 0 ;
210
210
}
211
211
212
- int memblock_alloc_helpers_checks (void )
212
+ /*
213
+ * A test that tries to allocate a memory region above an address that is too
214
+ * close to the end of the memory:
215
+ *
216
+ * +
217
+ * |-----------+ + |
218
+ * | rgn | | |
219
+ * +-----------+--------------+-----+
220
+ * ^ ^
221
+ * | |
222
+ * Aligned address min_addr
223
+ * boundary
224
+ *
225
+ * Expect to prioritize granting memory over satisfying the minimal address
226
+ * requirement. Allocation happens at beginning of the available memory.
227
+ */
228
+ static int alloc_from_bottom_up_high_addr_check (void )
213
229
{
214
- reset_memblock_attributes ();
215
- dummy_physical_memory_init ();
230
+ struct memblock_region * rgn = & memblock .reserved .regions [0 ];
231
+ void * allocated_ptr = NULL ;
232
+
233
+ phys_addr_t size = SZ_32 ;
234
+ phys_addr_t min_addr ;
235
+
236
+ setup_memblock ();
237
+
238
+ /* The address is too close to the end of the memory */
239
+ min_addr = memblock_end_of_DRAM () - SZ_8 ;
240
+
241
+ allocated_ptr = memblock_alloc_from (size , SMP_CACHE_BYTES , min_addr );
242
+
243
+ assert (allocated_ptr );
244
+ assert (rgn -> size == size );
245
+ assert (rgn -> base == memblock_start_of_DRAM ());
246
+
247
+ assert (memblock .reserved .cnt == 1 );
248
+ assert (memblock .reserved .total_size == size );
249
+
250
+ return 0 ;
251
+ }
216
252
253
+ /*
254
+ * A test that tries to allocate a memory region when there is no space
255
+ * available above the minimal address above a certain address:
256
+ *
257
+ * +
258
+ * |-----------+ +-------------------|
259
+ * | rgn | | |
260
+ * +-----------+----+-------------------+
261
+ * ^
262
+ * |
263
+ * min_addr
264
+ *
265
+ * Expect to prioritize granting memory over satisfying the minimal address
266
+ * requirement and to allocate at the beginning of the available memory.
267
+ */
268
+ static int alloc_from_bottom_up_no_space_above_check (void )
269
+ {
270
+ struct memblock_region * rgn = & memblock .reserved .regions [0 ];
271
+ void * allocated_ptr = NULL ;
272
+
273
+ phys_addr_t r1_size = SZ_64 ;
274
+ phys_addr_t min_addr ;
275
+ phys_addr_t r2_size ;
276
+
277
+ setup_memblock ();
278
+
279
+ min_addr = memblock_start_of_DRAM () + SZ_128 ;
280
+ r2_size = memblock_end_of_DRAM () - min_addr ;
281
+
282
+ /* No space above this address */
283
+ memblock_reserve (min_addr - SMP_CACHE_BYTES , r2_size );
284
+
285
+ allocated_ptr = memblock_alloc_from (r1_size , SMP_CACHE_BYTES , min_addr );
286
+
287
+ assert (allocated_ptr );
288
+ assert (rgn -> base == memblock_start_of_DRAM ());
289
+ assert (rgn -> size == r1_size );
290
+
291
+ assert (memblock .reserved .cnt == 2 );
292
+ assert (memblock .reserved .total_size == r1_size + r2_size );
293
+
294
+ return 0 ;
295
+ }
296
+
297
+ /*
298
+ * A test that tries to allocate a memory region with a minimal address below
299
+ * the start address of the available memory. Expect to allocate a region
300
+ * at the beginning of the available memory.
301
+ */
302
+ static int alloc_from_bottom_up_min_addr_cap_check (void )
303
+ {
304
+ struct memblock_region * rgn = & memblock .reserved .regions [0 ];
305
+ void * allocated_ptr = NULL ;
306
+
307
+ phys_addr_t r1_size = SZ_64 ;
308
+ phys_addr_t min_addr ;
309
+ phys_addr_t start_addr ;
310
+
311
+ setup_memblock ();
312
+
313
+ start_addr = (phys_addr_t )memblock_start_of_DRAM ();
314
+ min_addr = start_addr - SMP_CACHE_BYTES * 3 ;
315
+
316
+ allocated_ptr = memblock_alloc_from (r1_size , SMP_CACHE_BYTES , min_addr );
317
+
318
+ assert (allocated_ptr );
319
+ assert (rgn -> base == start_addr );
320
+ assert (rgn -> size == r1_size );
321
+
322
+ assert (memblock .reserved .cnt == 1 );
323
+ assert (memblock .reserved .total_size == r1_size );
324
+
325
+ return 0 ;
326
+ }
327
+
328
+ /* Test case wrappers */
329
+ static int alloc_from_simple_check (void )
330
+ {
331
+ memblock_set_bottom_up (false);
332
+ alloc_from_simple_generic_check ();
333
+ memblock_set_bottom_up (true);
217
334
alloc_from_simple_generic_check ();
335
+
336
+ return 0 ;
337
+ }
338
+
339
+ static int alloc_from_misaligned_check (void )
340
+ {
341
+ memblock_set_bottom_up (false);
218
342
alloc_from_misaligned_generic_check ();
343
+ memblock_set_bottom_up (true);
344
+ alloc_from_misaligned_generic_check ();
345
+
346
+ return 0 ;
347
+ }
348
+
349
+ static int alloc_from_high_addr_check (void )
350
+ {
351
+ memblock_set_bottom_up (false);
219
352
alloc_from_top_down_high_addr_check ();
220
- alloc_from_top_down_min_addr_cap_check ();
353
+ memblock_set_bottom_up (true);
354
+ alloc_from_bottom_up_high_addr_check ();
355
+
356
+ return 0 ;
357
+ }
358
+
359
+ static int alloc_from_no_space_above_check (void )
360
+ {
361
+ memblock_set_bottom_up (false);
221
362
alloc_from_top_down_no_space_above_check ();
363
+ memblock_set_bottom_up (true);
364
+ alloc_from_bottom_up_no_space_above_check ();
365
+
366
+ return 0 ;
367
+ }
368
+
369
+ static int alloc_from_min_addr_cap_check (void )
370
+ {
371
+ memblock_set_bottom_up (false);
372
+ alloc_from_top_down_min_addr_cap_check ();
373
+ memblock_set_bottom_up (true);
374
+ alloc_from_bottom_up_min_addr_cap_check ();
375
+
376
+ return 0 ;
377
+ }
378
+
379
+ int memblock_alloc_helpers_checks (void )
380
+ {
381
+ reset_memblock_attributes ();
382
+ dummy_physical_memory_init ();
383
+
384
+ alloc_from_simple_check ();
385
+ alloc_from_misaligned_check ();
386
+ alloc_from_high_addr_check ();
387
+ alloc_from_no_space_above_check ();
388
+ alloc_from_min_addr_cap_check ();
222
389
223
390
dummy_physical_memory_cleanup ();
224
391
0 commit comments