Path: blob/master/tools/testing/memblock/tests/basic_api.c
25923 views
// SPDX-License-Identifier: GPL-2.0-or-later1#include "basic_api.h"2#include <string.h>3#include <linux/memblock.h>45#define EXPECTED_MEMBLOCK_REGIONS 1286#define FUNC_ADD "memblock_add"7#define FUNC_RESERVE "memblock_reserve"8#define FUNC_REMOVE "memblock_remove"9#define FUNC_FREE "memblock_free"10#define FUNC_TRIM "memblock_trim_memory"1112static int memblock_initialization_check(void)13{14PREFIX_PUSH();1516ASSERT_NE(memblock.memory.regions, NULL);17ASSERT_EQ(memblock.memory.cnt, 0);18ASSERT_EQ(memblock.memory.max, EXPECTED_MEMBLOCK_REGIONS);19ASSERT_EQ(strcmp(memblock.memory.name, "memory"), 0);2021ASSERT_NE(memblock.reserved.regions, NULL);22ASSERT_EQ(memblock.reserved.cnt, 0);23ASSERT_EQ(memblock.memory.max, EXPECTED_MEMBLOCK_REGIONS);24ASSERT_EQ(strcmp(memblock.reserved.name, "reserved"), 0);2526ASSERT_EQ(memblock.bottom_up, false);27ASSERT_EQ(memblock.current_limit, MEMBLOCK_ALLOC_ANYWHERE);2829test_pass_pop();3031return 0;32}3334/*35* A simple test that adds a memory block of a specified base address36* and size to the collection of available memory regions (memblock.memory).37* Expect to create a new entry. The region counter and total memory get38* updated.39*/40static int memblock_add_simple_check(void)41{42struct memblock_region *rgn;4344rgn = &memblock.memory.regions[0];4546struct region r = {47.base = SZ_1G,48.size = SZ_4M49};5051PREFIX_PUSH();5253reset_memblock_regions();54memblock_add(r.base, r.size);5556ASSERT_EQ(rgn->base, r.base);57ASSERT_EQ(rgn->size, r.size);5859ASSERT_EQ(memblock.memory.cnt, 1);60ASSERT_EQ(memblock.memory.total_size, r.size);6162test_pass_pop();6364return 0;65}6667/*68* A simple test that adds a memory block of a specified base address, size,69* NUMA node and memory flags to the collection of available memory regions.70* Expect to create a new entry. The region counter and total memory get71* updated.72*/73static int memblock_add_node_simple_check(void)74{75struct memblock_region *rgn;7677rgn = &memblock.memory.regions[0];7879struct region r = {80.base = SZ_1M,81.size = SZ_16M82};8384PREFIX_PUSH();8586reset_memblock_regions();87memblock_add_node(r.base, r.size, 1, MEMBLOCK_HOTPLUG);8889ASSERT_EQ(rgn->base, r.base);90ASSERT_EQ(rgn->size, r.size);91#ifdef CONFIG_NUMA92ASSERT_EQ(rgn->nid, 1);93#endif94ASSERT_EQ(rgn->flags, MEMBLOCK_HOTPLUG);9596ASSERT_EQ(memblock.memory.cnt, 1);97ASSERT_EQ(memblock.memory.total_size, r.size);9899test_pass_pop();100101return 0;102}103104/*105* A test that tries to add two memory blocks that don't overlap with one106* another:107*108* | +--------+ +--------+ |109* | | r1 | | r2 | |110* +--------+--------+--------+--------+--+111*112* Expect to add two correctly initialized entries to the collection of113* available memory regions (memblock.memory). The total size and114* region counter fields get updated.115*/116static int memblock_add_disjoint_check(void)117{118struct memblock_region *rgn1, *rgn2;119120rgn1 = &memblock.memory.regions[0];121rgn2 = &memblock.memory.regions[1];122123struct region r1 = {124.base = SZ_1G,125.size = SZ_8K126};127struct region r2 = {128.base = SZ_1G + SZ_16K,129.size = SZ_8K130};131132PREFIX_PUSH();133134reset_memblock_regions();135memblock_add(r1.base, r1.size);136memblock_add(r2.base, r2.size);137138ASSERT_EQ(rgn1->base, r1.base);139ASSERT_EQ(rgn1->size, r1.size);140141ASSERT_EQ(rgn2->base, r2.base);142ASSERT_EQ(rgn2->size, r2.size);143144ASSERT_EQ(memblock.memory.cnt, 2);145ASSERT_EQ(memblock.memory.total_size, r1.size + r2.size);146147test_pass_pop();148149return 0;150}151152/*153* A test that tries to add two memory blocks r1 and r2, where r2 overlaps154* with the beginning of r1 (that is r1.base < r2.base + r2.size):155*156* | +----+----+------------+ |157* | | |r2 | r1 | |158* +----+----+----+------------+----------+159* ^ ^160* | |161* | r1.base162* |163* r2.base164*165* Expect to merge the two entries into one region that starts at r2.base166* and has size of two regions minus their intersection. The total size of167* the available memory is updated, and the region counter stays the same.168*/169static int memblock_add_overlap_top_check(void)170{171struct memblock_region *rgn;172phys_addr_t total_size;173174rgn = &memblock.memory.regions[0];175176struct region r1 = {177.base = SZ_512M,178.size = SZ_1G179};180struct region r2 = {181.base = SZ_256M,182.size = SZ_512M183};184185PREFIX_PUSH();186187total_size = (r1.base - r2.base) + r1.size;188189reset_memblock_regions();190memblock_add(r1.base, r1.size);191memblock_add(r2.base, r2.size);192193ASSERT_EQ(rgn->base, r2.base);194ASSERT_EQ(rgn->size, total_size);195196ASSERT_EQ(memblock.memory.cnt, 1);197ASSERT_EQ(memblock.memory.total_size, total_size);198199test_pass_pop();200201return 0;202}203204/*205* A test that tries to add two memory blocks r1 and r2, where r2 overlaps206* with the end of r1 (that is r2.base < r1.base + r1.size):207*208* | +--+------+----------+ |209* | | | r1 | r2 | |210* +--+--+------+----------+--------------+211* ^ ^212* | |213* | r2.base214* |215* r1.base216*217* Expect to merge the two entries into one region that starts at r1.base218* and has size of two regions minus their intersection. The total size of219* the available memory is updated, and the region counter stays the same.220*/221static int memblock_add_overlap_bottom_check(void)222{223struct memblock_region *rgn;224phys_addr_t total_size;225226rgn = &memblock.memory.regions[0];227228struct region r1 = {229.base = SZ_128M,230.size = SZ_512M231};232struct region r2 = {233.base = SZ_256M,234.size = SZ_1G235};236237PREFIX_PUSH();238239total_size = (r2.base - r1.base) + r2.size;240241reset_memblock_regions();242memblock_add(r1.base, r1.size);243memblock_add(r2.base, r2.size);244245ASSERT_EQ(rgn->base, r1.base);246ASSERT_EQ(rgn->size, total_size);247248ASSERT_EQ(memblock.memory.cnt, 1);249ASSERT_EQ(memblock.memory.total_size, total_size);250251test_pass_pop();252253return 0;254}255256/*257* A test that tries to add two memory blocks r1 and r2, where r2 is258* within the range of r1 (that is r1.base < r2.base &&259* r2.base + r2.size < r1.base + r1.size):260*261* | +-------+--+-----------------------+262* | | |r2| r1 |263* +---+-------+--+-----------------------+264* ^265* |266* r1.base267*268* Expect to merge two entries into one region that stays the same.269* The counter and total size of available memory are not updated.270*/271static int memblock_add_within_check(void)272{273struct memblock_region *rgn;274275rgn = &memblock.memory.regions[0];276277struct region r1 = {278.base = SZ_8M,279.size = SZ_32M280};281struct region r2 = {282.base = SZ_16M,283.size = SZ_1M284};285286PREFIX_PUSH();287288reset_memblock_regions();289memblock_add(r1.base, r1.size);290memblock_add(r2.base, r2.size);291292ASSERT_EQ(rgn->base, r1.base);293ASSERT_EQ(rgn->size, r1.size);294295ASSERT_EQ(memblock.memory.cnt, 1);296ASSERT_EQ(memblock.memory.total_size, r1.size);297298test_pass_pop();299300return 0;301}302303/*304* A simple test that tries to add the same memory block twice. Expect305* the counter and total size of available memory to not be updated.306*/307static int memblock_add_twice_check(void)308{309struct region r = {310.base = SZ_16K,311.size = SZ_2M312};313314PREFIX_PUSH();315316reset_memblock_regions();317318memblock_add(r.base, r.size);319memblock_add(r.base, r.size);320321ASSERT_EQ(memblock.memory.cnt, 1);322ASSERT_EQ(memblock.memory.total_size, r.size);323324test_pass_pop();325326return 0;327}328329/*330* A test that tries to add two memory blocks that don't overlap with one331* another and then add a third memory block in the space between the first two:332*333* | +--------+--------+--------+ |334* | | r1 | r3 | r2 | |335* +--------+--------+--------+--------+--+336*337* Expect to merge the three entries into one region that starts at r1.base338* and has size of r1.size + r2.size + r3.size. The region counter and total339* size of the available memory are updated.340*/341static int memblock_add_between_check(void)342{343struct memblock_region *rgn;344phys_addr_t total_size;345346rgn = &memblock.memory.regions[0];347348struct region r1 = {349.base = SZ_1G,350.size = SZ_8K351};352struct region r2 = {353.base = SZ_1G + SZ_16K,354.size = SZ_8K355};356struct region r3 = {357.base = SZ_1G + SZ_8K,358.size = SZ_8K359};360361PREFIX_PUSH();362363total_size = r1.size + r2.size + r3.size;364365reset_memblock_regions();366memblock_add(r1.base, r1.size);367memblock_add(r2.base, r2.size);368memblock_add(r3.base, r3.size);369370ASSERT_EQ(rgn->base, r1.base);371ASSERT_EQ(rgn->size, total_size);372373ASSERT_EQ(memblock.memory.cnt, 1);374ASSERT_EQ(memblock.memory.total_size, total_size);375376test_pass_pop();377378return 0;379}380381/*382* A simple test that tries to add a memory block r when r extends past383* PHYS_ADDR_MAX:384*385* +--------+386* | r |387* +--------+388* | +----+389* | | rgn|390* +----------------------------+----+391*392* Expect to add a memory block of size PHYS_ADDR_MAX - r.base. Expect the393* total size of available memory and the counter to be updated.394*/395static int memblock_add_near_max_check(void)396{397struct memblock_region *rgn;398phys_addr_t total_size;399400rgn = &memblock.memory.regions[0];401402struct region r = {403.base = PHYS_ADDR_MAX - SZ_1M,404.size = SZ_2M405};406407PREFIX_PUSH();408409total_size = PHYS_ADDR_MAX - r.base;410411reset_memblock_regions();412memblock_add(r.base, r.size);413414ASSERT_EQ(rgn->base, r.base);415ASSERT_EQ(rgn->size, total_size);416417ASSERT_EQ(memblock.memory.cnt, 1);418ASSERT_EQ(memblock.memory.total_size, total_size);419420test_pass_pop();421422return 0;423}424425/*426* A test that trying to add the 129th memory block.427* Expect to trigger memblock_double_array() to double the428* memblock.memory.max, find a new valid memory as429* memory.regions.430*/431static int memblock_add_many_check(void)432{433int i;434void *orig_region;435struct region r = {436.base = SZ_16K,437.size = SZ_16K,438};439phys_addr_t new_memory_regions_size;440phys_addr_t base, size = SZ_64;441phys_addr_t gap_size = SZ_64;442443PREFIX_PUSH();444445reset_memblock_regions();446memblock_allow_resize();447448dummy_physical_memory_init();449/*450* We allocated enough memory by using dummy_physical_memory_init(), and451* split it into small block. First we split a large enough memory block452* as the memory region which will be choosed by memblock_double_array().453*/454base = PAGE_ALIGN(dummy_physical_memory_base());455new_memory_regions_size = PAGE_ALIGN(INIT_MEMBLOCK_REGIONS * 2 *456sizeof(struct memblock_region));457memblock_add(base, new_memory_regions_size);458459/* This is the base of small memory block. */460base += new_memory_regions_size + gap_size;461462orig_region = memblock.memory.regions;463464for (i = 0; i < INIT_MEMBLOCK_REGIONS; i++) {465/*466* Add these small block to fulfill the memblock. We keep a467* gap between the nearby memory to avoid being merged.468*/469memblock_add(base, size);470base += size + gap_size;471472ASSERT_EQ(memblock.memory.cnt, i + 2);473ASSERT_EQ(memblock.memory.total_size, new_memory_regions_size +474(i + 1) * size);475}476477/*478* At there, memblock_double_array() has been succeed, check if it479* update the memory.max.480*/481ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2);482483/* memblock_double_array() will reserve the memory it used. Check it. */484ASSERT_EQ(memblock.reserved.cnt, 1);485ASSERT_EQ(memblock.reserved.total_size, new_memory_regions_size);486487/*488* Now memblock_double_array() works fine. Let's check after the489* double_array(), the memblock_add() still works as normal.490*/491memblock_add(r.base, r.size);492ASSERT_EQ(memblock.memory.regions[0].base, r.base);493ASSERT_EQ(memblock.memory.regions[0].size, r.size);494495ASSERT_EQ(memblock.memory.cnt, INIT_MEMBLOCK_REGIONS + 2);496ASSERT_EQ(memblock.memory.total_size, INIT_MEMBLOCK_REGIONS * size +497new_memory_regions_size +498r.size);499ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2);500501dummy_physical_memory_cleanup();502503/*504* The current memory.regions is occupying a range of memory that505* allocated from dummy_physical_memory_init(). After free the memory,506* we must not use it. So restore the origin memory region to make sure507* the tests can run as normal and not affected by the double array.508*/509memblock.memory.regions = orig_region;510memblock.memory.cnt = INIT_MEMBLOCK_REGIONS;511512test_pass_pop();513514return 0;515}516517static int memblock_add_checks(void)518{519prefix_reset();520prefix_push(FUNC_ADD);521test_print("Running %s tests...\n", FUNC_ADD);522523memblock_add_simple_check();524memblock_add_node_simple_check();525memblock_add_disjoint_check();526memblock_add_overlap_top_check();527memblock_add_overlap_bottom_check();528memblock_add_within_check();529memblock_add_twice_check();530memblock_add_between_check();531memblock_add_near_max_check();532memblock_add_many_check();533534prefix_pop();535536return 0;537}538539/*540* A simple test that marks a memory block of a specified base address541* and size as reserved and to the collection of reserved memory regions542* (memblock.reserved). Expect to create a new entry. The region counter543* and total memory size are updated.544*/545static int memblock_reserve_simple_check(void)546{547struct memblock_region *rgn;548549rgn = &memblock.reserved.regions[0];550551struct region r = {552.base = SZ_2G,553.size = SZ_128M554};555556PREFIX_PUSH();557558reset_memblock_regions();559memblock_reserve(r.base, r.size);560561ASSERT_EQ(rgn->base, r.base);562ASSERT_EQ(rgn->size, r.size);563564test_pass_pop();565566return 0;567}568569/*570* A test that tries to mark two memory blocks that don't overlap as reserved:571*572* | +--+ +----------------+ |573* | |r1| | r2 | |574* +--------+--+------+----------------+--+575*576* Expect to add two entries to the collection of reserved memory regions577* (memblock.reserved). The total size and region counter for578* memblock.reserved are updated.579*/580static int memblock_reserve_disjoint_check(void)581{582struct memblock_region *rgn1, *rgn2;583584rgn1 = &memblock.reserved.regions[0];585rgn2 = &memblock.reserved.regions[1];586587struct region r1 = {588.base = SZ_256M,589.size = SZ_16M590};591struct region r2 = {592.base = SZ_512M,593.size = SZ_512M594};595596PREFIX_PUSH();597598reset_memblock_regions();599memblock_reserve(r1.base, r1.size);600memblock_reserve(r2.base, r2.size);601602ASSERT_EQ(rgn1->base, r1.base);603ASSERT_EQ(rgn1->size, r1.size);604605ASSERT_EQ(rgn2->base, r2.base);606ASSERT_EQ(rgn2->size, r2.size);607608ASSERT_EQ(memblock.reserved.cnt, 2);609ASSERT_EQ(memblock.reserved.total_size, r1.size + r2.size);610611test_pass_pop();612613return 0;614}615616/*617* A test that tries to mark two memory blocks r1 and r2 as reserved,618* where r2 overlaps with the beginning of r1 (that is619* r1.base < r2.base + r2.size):620*621* | +--------------+--+--------------+ |622* | | r2 | | r1 | |623* +--+--------------+--+--------------+--+624* ^ ^625* | |626* | r1.base627* |628* r2.base629*630* Expect to merge two entries into one region that starts at r2.base and631* has size of two regions minus their intersection. The total size of the632* reserved memory is updated, and the region counter is not updated.633*/634static int memblock_reserve_overlap_top_check(void)635{636struct memblock_region *rgn;637phys_addr_t total_size;638639rgn = &memblock.reserved.regions[0];640641struct region r1 = {642.base = SZ_1G,643.size = SZ_1G644};645struct region r2 = {646.base = SZ_128M,647.size = SZ_1G648};649650PREFIX_PUSH();651652total_size = (r1.base - r2.base) + r1.size;653654reset_memblock_regions();655memblock_reserve(r1.base, r1.size);656memblock_reserve(r2.base, r2.size);657658ASSERT_EQ(rgn->base, r2.base);659ASSERT_EQ(rgn->size, total_size);660661ASSERT_EQ(memblock.reserved.cnt, 1);662ASSERT_EQ(memblock.reserved.total_size, total_size);663664test_pass_pop();665666return 0;667}668669/*670* A test that tries to mark two memory blocks r1 and r2 as reserved,671* where r2 overlaps with the end of r1 (that is672* r2.base < r1.base + r1.size):673*674* | +--------------+--+--------------+ |675* | | r1 | | r2 | |676* +--+--------------+--+--------------+--+677* ^ ^678* | |679* | r2.base680* |681* r1.base682*683* Expect to merge two entries into one region that starts at r1.base and684* has size of two regions minus their intersection. The total size of the685* reserved memory is updated, and the region counter is not updated.686*/687static int memblock_reserve_overlap_bottom_check(void)688{689struct memblock_region *rgn;690phys_addr_t total_size;691692rgn = &memblock.reserved.regions[0];693694struct region r1 = {695.base = SZ_2K,696.size = SZ_128K697};698struct region r2 = {699.base = SZ_128K,700.size = SZ_128K701};702703PREFIX_PUSH();704705total_size = (r2.base - r1.base) + r2.size;706707reset_memblock_regions();708memblock_reserve(r1.base, r1.size);709memblock_reserve(r2.base, r2.size);710711ASSERT_EQ(rgn->base, r1.base);712ASSERT_EQ(rgn->size, total_size);713714ASSERT_EQ(memblock.reserved.cnt, 1);715ASSERT_EQ(memblock.reserved.total_size, total_size);716717test_pass_pop();718719return 0;720}721722/*723* A test that tries to mark two memory blocks r1 and r2 as reserved,724* where r2 is within the range of r1 (that is725* (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):726*727* | +-----+--+---------------------------|728* | | |r2| r1 |729* +-+-----+--+---------------------------+730* ^ ^731* | |732* | r2.base733* |734* r1.base735*736* Expect to merge two entries into one region that stays the same. The737* counter and total size of available memory are not updated.738*/739static int memblock_reserve_within_check(void)740{741struct memblock_region *rgn;742743rgn = &memblock.reserved.regions[0];744745struct region r1 = {746.base = SZ_1M,747.size = SZ_8M748};749struct region r2 = {750.base = SZ_2M,751.size = SZ_64K752};753754PREFIX_PUSH();755756reset_memblock_regions();757memblock_reserve(r1.base, r1.size);758memblock_reserve(r2.base, r2.size);759760ASSERT_EQ(rgn->base, r1.base);761ASSERT_EQ(rgn->size, r1.size);762763ASSERT_EQ(memblock.reserved.cnt, 1);764ASSERT_EQ(memblock.reserved.total_size, r1.size);765766test_pass_pop();767768return 0;769}770771/*772* A simple test that tries to reserve the same memory block twice.773* Expect the region counter and total size of reserved memory to not774* be updated.775*/776static int memblock_reserve_twice_check(void)777{778struct region r = {779.base = SZ_16K,780.size = SZ_2M781};782783PREFIX_PUSH();784785reset_memblock_regions();786787memblock_reserve(r.base, r.size);788memblock_reserve(r.base, r.size);789790ASSERT_EQ(memblock.reserved.cnt, 1);791ASSERT_EQ(memblock.reserved.total_size, r.size);792793test_pass_pop();794795return 0;796}797798/*799* A test that tries to mark two memory blocks that don't overlap as reserved800* and then reserve a third memory block in the space between the first two:801*802* | +--------+--------+--------+ |803* | | r1 | r3 | r2 | |804* +--------+--------+--------+--------+--+805*806* Expect to merge the three entries into one reserved region that starts at807* r1.base and has size of r1.size + r2.size + r3.size. The region counter and808* total for memblock.reserved are updated.809*/810static int memblock_reserve_between_check(void)811{812struct memblock_region *rgn;813phys_addr_t total_size;814815rgn = &memblock.reserved.regions[0];816817struct region r1 = {818.base = SZ_1G,819.size = SZ_8K820};821struct region r2 = {822.base = SZ_1G + SZ_16K,823.size = SZ_8K824};825struct region r3 = {826.base = SZ_1G + SZ_8K,827.size = SZ_8K828};829830PREFIX_PUSH();831832total_size = r1.size + r2.size + r3.size;833834reset_memblock_regions();835memblock_reserve(r1.base, r1.size);836memblock_reserve(r2.base, r2.size);837memblock_reserve(r3.base, r3.size);838839ASSERT_EQ(rgn->base, r1.base);840ASSERT_EQ(rgn->size, total_size);841842ASSERT_EQ(memblock.reserved.cnt, 1);843ASSERT_EQ(memblock.reserved.total_size, total_size);844845test_pass_pop();846847return 0;848}849850/*851* A simple test that tries to reserve a memory block r when r extends past852* PHYS_ADDR_MAX:853*854* +--------+855* | r |856* +--------+857* | +----+858* | | rgn|859* +----------------------------+----+860*861* Expect to reserve a memory block of size PHYS_ADDR_MAX - r.base. Expect the862* total size of reserved memory and the counter to be updated.863*/864static int memblock_reserve_near_max_check(void)865{866struct memblock_region *rgn;867phys_addr_t total_size;868869rgn = &memblock.reserved.regions[0];870871struct region r = {872.base = PHYS_ADDR_MAX - SZ_1M,873.size = SZ_2M874};875876PREFIX_PUSH();877878total_size = PHYS_ADDR_MAX - r.base;879880reset_memblock_regions();881memblock_reserve(r.base, r.size);882883ASSERT_EQ(rgn->base, r.base);884ASSERT_EQ(rgn->size, total_size);885886ASSERT_EQ(memblock.reserved.cnt, 1);887ASSERT_EQ(memblock.reserved.total_size, total_size);888889test_pass_pop();890891return 0;892}893894/*895* A test that trying to reserve the 129th memory block.896* Expect to trigger memblock_double_array() to double the897* memblock.memory.max, find a new valid memory as898* reserved.regions.899*/900static int memblock_reserve_many_check(void)901{902int i;903void *orig_region;904struct region r = {905.base = SZ_16K,906.size = SZ_16K,907};908phys_addr_t memory_base = SZ_128K;909phys_addr_t new_reserved_regions_size;910911PREFIX_PUSH();912913reset_memblock_regions();914memblock_allow_resize();915916/* Add a valid memory region used by double_array(). */917dummy_physical_memory_init();918memblock_add(dummy_physical_memory_base(), MEM_SIZE);919920for (i = 0; i < INIT_MEMBLOCK_REGIONS; i++) {921/* Reserve some fakes memory region to fulfill the memblock. */922memblock_reserve(memory_base, MEM_SIZE);923924ASSERT_EQ(memblock.reserved.cnt, i + 1);925ASSERT_EQ(memblock.reserved.total_size, (i + 1) * MEM_SIZE);926927/* Keep the gap so these memory region will not be merged. */928memory_base += MEM_SIZE * 2;929}930931orig_region = memblock.reserved.regions;932933/* This reserve the 129 memory_region, and makes it double array. */934memblock_reserve(memory_base, MEM_SIZE);935936/*937* This is the memory region size used by the doubled reserved.regions,938* and it has been reserved due to it has been used. The size is used to939* calculate the total_size that the memblock.reserved have now.940*/941new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) *942sizeof(struct memblock_region));943/*944* The double_array() will find a free memory region as the new945* reserved.regions, and the used memory region will be reserved, so946* there will be one more region exist in the reserved memblock. And the947* one more reserved region's size is new_reserved_regions_size.948*/949ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2);950ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +951new_reserved_regions_size);952ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);953954/*955* Now memblock_double_array() works fine. Let's check after the956* double_array(), the memblock_reserve() still works as normal.957*/958memblock_reserve(r.base, r.size);959ASSERT_EQ(memblock.reserved.regions[0].base, r.base);960ASSERT_EQ(memblock.reserved.regions[0].size, r.size);961962ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3);963ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +964new_reserved_regions_size +965r.size);966ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);967968dummy_physical_memory_cleanup();969970/*971* The current reserved.regions is occupying a range of memory that972* allocated from dummy_physical_memory_init(). After free the memory,973* we must not use it. So restore the origin memory region to make sure974* the tests can run as normal and not affected by the double array.975*/976memblock.reserved.regions = orig_region;977memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;978979test_pass_pop();980981return 0;982}983984985/*986* A test that trying to reserve the 129th memory block at all locations.987* Expect to trigger memblock_double_array() to double the988* memblock.memory.max, find a new valid memory as reserved.regions.989*990* 0 1 2 128991* +-------+ +-------+ +-------+ +-------+992* | 32K | | 32K | | 32K | ... | 32K |993* +-------+-------+-------+-------+-------+ +-------+994* |<-32K->| |<-32K->|995*996*/997/* Keep the gap so these memory region will not be merged. */998#define MEMORY_BASE(idx) (SZ_128K + (MEM_SIZE * 2) * (idx))999static int memblock_reserve_all_locations_check(void)1000{1001int i, skip;1002void *orig_region;1003struct region r = {1004.base = SZ_16K,1005.size = SZ_16K,1006};1007phys_addr_t new_reserved_regions_size;10081009PREFIX_PUSH();10101011/* Reserve the 129th memory block for all possible positions*/1012for (skip = 0; skip < INIT_MEMBLOCK_REGIONS + 1; skip++) {1013reset_memblock_regions();1014memblock_allow_resize();10151016/* Add a valid memory region used by double_array(). */1017dummy_physical_memory_init();1018memblock_add(dummy_physical_memory_base(), MEM_SIZE);10191020for (i = 0; i < INIT_MEMBLOCK_REGIONS + 1; i++) {1021if (i == skip)1022continue;10231024/* Reserve some fakes memory region to fulfill the memblock. */1025memblock_reserve(MEMORY_BASE(i), MEM_SIZE);10261027if (i < skip) {1028ASSERT_EQ(memblock.reserved.cnt, i + 1);1029ASSERT_EQ(memblock.reserved.total_size, (i + 1) * MEM_SIZE);1030} else {1031ASSERT_EQ(memblock.reserved.cnt, i);1032ASSERT_EQ(memblock.reserved.total_size, i * MEM_SIZE);1033}1034}10351036orig_region = memblock.reserved.regions;10371038/* This reserve the 129 memory_region, and makes it double array. */1039memblock_reserve(MEMORY_BASE(skip), MEM_SIZE);10401041/*1042* This is the memory region size used by the doubled reserved.regions,1043* and it has been reserved due to it has been used. The size is used to1044* calculate the total_size that the memblock.reserved have now.1045*/1046new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) *1047sizeof(struct memblock_region));1048/*1049* The double_array() will find a free memory region as the new1050* reserved.regions, and the used memory region will be reserved, so1051* there will be one more region exist in the reserved memblock. And the1052* one more reserved region's size is new_reserved_regions_size.1053*/1054ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2);1055ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +1056new_reserved_regions_size);1057ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);10581059/*1060* Now memblock_double_array() works fine. Let's check after the1061* double_array(), the memblock_reserve() still works as normal.1062*/1063memblock_reserve(r.base, r.size);1064ASSERT_EQ(memblock.reserved.regions[0].base, r.base);1065ASSERT_EQ(memblock.reserved.regions[0].size, r.size);10661067ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3);1068ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +1069new_reserved_regions_size +1070r.size);1071ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);10721073dummy_physical_memory_cleanup();10741075/*1076* The current reserved.regions is occupying a range of memory that1077* allocated from dummy_physical_memory_init(). After free the memory,1078* we must not use it. So restore the origin memory region to make sure1079* the tests can run as normal and not affected by the double array.1080*/1081memblock.reserved.regions = orig_region;1082memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;1083}10841085test_pass_pop();10861087return 0;1088}10891090/*1091* A test that trying to reserve the 129th memory block at all locations.1092* Expect to trigger memblock_double_array() to double the1093* memblock.memory.max, find a new valid memory as reserved.regions. And make1094* sure it doesn't conflict with the range we want to reserve.1095*1096* For example, we have 128 regions in reserved and now want to reserve1097* the skipped one. Since reserved is full, memblock_double_array() would find1098* an available range in memory for the new array. We intended to put two1099* ranges in memory with one is the exact range of the skipped one. Before1100* commit 48c3b583bbdd ("mm/memblock: fix overlapping allocation when doubling1101* reserved array"), the new array would sits in the skipped range which is a1102* conflict. The expected new array should be allocated from memory.regions[0].1103*1104* 0 11105* memory +-------+ +-------+1106* | 32K | | 32K |1107* +-------+ ------+-------+-------+-------+1108* |<-32K->|<-32K->|<-32K->|1109*1110* 0 skipped 1271111* reserved +-------+ ......... +-------+1112* | 32K | . 32K . ... | 32K |1113* +-------+-------+-------+ +-------+1114* |<-32K->|1115* ^1116* |1117* |1118* skipped one1119*/1120/* Keep the gap so these memory region will not be merged. */1121#define MEMORY_BASE_OFFSET(idx, offset) ((offset) + (MEM_SIZE * 2) * (idx))1122static int memblock_reserve_many_may_conflict_check(void)1123{1124int i, skip;1125void *orig_region;1126struct region r = {1127.base = SZ_16K,1128.size = SZ_16K,1129};1130phys_addr_t new_reserved_regions_size;11311132/*1133* 0 1 1291134* +---+ +---+ +---+1135* |32K| |32K| .. |32K|1136* +---+ +---+ +---+1137*1138* Pre-allocate the range for 129 memory block + one range for double1139* memblock.reserved.regions at idx 0.1140*/1141dummy_physical_memory_init();1142phys_addr_t memory_base = dummy_physical_memory_base();1143phys_addr_t offset = PAGE_ALIGN(memory_base);11441145PREFIX_PUSH();11461147/* Reserve the 129th memory block for all possible positions*/1148for (skip = 1; skip <= INIT_MEMBLOCK_REGIONS + 1; skip++) {1149reset_memblock_regions();1150memblock_allow_resize();11511152reset_memblock_attributes();1153/* Add a valid memory region used by double_array(). */1154memblock_add(MEMORY_BASE_OFFSET(0, offset), MEM_SIZE);1155/*1156* Add a memory region which will be reserved as 129th memory1157* region. This is not expected to be used by double_array().1158*/1159memblock_add(MEMORY_BASE_OFFSET(skip, offset), MEM_SIZE);11601161for (i = 1; i <= INIT_MEMBLOCK_REGIONS + 1; i++) {1162if (i == skip)1163continue;11641165/* Reserve some fakes memory region to fulfill the memblock. */1166memblock_reserve(MEMORY_BASE_OFFSET(i, offset), MEM_SIZE);11671168if (i < skip) {1169ASSERT_EQ(memblock.reserved.cnt, i);1170ASSERT_EQ(memblock.reserved.total_size, i * MEM_SIZE);1171} else {1172ASSERT_EQ(memblock.reserved.cnt, i - 1);1173ASSERT_EQ(memblock.reserved.total_size, (i - 1) * MEM_SIZE);1174}1175}11761177orig_region = memblock.reserved.regions;11781179/* This reserve the 129 memory_region, and makes it double array. */1180memblock_reserve(MEMORY_BASE_OFFSET(skip, offset), MEM_SIZE);11811182/*1183* This is the memory region size used by the doubled reserved.regions,1184* and it has been reserved due to it has been used. The size is used to1185* calculate the total_size that the memblock.reserved have now.1186*/1187new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) *1188sizeof(struct memblock_region));1189/*1190* The double_array() will find a free memory region as the new1191* reserved.regions, and the used memory region will be reserved, so1192* there will be one more region exist in the reserved memblock. And the1193* one more reserved region's size is new_reserved_regions_size.1194*/1195ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2);1196ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +1197new_reserved_regions_size);1198ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);11991200/*1201* The first reserved region is allocated for double array1202* with the size of new_reserved_regions_size and the base to be1203* MEMORY_BASE_OFFSET(0, offset) + SZ_32K - new_reserved_regions_size1204*/1205ASSERT_EQ(memblock.reserved.regions[0].base + memblock.reserved.regions[0].size,1206MEMORY_BASE_OFFSET(0, offset) + SZ_32K);1207ASSERT_EQ(memblock.reserved.regions[0].size, new_reserved_regions_size);12081209/*1210* Now memblock_double_array() works fine. Let's check after the1211* double_array(), the memblock_reserve() still works as normal.1212*/1213memblock_reserve(r.base, r.size);1214ASSERT_EQ(memblock.reserved.regions[0].base, r.base);1215ASSERT_EQ(memblock.reserved.regions[0].size, r.size);12161217ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3);1218ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +1219new_reserved_regions_size +1220r.size);1221ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);12221223/*1224* The current reserved.regions is occupying a range of memory that1225* allocated from dummy_physical_memory_init(). After free the memory,1226* we must not use it. So restore the origin memory region to make sure1227* the tests can run as normal and not affected by the double array.1228*/1229memblock.reserved.regions = orig_region;1230memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;1231}12321233dummy_physical_memory_cleanup();12341235test_pass_pop();12361237return 0;1238}12391240static int memblock_reserve_checks(void)1241{1242prefix_reset();1243prefix_push(FUNC_RESERVE);1244test_print("Running %s tests...\n", FUNC_RESERVE);12451246memblock_reserve_simple_check();1247memblock_reserve_disjoint_check();1248memblock_reserve_overlap_top_check();1249memblock_reserve_overlap_bottom_check();1250memblock_reserve_within_check();1251memblock_reserve_twice_check();1252memblock_reserve_between_check();1253memblock_reserve_near_max_check();1254memblock_reserve_many_check();1255memblock_reserve_all_locations_check();1256memblock_reserve_many_may_conflict_check();12571258prefix_pop();12591260return 0;1261}12621263/*1264* A simple test that tries to remove a region r1 from the array of1265* available memory regions. By "removing" a region we mean overwriting it1266* with the next region r2 in memblock.memory:1267*1268* | ...... +----------------+ |1269* | : r1 : | r2 | |1270* +--+----+----------+----------------+--+1271* ^1272* |1273* rgn.base1274*1275* Expect to add two memory blocks r1 and r2 and then remove r1 so that1276* r2 is the first available region. The region counter and total size1277* are updated.1278*/1279static int memblock_remove_simple_check(void)1280{1281struct memblock_region *rgn;12821283rgn = &memblock.memory.regions[0];12841285struct region r1 = {1286.base = SZ_2K,1287.size = SZ_4K1288};1289struct region r2 = {1290.base = SZ_128K,1291.size = SZ_4M1292};12931294PREFIX_PUSH();12951296reset_memblock_regions();1297memblock_add(r1.base, r1.size);1298memblock_add(r2.base, r2.size);1299memblock_remove(r1.base, r1.size);13001301ASSERT_EQ(rgn->base, r2.base);1302ASSERT_EQ(rgn->size, r2.size);13031304ASSERT_EQ(memblock.memory.cnt, 1);1305ASSERT_EQ(memblock.memory.total_size, r2.size);13061307test_pass_pop();13081309return 0;1310}13111312/*1313* A test that tries to remove a region r2 that was not registered as1314* available memory (i.e. has no corresponding entry in memblock.memory):1315*1316* +----------------+1317* | r2 |1318* +----------------+1319* | +----+ |1320* | | r1 | |1321* +--+----+------------------------------+1322* ^1323* |1324* rgn.base1325*1326* Expect the array, regions counter and total size to not be modified.1327*/1328static int memblock_remove_absent_check(void)1329{1330struct memblock_region *rgn;13311332rgn = &memblock.memory.regions[0];13331334struct region r1 = {1335.base = SZ_512K,1336.size = SZ_4M1337};1338struct region r2 = {1339.base = SZ_64M,1340.size = SZ_1G1341};13421343PREFIX_PUSH();13441345reset_memblock_regions();1346memblock_add(r1.base, r1.size);1347memblock_remove(r2.base, r2.size);13481349ASSERT_EQ(rgn->base, r1.base);1350ASSERT_EQ(rgn->size, r1.size);13511352ASSERT_EQ(memblock.memory.cnt, 1);1353ASSERT_EQ(memblock.memory.total_size, r1.size);13541355test_pass_pop();13561357return 0;1358}13591360/*1361* A test that tries to remove a region r2 that overlaps with the1362* beginning of the already existing entry r11363* (that is r1.base < r2.base + r2.size):1364*1365* +-----------------+1366* | r2 |1367* +-----------------+1368* | .........+--------+ |1369* | : r1 | rgn | |1370* +-----------------+--------+--------+--+1371* ^ ^1372* | |1373* | rgn.base1374* r1.base1375*1376* Expect that only the intersection of both regions is removed from the1377* available memory pool. The regions counter and total size are updated.1378*/1379static int memblock_remove_overlap_top_check(void)1380{1381struct memblock_region *rgn;1382phys_addr_t r1_end, r2_end, total_size;13831384rgn = &memblock.memory.regions[0];13851386struct region r1 = {1387.base = SZ_32M,1388.size = SZ_32M1389};1390struct region r2 = {1391.base = SZ_16M,1392.size = SZ_32M1393};13941395PREFIX_PUSH();13961397r1_end = r1.base + r1.size;1398r2_end = r2.base + r2.size;1399total_size = r1_end - r2_end;14001401reset_memblock_regions();1402memblock_add(r1.base, r1.size);1403memblock_remove(r2.base, r2.size);14041405ASSERT_EQ(rgn->base, r1.base + r2.base);1406ASSERT_EQ(rgn->size, total_size);14071408ASSERT_EQ(memblock.memory.cnt, 1);1409ASSERT_EQ(memblock.memory.total_size, total_size);14101411test_pass_pop();14121413return 0;1414}14151416/*1417* A test that tries to remove a region r2 that overlaps with the end of1418* the already existing region r1 (that is r2.base < r1.base + r1.size):1419*1420* +--------------------------------+1421* | r2 |1422* +--------------------------------+1423* | +---+..... |1424* | |rgn| r1 : |1425* +-+---+----+---------------------------+1426* ^1427* |1428* r1.base1429*1430* Expect that only the intersection of both regions is removed from the1431* available memory pool. The regions counter and total size are updated.1432*/1433static int memblock_remove_overlap_bottom_check(void)1434{1435struct memblock_region *rgn;1436phys_addr_t total_size;14371438rgn = &memblock.memory.regions[0];14391440struct region r1 = {1441.base = SZ_2M,1442.size = SZ_64M1443};1444struct region r2 = {1445.base = SZ_32M,1446.size = SZ_256M1447};14481449PREFIX_PUSH();14501451total_size = r2.base - r1.base;14521453reset_memblock_regions();1454memblock_add(r1.base, r1.size);1455memblock_remove(r2.base, r2.size);14561457ASSERT_EQ(rgn->base, r1.base);1458ASSERT_EQ(rgn->size, total_size);14591460ASSERT_EQ(memblock.memory.cnt, 1);1461ASSERT_EQ(memblock.memory.total_size, total_size);14621463test_pass_pop();14641465return 0;1466}14671468/*1469* A test that tries to remove a region r2 that is within the range of1470* the already existing entry r1 (that is1471* (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):1472*1473* +----+1474* | r2 |1475* +----+1476* | +-------------+....+---------------+ |1477* | | rgn1 | r1 | rgn2 | |1478* +-+-------------+----+---------------+-+1479* ^1480* |1481* r1.base1482*1483* Expect that the region is split into two - one that ends at r2.base and1484* another that starts at r2.base + r2.size, with appropriate sizes. The1485* region counter and total size are updated.1486*/1487static int memblock_remove_within_check(void)1488{1489struct memblock_region *rgn1, *rgn2;1490phys_addr_t r1_size, r2_size, total_size;14911492rgn1 = &memblock.memory.regions[0];1493rgn2 = &memblock.memory.regions[1];14941495struct region r1 = {1496.base = SZ_1M,1497.size = SZ_32M1498};1499struct region r2 = {1500.base = SZ_16M,1501.size = SZ_1M1502};15031504PREFIX_PUSH();15051506r1_size = r2.base - r1.base;1507r2_size = (r1.base + r1.size) - (r2.base + r2.size);1508total_size = r1_size + r2_size;15091510reset_memblock_regions();1511memblock_add(r1.base, r1.size);1512memblock_remove(r2.base, r2.size);15131514ASSERT_EQ(rgn1->base, r1.base);1515ASSERT_EQ(rgn1->size, r1_size);15161517ASSERT_EQ(rgn2->base, r2.base + r2.size);1518ASSERT_EQ(rgn2->size, r2_size);15191520ASSERT_EQ(memblock.memory.cnt, 2);1521ASSERT_EQ(memblock.memory.total_size, total_size);15221523test_pass_pop();15241525return 0;1526}15271528/*1529* A simple test that tries to remove a region r1 from the array of1530* available memory regions when r1 is the only available region.1531* Expect to add a memory block r1 and then remove r1 so that a dummy1532* region is added. The region counter stays the same, and the total size1533* is updated.1534*/1535static int memblock_remove_only_region_check(void)1536{1537struct memblock_region *rgn;15381539rgn = &memblock.memory.regions[0];15401541struct region r1 = {1542.base = SZ_2K,1543.size = SZ_4K1544};15451546PREFIX_PUSH();15471548reset_memblock_regions();1549memblock_add(r1.base, r1.size);1550memblock_remove(r1.base, r1.size);15511552ASSERT_EQ(rgn->base, 0);1553ASSERT_EQ(rgn->size, 0);15541555ASSERT_EQ(memblock.memory.cnt, 0);1556ASSERT_EQ(memblock.memory.total_size, 0);15571558test_pass_pop();15591560return 0;1561}15621563/*1564* A simple test that tries remove a region r2 from the array of available1565* memory regions when r2 extends past PHYS_ADDR_MAX:1566*1567* +--------+1568* | r2 |1569* +--------+1570* | +---+....+1571* | |rgn| |1572* +------------------------+---+----+1573*1574* Expect that only the portion between PHYS_ADDR_MAX and r2.base is removed.1575* Expect the total size of available memory to be updated and the counter to1576* not be updated.1577*/1578static int memblock_remove_near_max_check(void)1579{1580struct memblock_region *rgn;1581phys_addr_t total_size;15821583rgn = &memblock.memory.regions[0];15841585struct region r1 = {1586.base = PHYS_ADDR_MAX - SZ_2M,1587.size = SZ_2M1588};15891590struct region r2 = {1591.base = PHYS_ADDR_MAX - SZ_1M,1592.size = SZ_2M1593};15941595PREFIX_PUSH();15961597total_size = r1.size - (PHYS_ADDR_MAX - r2.base);15981599reset_memblock_regions();1600memblock_add(r1.base, r1.size);1601memblock_remove(r2.base, r2.size);16021603ASSERT_EQ(rgn->base, r1.base);1604ASSERT_EQ(rgn->size, total_size);16051606ASSERT_EQ(memblock.memory.cnt, 1);1607ASSERT_EQ(memblock.memory.total_size, total_size);16081609test_pass_pop();16101611return 0;1612}16131614/*1615* A test that tries to remove a region r3 that overlaps with two existing1616* regions r1 and r2:1617*1618* +----------------+1619* | r3 |1620* +----------------+1621* | +----+..... ........+--------+1622* | | |r1 : : |r2 | |1623* +----+----+----+---+-------+--------+-----+1624*1625* Expect that only the intersections of r1 with r3 and r2 with r3 are removed1626* from the available memory pool. Expect the total size of available memory to1627* be updated and the counter to not be updated.1628*/1629static int memblock_remove_overlap_two_check(void)1630{1631struct memblock_region *rgn1, *rgn2;1632phys_addr_t new_r1_size, new_r2_size, r2_end, r3_end, total_size;16331634rgn1 = &memblock.memory.regions[0];1635rgn2 = &memblock.memory.regions[1];16361637struct region r1 = {1638.base = SZ_16M,1639.size = SZ_32M1640};1641struct region r2 = {1642.base = SZ_64M,1643.size = SZ_64M1644};1645struct region r3 = {1646.base = SZ_32M,1647.size = SZ_64M1648};16491650PREFIX_PUSH();16511652r2_end = r2.base + r2.size;1653r3_end = r3.base + r3.size;1654new_r1_size = r3.base - r1.base;1655new_r2_size = r2_end - r3_end;1656total_size = new_r1_size + new_r2_size;16571658reset_memblock_regions();1659memblock_add(r1.base, r1.size);1660memblock_add(r2.base, r2.size);1661memblock_remove(r3.base, r3.size);16621663ASSERT_EQ(rgn1->base, r1.base);1664ASSERT_EQ(rgn1->size, new_r1_size);16651666ASSERT_EQ(rgn2->base, r3_end);1667ASSERT_EQ(rgn2->size, new_r2_size);16681669ASSERT_EQ(memblock.memory.cnt, 2);1670ASSERT_EQ(memblock.memory.total_size, total_size);16711672test_pass_pop();16731674return 0;1675}16761677static int memblock_remove_checks(void)1678{1679prefix_reset();1680prefix_push(FUNC_REMOVE);1681test_print("Running %s tests...\n", FUNC_REMOVE);16821683memblock_remove_simple_check();1684memblock_remove_absent_check();1685memblock_remove_overlap_top_check();1686memblock_remove_overlap_bottom_check();1687memblock_remove_within_check();1688memblock_remove_only_region_check();1689memblock_remove_near_max_check();1690memblock_remove_overlap_two_check();16911692prefix_pop();16931694return 0;1695}16961697/*1698* A simple test that tries to free a memory block r1 that was marked1699* earlier as reserved. By "freeing" a region we mean overwriting it with1700* the next entry r2 in memblock.reserved:1701*1702* | ...... +----+ |1703* | : r1 : | r2 | |1704* +--------------+----+-----------+----+-+1705* ^1706* |1707* rgn.base1708*1709* Expect to reserve two memory regions and then erase r1 region with the1710* value of r2. The region counter and total size are updated.1711*/1712static int memblock_free_simple_check(void)1713{1714struct memblock_region *rgn;17151716rgn = &memblock.reserved.regions[0];17171718struct region r1 = {1719.base = SZ_4M,1720.size = SZ_1M1721};1722struct region r2 = {1723.base = SZ_8M,1724.size = SZ_1M1725};17261727PREFIX_PUSH();17281729reset_memblock_regions();1730memblock_reserve(r1.base, r1.size);1731memblock_reserve(r2.base, r2.size);1732memblock_free((void *)r1.base, r1.size);17331734ASSERT_EQ(rgn->base, r2.base);1735ASSERT_EQ(rgn->size, r2.size);17361737ASSERT_EQ(memblock.reserved.cnt, 1);1738ASSERT_EQ(memblock.reserved.total_size, r2.size);17391740test_pass_pop();17411742return 0;1743}17441745/*1746* A test that tries to free a region r2 that was not marked as reserved1747* (i.e. has no corresponding entry in memblock.reserved):1748*1749* +----------------+1750* | r2 |1751* +----------------+1752* | +----+ |1753* | | r1 | |1754* +--+----+------------------------------+1755* ^1756* |1757* rgn.base1758*1759* The array, regions counter and total size are not modified.1760*/1761static int memblock_free_absent_check(void)1762{1763struct memblock_region *rgn;17641765rgn = &memblock.reserved.regions[0];17661767struct region r1 = {1768.base = SZ_2M,1769.size = SZ_8K1770};1771struct region r2 = {1772.base = SZ_16M,1773.size = SZ_128M1774};17751776PREFIX_PUSH();17771778reset_memblock_regions();1779memblock_reserve(r1.base, r1.size);1780memblock_free((void *)r2.base, r2.size);17811782ASSERT_EQ(rgn->base, r1.base);1783ASSERT_EQ(rgn->size, r1.size);17841785ASSERT_EQ(memblock.reserved.cnt, 1);1786ASSERT_EQ(memblock.reserved.total_size, r1.size);17871788test_pass_pop();17891790return 0;1791}17921793/*1794* A test that tries to free a region r2 that overlaps with the beginning1795* of the already existing entry r1 (that is r1.base < r2.base + r2.size):1796*1797* +----+1798* | r2 |1799* +----+1800* | ...+--------------+ |1801* | : | r1 | |1802* +----+--+--------------+---------------+1803* ^ ^1804* | |1805* | rgn.base1806* |1807* r1.base1808*1809* Expect that only the intersection of both regions is freed. The1810* regions counter and total size are updated.1811*/1812static int memblock_free_overlap_top_check(void)1813{1814struct memblock_region *rgn;1815phys_addr_t total_size;18161817rgn = &memblock.reserved.regions[0];18181819struct region r1 = {1820.base = SZ_8M,1821.size = SZ_32M1822};1823struct region r2 = {1824.base = SZ_1M,1825.size = SZ_8M1826};18271828PREFIX_PUSH();18291830total_size = (r1.size + r1.base) - (r2.base + r2.size);18311832reset_memblock_regions();1833memblock_reserve(r1.base, r1.size);1834memblock_free((void *)r2.base, r2.size);18351836ASSERT_EQ(rgn->base, r2.base + r2.size);1837ASSERT_EQ(rgn->size, total_size);18381839ASSERT_EQ(memblock.reserved.cnt, 1);1840ASSERT_EQ(memblock.reserved.total_size, total_size);18411842test_pass_pop();18431844return 0;1845}18461847/*1848* A test that tries to free a region r2 that overlaps with the end of1849* the already existing entry r1 (that is r2.base < r1.base + r1.size):1850*1851* +----------------+1852* | r2 |1853* +----------------+1854* | +-----------+..... |1855* | | r1 | : |1856* +----+-----------+----+----------------+1857*1858* Expect that only the intersection of both regions is freed. The1859* regions counter and total size are updated.1860*/1861static int memblock_free_overlap_bottom_check(void)1862{1863struct memblock_region *rgn;1864phys_addr_t total_size;18651866rgn = &memblock.reserved.regions[0];18671868struct region r1 = {1869.base = SZ_8M,1870.size = SZ_32M1871};1872struct region r2 = {1873.base = SZ_32M,1874.size = SZ_32M1875};18761877PREFIX_PUSH();18781879total_size = r2.base - r1.base;18801881reset_memblock_regions();1882memblock_reserve(r1.base, r1.size);1883memblock_free((void *)r2.base, r2.size);18841885ASSERT_EQ(rgn->base, r1.base);1886ASSERT_EQ(rgn->size, total_size);18871888ASSERT_EQ(memblock.reserved.cnt, 1);1889ASSERT_EQ(memblock.reserved.total_size, total_size);18901891test_pass_pop();18921893return 0;1894}18951896/*1897* A test that tries to free a region r2 that is within the range of the1898* already existing entry r1 (that is1899* (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):1900*1901* +----+1902* | r2 |1903* +----+1904* | +------------+....+---------------+1905* | | rgn1 | r1 | rgn2 |1906* +----+------------+----+---------------+1907* ^1908* |1909* r1.base1910*1911* Expect that the region is split into two - one that ends at r2.base and1912* another that starts at r2.base + r2.size, with appropriate sizes. The1913* region counter and total size fields are updated.1914*/1915static int memblock_free_within_check(void)1916{1917struct memblock_region *rgn1, *rgn2;1918phys_addr_t r1_size, r2_size, total_size;19191920rgn1 = &memblock.reserved.regions[0];1921rgn2 = &memblock.reserved.regions[1];19221923struct region r1 = {1924.base = SZ_1M,1925.size = SZ_8M1926};1927struct region r2 = {1928.base = SZ_4M,1929.size = SZ_1M1930};19311932PREFIX_PUSH();19331934r1_size = r2.base - r1.base;1935r2_size = (r1.base + r1.size) - (r2.base + r2.size);1936total_size = r1_size + r2_size;19371938reset_memblock_regions();1939memblock_reserve(r1.base, r1.size);1940memblock_free((void *)r2.base, r2.size);19411942ASSERT_EQ(rgn1->base, r1.base);1943ASSERT_EQ(rgn1->size, r1_size);19441945ASSERT_EQ(rgn2->base, r2.base + r2.size);1946ASSERT_EQ(rgn2->size, r2_size);19471948ASSERT_EQ(memblock.reserved.cnt, 2);1949ASSERT_EQ(memblock.reserved.total_size, total_size);19501951test_pass_pop();19521953return 0;1954}19551956/*1957* A simple test that tries to free a memory block r1 that was marked1958* earlier as reserved when r1 is the only available region.1959* Expect to reserve a memory block r1 and then free r1 so that r1 is1960* overwritten with a dummy region. The region counter stays the same,1961* and the total size is updated.1962*/1963static int memblock_free_only_region_check(void)1964{1965struct memblock_region *rgn;19661967rgn = &memblock.reserved.regions[0];19681969struct region r1 = {1970.base = SZ_2K,1971.size = SZ_4K1972};19731974PREFIX_PUSH();19751976reset_memblock_regions();1977memblock_reserve(r1.base, r1.size);1978memblock_free((void *)r1.base, r1.size);19791980ASSERT_EQ(rgn->base, 0);1981ASSERT_EQ(rgn->size, 0);19821983ASSERT_EQ(memblock.reserved.cnt, 0);1984ASSERT_EQ(memblock.reserved.total_size, 0);19851986test_pass_pop();19871988return 0;1989}19901991/*1992* A simple test that tries free a region r2 when r2 extends past PHYS_ADDR_MAX:1993*1994* +--------+1995* | r2 |1996* +--------+1997* | +---+....+1998* | |rgn| |1999* +------------------------+---+----+2000*2001* Expect that only the portion between PHYS_ADDR_MAX and r2.base is freed.2002* Expect the total size of reserved memory to be updated and the counter to2003* not be updated.2004*/2005static int memblock_free_near_max_check(void)2006{2007struct memblock_region *rgn;2008phys_addr_t total_size;20092010rgn = &memblock.reserved.regions[0];20112012struct region r1 = {2013.base = PHYS_ADDR_MAX - SZ_2M,2014.size = SZ_2M2015};20162017struct region r2 = {2018.base = PHYS_ADDR_MAX - SZ_1M,2019.size = SZ_2M2020};20212022PREFIX_PUSH();20232024total_size = r1.size - (PHYS_ADDR_MAX - r2.base);20252026reset_memblock_regions();2027memblock_reserve(r1.base, r1.size);2028memblock_free((void *)r2.base, r2.size);20292030ASSERT_EQ(rgn->base, r1.base);2031ASSERT_EQ(rgn->size, total_size);20322033ASSERT_EQ(memblock.reserved.cnt, 1);2034ASSERT_EQ(memblock.reserved.total_size, total_size);20352036test_pass_pop();20372038return 0;2039}20402041/*2042* A test that tries to free a reserved region r3 that overlaps with two2043* existing reserved regions r1 and r2:2044*2045* +----------------+2046* | r3 |2047* +----------------+2048* | +----+..... ........+--------+2049* | | |r1 : : |r2 | |2050* +----+----+----+---+-------+--------+-----+2051*2052* Expect that only the intersections of r1 with r3 and r2 with r3 are freed2053* from the collection of reserved memory. Expect the total size of reserved2054* memory to be updated and the counter to not be updated.2055*/2056static int memblock_free_overlap_two_check(void)2057{2058struct memblock_region *rgn1, *rgn2;2059phys_addr_t new_r1_size, new_r2_size, r2_end, r3_end, total_size;20602061rgn1 = &memblock.reserved.regions[0];2062rgn2 = &memblock.reserved.regions[1];20632064struct region r1 = {2065.base = SZ_16M,2066.size = SZ_32M2067};2068struct region r2 = {2069.base = SZ_64M,2070.size = SZ_64M2071};2072struct region r3 = {2073.base = SZ_32M,2074.size = SZ_64M2075};20762077PREFIX_PUSH();20782079r2_end = r2.base + r2.size;2080r3_end = r3.base + r3.size;2081new_r1_size = r3.base - r1.base;2082new_r2_size = r2_end - r3_end;2083total_size = new_r1_size + new_r2_size;20842085reset_memblock_regions();2086memblock_reserve(r1.base, r1.size);2087memblock_reserve(r2.base, r2.size);2088memblock_free((void *)r3.base, r3.size);20892090ASSERT_EQ(rgn1->base, r1.base);2091ASSERT_EQ(rgn1->size, new_r1_size);20922093ASSERT_EQ(rgn2->base, r3_end);2094ASSERT_EQ(rgn2->size, new_r2_size);20952096ASSERT_EQ(memblock.reserved.cnt, 2);2097ASSERT_EQ(memblock.reserved.total_size, total_size);20982099test_pass_pop();21002101return 0;2102}21032104static int memblock_free_checks(void)2105{2106prefix_reset();2107prefix_push(FUNC_FREE);2108test_print("Running %s tests...\n", FUNC_FREE);21092110memblock_free_simple_check();2111memblock_free_absent_check();2112memblock_free_overlap_top_check();2113memblock_free_overlap_bottom_check();2114memblock_free_within_check();2115memblock_free_only_region_check();2116memblock_free_near_max_check();2117memblock_free_overlap_two_check();21182119prefix_pop();21202121return 0;2122}21232124static int memblock_set_bottom_up_check(void)2125{2126prefix_push("memblock_set_bottom_up");21272128memblock_set_bottom_up(false);2129ASSERT_EQ(memblock.bottom_up, false);2130memblock_set_bottom_up(true);2131ASSERT_EQ(memblock.bottom_up, true);21322133reset_memblock_attributes();2134test_pass_pop();21352136return 0;2137}21382139static int memblock_bottom_up_check(void)2140{2141prefix_push("memblock_bottom_up");21422143memblock_set_bottom_up(false);2144ASSERT_EQ(memblock_bottom_up(), memblock.bottom_up);2145ASSERT_EQ(memblock_bottom_up(), false);2146memblock_set_bottom_up(true);2147ASSERT_EQ(memblock_bottom_up(), memblock.bottom_up);2148ASSERT_EQ(memblock_bottom_up(), true);21492150reset_memblock_attributes();2151test_pass_pop();21522153return 0;2154}21552156static int memblock_bottom_up_checks(void)2157{2158test_print("Running memblock_*bottom_up tests...\n");21592160prefix_reset();2161memblock_set_bottom_up_check();2162prefix_reset();2163memblock_bottom_up_check();21642165return 0;2166}21672168/*2169* A test that tries to trim memory when both ends of the memory region are2170* aligned. Expect that the memory will not be trimmed. Expect the counter to2171* not be updated.2172*/2173static int memblock_trim_memory_aligned_check(void)2174{2175struct memblock_region *rgn;2176const phys_addr_t alignment = SMP_CACHE_BYTES;21772178rgn = &memblock.memory.regions[0];21792180struct region r = {2181.base = alignment,2182.size = alignment * 42183};21842185PREFIX_PUSH();21862187reset_memblock_regions();2188memblock_add(r.base, r.size);2189memblock_trim_memory(alignment);21902191ASSERT_EQ(rgn->base, r.base);2192ASSERT_EQ(rgn->size, r.size);21932194ASSERT_EQ(memblock.memory.cnt, 1);21952196test_pass_pop();21972198return 0;2199}22002201/*2202* A test that tries to trim memory when there are two available regions, r1 and2203* r2. Region r1 is aligned on both ends and region r2 is unaligned on one end2204* and smaller than the alignment:2205*2206* alignment2207* |--------|2208* | +-----------------+ +------+ |2209* | | r1 | | r2 | |2210* +--------+-----------------+--------+------+---+2211* ^ ^ ^ ^ ^2212* |________|________|________| |2213* | Unaligned address2214* Aligned addresses2215*2216* Expect that r1 will not be trimmed and r2 will be removed. Expect the2217* counter to be updated.2218*/2219static int memblock_trim_memory_too_small_check(void)2220{2221struct memblock_region *rgn;2222const phys_addr_t alignment = SMP_CACHE_BYTES;22232224rgn = &memblock.memory.regions[0];22252226struct region r1 = {2227.base = alignment,2228.size = alignment * 22229};2230struct region r2 = {2231.base = alignment * 4,2232.size = alignment - SZ_22233};22342235PREFIX_PUSH();22362237reset_memblock_regions();2238memblock_add(r1.base, r1.size);2239memblock_add(r2.base, r2.size);2240memblock_trim_memory(alignment);22412242ASSERT_EQ(rgn->base, r1.base);2243ASSERT_EQ(rgn->size, r1.size);22442245ASSERT_EQ(memblock.memory.cnt, 1);22462247test_pass_pop();22482249return 0;2250}22512252/*2253* A test that tries to trim memory when there are two available regions, r1 and2254* r2. Region r1 is aligned on both ends and region r2 is unaligned at the base2255* and aligned at the end:2256*2257* Unaligned address2258* |2259* v2260* | +-----------------+ +---------------+ |2261* | | r1 | | r2 | |2262* +--------+-----------------+----------+---------------+---+2263* ^ ^ ^ ^ ^ ^2264* |________|________|________|________|________|2265* |2266* Aligned addresses2267*2268* Expect that r1 will not be trimmed and r2 will be trimmed at the base.2269* Expect the counter to not be updated.2270*/2271static int memblock_trim_memory_unaligned_base_check(void)2272{2273struct memblock_region *rgn1, *rgn2;2274const phys_addr_t alignment = SMP_CACHE_BYTES;2275phys_addr_t offset = SZ_2;2276phys_addr_t new_r2_base, new_r2_size;22772278rgn1 = &memblock.memory.regions[0];2279rgn2 = &memblock.memory.regions[1];22802281struct region r1 = {2282.base = alignment,2283.size = alignment * 22284};2285struct region r2 = {2286.base = alignment * 4 + offset,2287.size = alignment * 2 - offset2288};22892290PREFIX_PUSH();22912292new_r2_base = r2.base + (alignment - offset);2293new_r2_size = r2.size - (alignment - offset);22942295reset_memblock_regions();2296memblock_add(r1.base, r1.size);2297memblock_add(r2.base, r2.size);2298memblock_trim_memory(alignment);22992300ASSERT_EQ(rgn1->base, r1.base);2301ASSERT_EQ(rgn1->size, r1.size);23022303ASSERT_EQ(rgn2->base, new_r2_base);2304ASSERT_EQ(rgn2->size, new_r2_size);23052306ASSERT_EQ(memblock.memory.cnt, 2);23072308test_pass_pop();23092310return 0;2311}23122313/*2314* A test that tries to trim memory when there are two available regions, r1 and2315* r2. Region r1 is aligned on both ends and region r2 is aligned at the base2316* and unaligned at the end:2317*2318* Unaligned address2319* |2320* v2321* | +-----------------+ +---------------+ |2322* | | r1 | | r2 | |2323* +--------+-----------------+--------+---------------+---+2324* ^ ^ ^ ^ ^ ^2325* |________|________|________|________|________|2326* |2327* Aligned addresses2328*2329* Expect that r1 will not be trimmed and r2 will be trimmed at the end.2330* Expect the counter to not be updated.2331*/2332static int memblock_trim_memory_unaligned_end_check(void)2333{2334struct memblock_region *rgn1, *rgn2;2335const phys_addr_t alignment = SMP_CACHE_BYTES;2336phys_addr_t offset = SZ_2;2337phys_addr_t new_r2_size;23382339rgn1 = &memblock.memory.regions[0];2340rgn2 = &memblock.memory.regions[1];23412342struct region r1 = {2343.base = alignment,2344.size = alignment * 22345};2346struct region r2 = {2347.base = alignment * 4,2348.size = alignment * 2 - offset2349};23502351PREFIX_PUSH();23522353new_r2_size = r2.size - (alignment - offset);23542355reset_memblock_regions();2356memblock_add(r1.base, r1.size);2357memblock_add(r2.base, r2.size);2358memblock_trim_memory(alignment);23592360ASSERT_EQ(rgn1->base, r1.base);2361ASSERT_EQ(rgn1->size, r1.size);23622363ASSERT_EQ(rgn2->base, r2.base);2364ASSERT_EQ(rgn2->size, new_r2_size);23652366ASSERT_EQ(memblock.memory.cnt, 2);23672368test_pass_pop();23692370return 0;2371}23722373static int memblock_trim_memory_checks(void)2374{2375prefix_reset();2376prefix_push(FUNC_TRIM);2377test_print("Running %s tests...\n", FUNC_TRIM);23782379memblock_trim_memory_aligned_check();2380memblock_trim_memory_too_small_check();2381memblock_trim_memory_unaligned_base_check();2382memblock_trim_memory_unaligned_end_check();23832384prefix_pop();23852386return 0;2387}23882389static int memblock_overlaps_region_check(void)2390{2391struct region r = {2392.base = SZ_1G,2393.size = SZ_4M2394};23952396PREFIX_PUSH();23972398reset_memblock_regions();2399memblock_add(r.base, r.size);24002401/* Far Away */2402ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_1M, SZ_1M));2403ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_2G, SZ_1M));24042405/* Neighbor */2406ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_1G - SZ_1M, SZ_1M));2407ASSERT_FALSE(memblock_overlaps_region(&memblock.memory, SZ_1G + SZ_4M, SZ_1M));24082409/* Partial Overlap */2410ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G - SZ_1M, SZ_2M));2411ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G + SZ_2M, SZ_2M));24122413/* Totally Overlap */2414ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G, SZ_4M));2415ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G - SZ_2M, SZ_8M));2416ASSERT_TRUE(memblock_overlaps_region(&memblock.memory, SZ_1G + SZ_1M, SZ_1M));24172418test_pass_pop();24192420return 0;2421}24222423static int memblock_overlaps_region_checks(void)2424{2425prefix_reset();2426prefix_push("memblock_overlaps_region");2427test_print("Running memblock_overlaps_region tests...\n");24282429memblock_overlaps_region_check();24302431prefix_pop();24322433return 0;2434}24352436#ifdef CONFIG_NUMA2437static int memblock_set_node_check(void)2438{2439unsigned long i, max_reserved;2440struct memblock_region *rgn;2441void *orig_region;24422443PREFIX_PUSH();24442445reset_memblock_regions();2446memblock_allow_resize();24472448dummy_physical_memory_init();2449memblock_add(dummy_physical_memory_base(), MEM_SIZE);2450orig_region = memblock.reserved.regions;24512452/* Equally Split range to node 0 and 1*/2453memblock_set_node(memblock_start_of_DRAM(),2454memblock_phys_mem_size() / 2, &memblock.memory, 0);2455memblock_set_node(memblock_start_of_DRAM() + memblock_phys_mem_size() / 2,2456memblock_phys_mem_size() / 2, &memblock.memory, 1);24572458ASSERT_EQ(memblock.memory.cnt, 2);2459rgn = &memblock.memory.regions[0];2460ASSERT_EQ(rgn->base, memblock_start_of_DRAM());2461ASSERT_EQ(rgn->size, memblock_phys_mem_size() / 2);2462ASSERT_EQ(memblock_get_region_node(rgn), 0);2463rgn = &memblock.memory.regions[1];2464ASSERT_EQ(rgn->base, memblock_start_of_DRAM() + memblock_phys_mem_size() / 2);2465ASSERT_EQ(rgn->size, memblock_phys_mem_size() / 2);2466ASSERT_EQ(memblock_get_region_node(rgn), 1);24672468/* Reserve 126 regions with the last one across node boundary */2469for (i = 0; i < 125; i++)2470memblock_reserve(memblock_start_of_DRAM() + SZ_16 * i, SZ_8);24712472memblock_reserve(memblock_start_of_DRAM() + memblock_phys_mem_size() / 2 - SZ_8,2473SZ_16);24742475/*2476* Commit 61167ad5fecd ("mm: pass nid to reserve_bootmem_region()")2477* do following process to set nid to each memblock.reserved region.2478* But it may miss some region if memblock_set_node() double the2479* array.2480*2481* By checking 'max', we make sure all region nid is set properly.2482*/2483repeat:2484max_reserved = memblock.reserved.max;2485for_each_mem_region(rgn) {2486int nid = memblock_get_region_node(rgn);24872488memblock_set_node(rgn->base, rgn->size, &memblock.reserved, nid);2489}2490if (max_reserved != memblock.reserved.max)2491goto repeat;24922493/* Confirm each region has valid node set */2494for_each_reserved_mem_region(rgn) {2495ASSERT_TRUE(numa_valid_node(memblock_get_region_node(rgn)));2496if (rgn == (memblock.reserved.regions + memblock.reserved.cnt - 1))2497ASSERT_EQ(1, memblock_get_region_node(rgn));2498else2499ASSERT_EQ(0, memblock_get_region_node(rgn));2500}25012502dummy_physical_memory_cleanup();25032504/*2505* The current reserved.regions is occupying a range of memory that2506* allocated from dummy_physical_memory_init(). After free the memory,2507* we must not use it. So restore the origin memory region to make sure2508* the tests can run as normal and not affected by the double array.2509*/2510memblock.reserved.regions = orig_region;2511memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;25122513test_pass_pop();25142515return 0;2516}25172518static int memblock_set_node_checks(void)2519{2520prefix_reset();2521prefix_push("memblock_set_node");2522test_print("Running memblock_set_node tests...\n");25232524memblock_set_node_check();25252526prefix_pop();25272528return 0;2529}2530#else2531static int memblock_set_node_checks(void)2532{2533return 0;2534}2535#endif25362537int memblock_basic_checks(void)2538{2539memblock_initialization_check();2540memblock_add_checks();2541memblock_reserve_checks();2542memblock_remove_checks();2543memblock_free_checks();2544memblock_bottom_up_checks();2545memblock_trim_memory_checks();2546memblock_overlaps_region_checks();2547memblock_set_node_checks();25482549return 0;2550}255125522553