Path: blob/master/tools/testing/memblock/tests/alloc_exact_nid_api.c
26299 views
// SPDX-License-Identifier: GPL-2.0-or-later1#include "alloc_exact_nid_api.h"2#include "alloc_nid_api.h"34#define FUNC_NAME "memblock_alloc_exact_nid_raw"56/*7* contains the fraction of MEM_SIZE contained in each node in basis point8* units (one hundredth of 1% or 1/10000)9*/10static const unsigned int node_fractions[] = {112500, /* 1/4 */12625, /* 1/16 */131250, /* 1/8 */141250, /* 1/8 */15625, /* 1/16 */16625, /* 1/16 */172500, /* 1/4 */18625, /* 1/16 */19};2021/*22* A test that tries to allocate a memory region in a specific NUMA node that23* has enough memory to allocate a region of the requested size.24* Expect to allocate an aligned region at the end of the requested node.25*/26static int alloc_exact_nid_top_down_numa_simple_check(void)27{28int nid_req = 3;29struct memblock_region *new_rgn = &memblock.reserved.regions[0];30struct memblock_region *req_node = &memblock.memory.regions[nid_req];31void *allocated_ptr = NULL;32phys_addr_t size;33phys_addr_t min_addr;34phys_addr_t max_addr;3536PREFIX_PUSH();37setup_numa_memblock(node_fractions);3839ASSERT_LE(SZ_4, req_node->size);40size = req_node->size / SZ_4;41min_addr = memblock_start_of_DRAM();42max_addr = memblock_end_of_DRAM();4344allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,45min_addr, max_addr,46nid_req);4748ASSERT_NE(allocated_ptr, NULL);49ASSERT_MEM_NE(allocated_ptr, 0, size);5051ASSERT_EQ(new_rgn->size, size);52ASSERT_EQ(new_rgn->base, region_end(req_node) - size);53ASSERT_LE(req_node->base, new_rgn->base);5455ASSERT_EQ(memblock.reserved.cnt, 1);56ASSERT_EQ(memblock.reserved.total_size, size);5758test_pass_pop();5960return 0;61}6263/*64* A test that tries to allocate a memory region in a specific NUMA node that65* is partially reserved but has enough memory for the allocated region:66*67* | +---------------------------------------+ |68* | | requested | |69* +-----------+---------------------------------------+----------+70*71* | +------------------+ +-----+ |72* | | reserved | | new | |73* +-----------+------------------+--------------+-----+----------+74*75* Expect to allocate an aligned region at the end of the requested node. The76* region count and total size get updated.77*/78static int alloc_exact_nid_top_down_numa_part_reserved_check(void)79{80int nid_req = 4;81struct memblock_region *new_rgn = &memblock.reserved.regions[1];82struct memblock_region *req_node = &memblock.memory.regions[nid_req];83void *allocated_ptr = NULL;84struct region r1;85phys_addr_t size;86phys_addr_t min_addr;87phys_addr_t max_addr;8889PREFIX_PUSH();90setup_numa_memblock(node_fractions);9192ASSERT_LE(SZ_8, req_node->size);93r1.base = req_node->base;94r1.size = req_node->size / SZ_2;95size = r1.size / SZ_4;96min_addr = memblock_start_of_DRAM();97max_addr = memblock_end_of_DRAM();9899memblock_reserve(r1.base, r1.size);100allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,101min_addr, max_addr,102nid_req);103104ASSERT_NE(allocated_ptr, NULL);105ASSERT_MEM_NE(allocated_ptr, 0, size);106107ASSERT_EQ(new_rgn->size, size);108ASSERT_EQ(new_rgn->base, region_end(req_node) - size);109ASSERT_LE(req_node->base, new_rgn->base);110111ASSERT_EQ(memblock.reserved.cnt, 2);112ASSERT_EQ(memblock.reserved.total_size, size + r1.size);113114test_pass_pop();115116return 0;117}118119/*120* A test that tries to allocate a memory region that spans over the min_addr121* and max_addr range and overlaps with two different nodes, where the first122* node is the requested node:123*124* min_addr125* | max_addr126* | |127* v v128* | +-----------------------+-----------+ |129* | | requested | node3 | |130* +-----------+-----------------------+-----------+--------------+131* + +132* | +-----------+ |133* | | rgn | |134* +-----------------------+-----------+--------------------------+135*136* Expect to drop the lower limit and allocate a memory region that ends at137* the end of the requested node.138*/139static int alloc_exact_nid_top_down_numa_split_range_low_check(void)140{141int nid_req = 2;142struct memblock_region *new_rgn = &memblock.reserved.regions[0];143struct memblock_region *req_node = &memblock.memory.regions[nid_req];144void *allocated_ptr = NULL;145phys_addr_t size = SZ_512;146phys_addr_t min_addr;147phys_addr_t max_addr;148phys_addr_t req_node_end;149150PREFIX_PUSH();151setup_numa_memblock(node_fractions);152153req_node_end = region_end(req_node);154min_addr = req_node_end - SZ_256;155max_addr = min_addr + size;156157allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,158min_addr, max_addr,159nid_req);160161ASSERT_NE(allocated_ptr, NULL);162ASSERT_MEM_NE(allocated_ptr, 0, size);163164ASSERT_EQ(new_rgn->size, size);165ASSERT_EQ(new_rgn->base, req_node_end - size);166ASSERT_LE(req_node->base, new_rgn->base);167168ASSERT_EQ(memblock.reserved.cnt, 1);169ASSERT_EQ(memblock.reserved.total_size, size);170171test_pass_pop();172173return 0;174}175176/*177* A test that tries to allocate a memory region that spans over the min_addr178* and max_addr range and overlaps with two different nodes, where the requested179* node ends before min_addr:180*181* min_addr182* | max_addr183* | |184* v v185* | +---------------+ +-------------+---------+ |186* | | requested | | node1 | node2 | |187* +----+---------------+--------+-------------+---------+----------+188* + +189* | +---------+ |190* | | rgn | |191* +----------+---------+-------------------------------------------+192*193* Expect to drop the lower limit and allocate a memory region that ends at194* the end of the requested node.195*/196static int alloc_exact_nid_top_down_numa_no_overlap_split_check(void)197{198int nid_req = 2;199struct memblock_region *new_rgn = &memblock.reserved.regions[0];200struct memblock_region *req_node = &memblock.memory.regions[nid_req];201struct memblock_region *node2 = &memblock.memory.regions[6];202void *allocated_ptr = NULL;203phys_addr_t size;204phys_addr_t min_addr;205phys_addr_t max_addr;206207PREFIX_PUSH();208setup_numa_memblock(node_fractions);209210size = SZ_512;211min_addr = node2->base - SZ_256;212max_addr = min_addr + size;213214allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,215min_addr, max_addr,216nid_req);217218ASSERT_NE(allocated_ptr, NULL);219ASSERT_MEM_NE(allocated_ptr, 0, size);220221ASSERT_EQ(new_rgn->size, size);222ASSERT_EQ(new_rgn->base, region_end(req_node) - size);223ASSERT_LE(req_node->base, new_rgn->base);224225ASSERT_EQ(memblock.reserved.cnt, 1);226ASSERT_EQ(memblock.reserved.total_size, size);227228test_pass_pop();229230return 0;231}232233/*234* A test that tries to allocate memory within min_addr and max_add range when235* the requested node and the range do not overlap, and requested node ends236* before min_addr. The range overlaps with multiple nodes along node237* boundaries:238*239* min_addr240* | max_addr241* | |242* v v243* |-----------+ +----------+----...----+----------+ |244* | requested | | min node | ... | max node | |245* +-----------+-----------+----------+----...----+----------+------+246* + +247* | +-----+ |248* | | rgn | |249* +-----+-----+----------------------------------------------------+250*251* Expect to drop the lower limit and allocate a memory region that ends at252* the end of the requested node.253*/254static int alloc_exact_nid_top_down_numa_no_overlap_low_check(void)255{256int nid_req = 0;257struct memblock_region *new_rgn = &memblock.reserved.regions[0];258struct memblock_region *req_node = &memblock.memory.regions[nid_req];259struct memblock_region *min_node = &memblock.memory.regions[2];260struct memblock_region *max_node = &memblock.memory.regions[5];261void *allocated_ptr = NULL;262phys_addr_t size = SZ_64;263phys_addr_t max_addr;264phys_addr_t min_addr;265266PREFIX_PUSH();267setup_numa_memblock(node_fractions);268269min_addr = min_node->base;270max_addr = region_end(max_node);271272allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,273min_addr, max_addr,274nid_req);275276ASSERT_NE(allocated_ptr, NULL);277ASSERT_MEM_NE(allocated_ptr, 0, size);278279ASSERT_EQ(new_rgn->size, size);280ASSERT_EQ(new_rgn->base, region_end(req_node) - size);281282ASSERT_EQ(memblock.reserved.cnt, 1);283ASSERT_EQ(memblock.reserved.total_size, size);284285test_pass_pop();286287return 0;288}289290/*291* A test that tries to allocate a memory region in a specific NUMA node that292* has enough memory to allocate a region of the requested size.293* Expect to allocate an aligned region at the beginning of the requested node.294*/295static int alloc_exact_nid_bottom_up_numa_simple_check(void)296{297int nid_req = 3;298struct memblock_region *new_rgn = &memblock.reserved.regions[0];299struct memblock_region *req_node = &memblock.memory.regions[nid_req];300void *allocated_ptr = NULL;301phys_addr_t size;302phys_addr_t min_addr;303phys_addr_t max_addr;304305PREFIX_PUSH();306setup_numa_memblock(node_fractions);307308ASSERT_LE(SZ_4, req_node->size);309size = req_node->size / SZ_4;310min_addr = memblock_start_of_DRAM();311max_addr = memblock_end_of_DRAM();312313allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,314min_addr, max_addr,315nid_req);316317ASSERT_NE(allocated_ptr, NULL);318ASSERT_MEM_NE(allocated_ptr, 0, size);319320ASSERT_EQ(new_rgn->size, size);321ASSERT_EQ(new_rgn->base, req_node->base);322ASSERT_LE(region_end(new_rgn), region_end(req_node));323324ASSERT_EQ(memblock.reserved.cnt, 1);325ASSERT_EQ(memblock.reserved.total_size, size);326327test_pass_pop();328329return 0;330}331332/*333* A test that tries to allocate a memory region in a specific NUMA node that334* is partially reserved but has enough memory for the allocated region:335*336* | +---------------------------------------+ |337* | | requested | |338* +-----------+---------------------------------------+---------+339*340* | +------------------+-----+ |341* | | reserved | new | |342* +-----------+------------------+-----+------------------------+343*344* Expect to allocate an aligned region in the requested node that merges with345* the existing reserved region. The total size gets updated.346*/347static int alloc_exact_nid_bottom_up_numa_part_reserved_check(void)348{349int nid_req = 4;350struct memblock_region *new_rgn = &memblock.reserved.regions[0];351struct memblock_region *req_node = &memblock.memory.regions[nid_req];352void *allocated_ptr = NULL;353struct region r1;354phys_addr_t size;355phys_addr_t min_addr;356phys_addr_t max_addr;357phys_addr_t total_size;358359PREFIX_PUSH();360setup_numa_memblock(node_fractions);361362ASSERT_LE(SZ_8, req_node->size);363r1.base = req_node->base;364r1.size = req_node->size / SZ_2;365size = r1.size / SZ_4;366min_addr = memblock_start_of_DRAM();367max_addr = memblock_end_of_DRAM();368total_size = size + r1.size;369370memblock_reserve(r1.base, r1.size);371allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,372min_addr, max_addr,373nid_req);374375ASSERT_NE(allocated_ptr, NULL);376ASSERT_MEM_NE(allocated_ptr, 0, size);377378ASSERT_EQ(new_rgn->size, total_size);379ASSERT_EQ(new_rgn->base, req_node->base);380ASSERT_LE(region_end(new_rgn), region_end(req_node));381382ASSERT_EQ(memblock.reserved.cnt, 1);383ASSERT_EQ(memblock.reserved.total_size, total_size);384385test_pass_pop();386387return 0;388}389390/*391* A test that tries to allocate a memory region that spans over the min_addr392* and max_addr range and overlaps with two different nodes, where the first393* node is the requested node:394*395* min_addr396* | max_addr397* | |398* v v399* | +-----------------------+-----------+ |400* | | requested | node3 | |401* +-----------+-----------------------+-----------+--------------+402* + +403* | +-----------+ |404* | | rgn | |405* +-----------+-----------+--------------------------------------+406*407* Expect to drop the lower limit and allocate a memory region at the beginning408* of the requested node.409*/410static int alloc_exact_nid_bottom_up_numa_split_range_low_check(void)411{412int nid_req = 2;413struct memblock_region *new_rgn = &memblock.reserved.regions[0];414struct memblock_region *req_node = &memblock.memory.regions[nid_req];415void *allocated_ptr = NULL;416phys_addr_t size = SZ_512;417phys_addr_t min_addr;418phys_addr_t max_addr;419phys_addr_t req_node_end;420421PREFIX_PUSH();422setup_numa_memblock(node_fractions);423424req_node_end = region_end(req_node);425min_addr = req_node_end - SZ_256;426max_addr = min_addr + size;427428allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,429min_addr, max_addr,430nid_req);431432ASSERT_NE(allocated_ptr, NULL);433ASSERT_MEM_NE(allocated_ptr, 0, size);434435ASSERT_EQ(new_rgn->size, size);436ASSERT_EQ(new_rgn->base, req_node->base);437ASSERT_LE(region_end(new_rgn), req_node_end);438439ASSERT_EQ(memblock.reserved.cnt, 1);440ASSERT_EQ(memblock.reserved.total_size, size);441442test_pass_pop();443444return 0;445}446447/*448* A test that tries to allocate a memory region that spans over the min_addr449* and max_addr range and overlaps with two different nodes, where the requested450* node ends before min_addr:451*452* min_addr453* | max_addr454* | |455* v v456* | +---------------+ +-------------+---------+ |457* | | requested | | node1 | node2 | |458* +----+---------------+--------+-------------+---------+---------+459* + +460* | +---------+ |461* | | rgn | |462* +----+---------+------------------------------------------------+463*464* Expect to drop the lower limit and allocate a memory region that starts at465* the beginning of the requested node.466*/467static int alloc_exact_nid_bottom_up_numa_no_overlap_split_check(void)468{469int nid_req = 2;470struct memblock_region *new_rgn = &memblock.reserved.regions[0];471struct memblock_region *req_node = &memblock.memory.regions[nid_req];472struct memblock_region *node2 = &memblock.memory.regions[6];473void *allocated_ptr = NULL;474phys_addr_t size;475phys_addr_t min_addr;476phys_addr_t max_addr;477478PREFIX_PUSH();479setup_numa_memblock(node_fractions);480481size = SZ_512;482min_addr = node2->base - SZ_256;483max_addr = min_addr + size;484485allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,486min_addr, max_addr,487nid_req);488489ASSERT_NE(allocated_ptr, NULL);490ASSERT_MEM_NE(allocated_ptr, 0, size);491492ASSERT_EQ(new_rgn->size, size);493ASSERT_EQ(new_rgn->base, req_node->base);494ASSERT_LE(region_end(new_rgn), region_end(req_node));495496ASSERT_EQ(memblock.reserved.cnt, 1);497ASSERT_EQ(memblock.reserved.total_size, size);498499test_pass_pop();500501return 0;502}503504/*505* A test that tries to allocate memory within min_addr and max_add range when506* the requested node and the range do not overlap, and requested node ends507* before min_addr. The range overlaps with multiple nodes along node508* boundaries:509*510* min_addr511* | max_addr512* | |513* v v514* |-----------+ +----------+----...----+----------+ |515* | requested | | min node | ... | max node | |516* +-----------+-----------+----------+----...----+----------+------+517* + +518* |-----+ |519* | rgn | |520* +-----+----------------------------------------------------------+521*522* Expect to drop the lower limit and allocate a memory region that starts at523* the beginning of the requested node.524*/525static int alloc_exact_nid_bottom_up_numa_no_overlap_low_check(void)526{527int nid_req = 0;528struct memblock_region *new_rgn = &memblock.reserved.regions[0];529struct memblock_region *req_node = &memblock.memory.regions[nid_req];530struct memblock_region *min_node = &memblock.memory.regions[2];531struct memblock_region *max_node = &memblock.memory.regions[5];532void *allocated_ptr = NULL;533phys_addr_t size = SZ_64;534phys_addr_t max_addr;535phys_addr_t min_addr;536537PREFIX_PUSH();538setup_numa_memblock(node_fractions);539540min_addr = min_node->base;541max_addr = region_end(max_node);542543allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,544min_addr, max_addr,545nid_req);546547ASSERT_NE(allocated_ptr, NULL);548ASSERT_MEM_NE(allocated_ptr, 0, size);549550ASSERT_EQ(new_rgn->size, size);551ASSERT_EQ(new_rgn->base, req_node->base);552ASSERT_LE(region_end(new_rgn), region_end(req_node));553554ASSERT_EQ(memblock.reserved.cnt, 1);555ASSERT_EQ(memblock.reserved.total_size, size);556557test_pass_pop();558559return 0;560}561562/*563* A test that tries to allocate a memory region in a specific NUMA node that564* does not have enough memory to allocate a region of the requested size:565*566* | +-----+ |567* | | req | |568* +---+-----+----------------------------+569*570* +---------+571* | rgn |572* +---------+573*574* Expect no allocation to happen.575*/576static int alloc_exact_nid_numa_small_node_generic_check(void)577{578int nid_req = 1;579struct memblock_region *req_node = &memblock.memory.regions[nid_req];580void *allocated_ptr = NULL;581phys_addr_t size;582phys_addr_t min_addr;583phys_addr_t max_addr;584585PREFIX_PUSH();586setup_numa_memblock(node_fractions);587588size = SZ_2 * req_node->size;589min_addr = memblock_start_of_DRAM();590max_addr = memblock_end_of_DRAM();591592allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,593min_addr, max_addr,594nid_req);595596ASSERT_EQ(allocated_ptr, NULL);597598test_pass_pop();599600return 0;601}602603/*604* A test that tries to allocate a memory region in a specific NUMA node that605* is fully reserved:606*607* | +---------+ |608* | |requested| |609* +--------------+---------+-------------+610*611* | +---------+ |612* | | reserved| |613* +--------------+---------+-------------+614*615* Expect no allocation to happen.616*/617static int alloc_exact_nid_numa_node_reserved_generic_check(void)618{619int nid_req = 2;620struct memblock_region *req_node = &memblock.memory.regions[nid_req];621void *allocated_ptr = NULL;622phys_addr_t size;623phys_addr_t min_addr;624phys_addr_t max_addr;625626PREFIX_PUSH();627setup_numa_memblock(node_fractions);628629size = req_node->size;630min_addr = memblock_start_of_DRAM();631max_addr = memblock_end_of_DRAM();632633memblock_reserve(req_node->base, req_node->size);634allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,635min_addr, max_addr,636nid_req);637638ASSERT_EQ(allocated_ptr, NULL);639640test_pass_pop();641642return 0;643}644645/*646* A test that tries to allocate a memory region in a specific NUMA node that647* is partially reserved and does not have enough contiguous memory for the648* allocated region:649*650* | +-----------------------+ |651* | | requested | |652* +-----------+-----------------------+----+653*654* | +----------+ |655* | | reserved | |656* +-----------------+----------+-----------+657*658* Expect no allocation to happen.659*/660static int alloc_exact_nid_numa_part_reserved_fail_generic_check(void)661{662int nid_req = 4;663struct memblock_region *req_node = &memblock.memory.regions[nid_req];664void *allocated_ptr = NULL;665struct region r1;666phys_addr_t size;667phys_addr_t min_addr;668phys_addr_t max_addr;669670PREFIX_PUSH();671setup_numa_memblock(node_fractions);672673ASSERT_LE(SZ_4, req_node->size);674size = req_node->size / SZ_2;675r1.base = req_node->base + (size / SZ_2);676r1.size = size;677678min_addr = memblock_start_of_DRAM();679max_addr = memblock_end_of_DRAM();680681memblock_reserve(r1.base, r1.size);682allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,683min_addr, max_addr,684nid_req);685686ASSERT_EQ(allocated_ptr, NULL);687688test_pass_pop();689690return 0;691}692693/*694* A test that tries to allocate a memory region that spans over the min_addr695* and max_addr range and overlaps with two different nodes, where the second696* node is the requested node:697*698* min_addr699* | max_addr700* | |701* v v702* | +--------------------------+---------+ |703* | | first node |requested| |704* +------+--------------------------+---------+----------------+705*706* Expect no allocation to happen.707*/708static int alloc_exact_nid_numa_split_range_high_generic_check(void)709{710int nid_req = 3;711struct memblock_region *req_node = &memblock.memory.regions[nid_req];712void *allocated_ptr = NULL;713phys_addr_t size = SZ_512;714phys_addr_t min_addr;715phys_addr_t max_addr;716717PREFIX_PUSH();718setup_numa_memblock(node_fractions);719720min_addr = req_node->base - SZ_256;721max_addr = min_addr + size;722723allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,724min_addr, max_addr,725nid_req);726727ASSERT_EQ(allocated_ptr, NULL);728729test_pass_pop();730731return 0;732}733734/*735* A test that tries to allocate memory within min_addr and max_add range when736* the requested node and the range do not overlap, and requested node starts737* after max_addr. The range overlaps with multiple nodes along node738* boundaries:739*740* min_addr741* | max_addr742* | |743* v v744* | +----------+----...----+----------+ +-----------+ |745* | | min node | ... | max node | | requested | |746* +-----+----------+----...----+----------+--------+-----------+---+747*748* Expect no allocation to happen.749*/750static int alloc_exact_nid_numa_no_overlap_high_generic_check(void)751{752int nid_req = 7;753struct memblock_region *min_node = &memblock.memory.regions[2];754struct memblock_region *max_node = &memblock.memory.regions[5];755void *allocated_ptr = NULL;756phys_addr_t size = SZ_64;757phys_addr_t max_addr;758phys_addr_t min_addr;759760PREFIX_PUSH();761setup_numa_memblock(node_fractions);762763min_addr = min_node->base;764max_addr = region_end(max_node);765766allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,767min_addr, max_addr,768nid_req);769770ASSERT_EQ(allocated_ptr, NULL);771772test_pass_pop();773774return 0;775}776777/*778* A test that tries to allocate a memory region in a specific NUMA node that779* does not have enough memory to allocate a region of the requested size.780* Additionally, none of the nodes have enough memory to allocate the region:781*782* +-----------------------------------+783* | new |784* +-----------------------------------+785* |-------+-------+-------+-------+-------+-------+-------+-------|786* | node0 | node1 | node2 | node3 | node4 | node5 | node6 | node7 |787* +-------+-------+-------+-------+-------+-------+-------+-------+788*789* Expect no allocation to happen.790*/791static int alloc_exact_nid_numa_large_region_generic_check(void)792{793int nid_req = 3;794void *allocated_ptr = NULL;795phys_addr_t size = MEM_SIZE / SZ_2;796phys_addr_t min_addr;797phys_addr_t max_addr;798799PREFIX_PUSH();800setup_numa_memblock(node_fractions);801802min_addr = memblock_start_of_DRAM();803max_addr = memblock_end_of_DRAM();804805allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,806min_addr, max_addr,807nid_req);808ASSERT_EQ(allocated_ptr, NULL);809810test_pass_pop();811812return 0;813}814815/*816* A test that tries to allocate memory within min_addr and max_addr range when817* there are two reserved regions at the borders. The requested node starts at818* min_addr and ends at max_addr and is the same size as the region to be819* allocated:820*821* min_addr822* | max_addr823* | |824* v v825* | +-----------+-----------------------+-----------------------|826* | | node5 | requested | node7 |827* +------+-----------+-----------------------+-----------------------+828* + +829* | +----+-----------------------+----+ |830* | | r2 | new | r1 | |831* +-------------+----+-----------------------+----+------------------+832*833* Expect to merge all of the regions into one. The region counter and total834* size fields get updated.835*/836static int alloc_exact_nid_numa_reserved_full_merge_generic_check(void)837{838int nid_req = 6;839int nid_next = nid_req + 1;840struct memblock_region *new_rgn = &memblock.reserved.regions[0];841struct memblock_region *req_node = &memblock.memory.regions[nid_req];842struct memblock_region *next_node = &memblock.memory.regions[nid_next];843void *allocated_ptr = NULL;844struct region r1, r2;845phys_addr_t size = req_node->size;846phys_addr_t total_size;847phys_addr_t max_addr;848phys_addr_t min_addr;849850PREFIX_PUSH();851setup_numa_memblock(node_fractions);852853r1.base = next_node->base;854r1.size = SZ_128;855856r2.size = SZ_128;857r2.base = r1.base - (size + r2.size);858859total_size = r1.size + r2.size + size;860min_addr = r2.base + r2.size;861max_addr = r1.base;862863memblock_reserve(r1.base, r1.size);864memblock_reserve(r2.base, r2.size);865866allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,867min_addr, max_addr,868nid_req);869870ASSERT_NE(allocated_ptr, NULL);871ASSERT_MEM_NE(allocated_ptr, 0, size);872873ASSERT_EQ(new_rgn->size, total_size);874ASSERT_EQ(new_rgn->base, r2.base);875876ASSERT_LE(new_rgn->base, req_node->base);877ASSERT_LE(region_end(req_node), region_end(new_rgn));878879ASSERT_EQ(memblock.reserved.cnt, 1);880ASSERT_EQ(memblock.reserved.total_size, total_size);881882test_pass_pop();883884return 0;885}886887/*888* A test that tries to allocate memory within min_addr and max_add range,889* where the total range can fit the region, but it is split between two nodes890* and everything else is reserved. Additionally, nid is set to NUMA_NO_NODE891* instead of requesting a specific node:892*893* +-----------+894* | new |895* +-----------+896* | +---------------------+-----------|897* | | prev node | next node |898* +------+---------------------+-----------+899* + +900* |----------------------+ +-----|901* | r1 | | r2 |902* +----------------------+-----------+-----+903* ^ ^904* | |905* | max_addr906* |907* min_addr908*909* Expect no allocation to happen.910*/911static int alloc_exact_nid_numa_split_all_reserved_generic_check(void)912{913void *allocated_ptr = NULL;914struct memblock_region *next_node = &memblock.memory.regions[7];915struct region r1, r2;916phys_addr_t size = SZ_256;917phys_addr_t max_addr;918phys_addr_t min_addr;919920PREFIX_PUSH();921setup_numa_memblock(node_fractions);922923r2.base = next_node->base + SZ_128;924r2.size = memblock_end_of_DRAM() - r2.base;925926r1.size = MEM_SIZE - (r2.size + size);927r1.base = memblock_start_of_DRAM();928929min_addr = r1.base + r1.size;930max_addr = r2.base;931932memblock_reserve(r1.base, r1.size);933memblock_reserve(r2.base, r2.size);934935allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,936min_addr, max_addr,937NUMA_NO_NODE);938939ASSERT_EQ(allocated_ptr, NULL);940941test_pass_pop();942943return 0;944}945946/* Test case wrappers for NUMA tests */947static int alloc_exact_nid_numa_simple_check(void)948{949test_print("\tRunning %s...\n", __func__);950memblock_set_bottom_up(false);951alloc_exact_nid_top_down_numa_simple_check();952memblock_set_bottom_up(true);953alloc_exact_nid_bottom_up_numa_simple_check();954955return 0;956}957958static int alloc_exact_nid_numa_part_reserved_check(void)959{960test_print("\tRunning %s...\n", __func__);961memblock_set_bottom_up(false);962alloc_exact_nid_top_down_numa_part_reserved_check();963memblock_set_bottom_up(true);964alloc_exact_nid_bottom_up_numa_part_reserved_check();965966return 0;967}968969static int alloc_exact_nid_numa_split_range_low_check(void)970{971test_print("\tRunning %s...\n", __func__);972memblock_set_bottom_up(false);973alloc_exact_nid_top_down_numa_split_range_low_check();974memblock_set_bottom_up(true);975alloc_exact_nid_bottom_up_numa_split_range_low_check();976977return 0;978}979980static int alloc_exact_nid_numa_no_overlap_split_check(void)981{982test_print("\tRunning %s...\n", __func__);983memblock_set_bottom_up(false);984alloc_exact_nid_top_down_numa_no_overlap_split_check();985memblock_set_bottom_up(true);986alloc_exact_nid_bottom_up_numa_no_overlap_split_check();987988return 0;989}990991static int alloc_exact_nid_numa_no_overlap_low_check(void)992{993test_print("\tRunning %s...\n", __func__);994memblock_set_bottom_up(false);995alloc_exact_nid_top_down_numa_no_overlap_low_check();996memblock_set_bottom_up(true);997alloc_exact_nid_bottom_up_numa_no_overlap_low_check();998999return 0;1000}10011002static int alloc_exact_nid_numa_small_node_check(void)1003{1004test_print("\tRunning %s...\n", __func__);1005run_top_down(alloc_exact_nid_numa_small_node_generic_check);1006run_bottom_up(alloc_exact_nid_numa_small_node_generic_check);10071008return 0;1009}10101011static int alloc_exact_nid_numa_node_reserved_check(void)1012{1013test_print("\tRunning %s...\n", __func__);1014run_top_down(alloc_exact_nid_numa_node_reserved_generic_check);1015run_bottom_up(alloc_exact_nid_numa_node_reserved_generic_check);10161017return 0;1018}10191020static int alloc_exact_nid_numa_part_reserved_fail_check(void)1021{1022test_print("\tRunning %s...\n", __func__);1023run_top_down(alloc_exact_nid_numa_part_reserved_fail_generic_check);1024run_bottom_up(alloc_exact_nid_numa_part_reserved_fail_generic_check);10251026return 0;1027}10281029static int alloc_exact_nid_numa_split_range_high_check(void)1030{1031test_print("\tRunning %s...\n", __func__);1032run_top_down(alloc_exact_nid_numa_split_range_high_generic_check);1033run_bottom_up(alloc_exact_nid_numa_split_range_high_generic_check);10341035return 0;1036}10371038static int alloc_exact_nid_numa_no_overlap_high_check(void)1039{1040test_print("\tRunning %s...\n", __func__);1041run_top_down(alloc_exact_nid_numa_no_overlap_high_generic_check);1042run_bottom_up(alloc_exact_nid_numa_no_overlap_high_generic_check);10431044return 0;1045}10461047static int alloc_exact_nid_numa_large_region_check(void)1048{1049test_print("\tRunning %s...\n", __func__);1050run_top_down(alloc_exact_nid_numa_large_region_generic_check);1051run_bottom_up(alloc_exact_nid_numa_large_region_generic_check);10521053return 0;1054}10551056static int alloc_exact_nid_numa_reserved_full_merge_check(void)1057{1058test_print("\tRunning %s...\n", __func__);1059run_top_down(alloc_exact_nid_numa_reserved_full_merge_generic_check);1060run_bottom_up(alloc_exact_nid_numa_reserved_full_merge_generic_check);10611062return 0;1063}10641065static int alloc_exact_nid_numa_split_all_reserved_check(void)1066{1067test_print("\tRunning %s...\n", __func__);1068run_top_down(alloc_exact_nid_numa_split_all_reserved_generic_check);1069run_bottom_up(alloc_exact_nid_numa_split_all_reserved_generic_check);10701071return 0;1072}10731074int __memblock_alloc_exact_nid_numa_checks(void)1075{1076test_print("Running %s NUMA tests...\n", FUNC_NAME);10771078alloc_exact_nid_numa_simple_check();1079alloc_exact_nid_numa_part_reserved_check();1080alloc_exact_nid_numa_split_range_low_check();1081alloc_exact_nid_numa_no_overlap_split_check();1082alloc_exact_nid_numa_no_overlap_low_check();10831084alloc_exact_nid_numa_small_node_check();1085alloc_exact_nid_numa_node_reserved_check();1086alloc_exact_nid_numa_part_reserved_fail_check();1087alloc_exact_nid_numa_split_range_high_check();1088alloc_exact_nid_numa_no_overlap_high_check();1089alloc_exact_nid_numa_large_region_check();1090alloc_exact_nid_numa_reserved_full_merge_check();1091alloc_exact_nid_numa_split_all_reserved_check();10921093return 0;1094}10951096int memblock_alloc_exact_nid_checks(void)1097{1098prefix_reset();1099prefix_push(FUNC_NAME);11001101reset_memblock_attributes();1102dummy_physical_memory_init();11031104memblock_alloc_exact_nid_range_checks();1105memblock_alloc_exact_nid_numa_checks();11061107dummy_physical_memory_cleanup();11081109prefix_pop();11101111return 0;1112}111311141115