@@ -209,16 +209,183 @@ static int alloc_from_top_down_min_addr_cap_check(void)
209209 return 0 ;
210210}
211211
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 )
213229{
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+ }
216252
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);
217334 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);
218342 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);
219352 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);
221362 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 ();
222389
223390 dummy_physical_memory_cleanup ();
224391
0 commit comments