diff --git a/MAINTAINERS b/MAINTAINERS index ef17300b3fe8a..61dfea154445b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12554,6 +12554,7 @@ S: Maintained F: Documentation/core-api/boot-time-mm.rst F: include/linux/memblock.h F: mm/memblock.c +F: tools/testing/memblock/ MEMORY CONTROLLER DRIVERS M: Krzysztof Kozlowski diff --git a/mm/memblock.c b/mm/memblock.c index b12a364f2766f..e4f03a6e8e56e 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1284,11 +1284,10 @@ __next_mem_pfn_range_in_zone(u64 *idx, struct zone *zone, { int zone_nid = zone_to_nid(zone); phys_addr_t spa, epa; - int nid; __next_mem_range(idx, zone_nid, MEMBLOCK_NONE, &memblock.memory, &memblock.reserved, - &spa, &epa, &nid); + &spa, &epa, NULL); while (*idx != U64_MAX) { unsigned long epfn = PFN_DOWN(epa); @@ -1315,7 +1314,7 @@ __next_mem_pfn_range_in_zone(u64 *idx, struct zone *zone, __next_mem_range(idx, zone_nid, MEMBLOCK_NONE, &memblock.memory, &memblock.reserved, - &spa, &epa, &nid); + &spa, &epa, NULL); } /* signal end of iteration */ diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h index 00a6c4ca562b9..01907b33537e0 100644 --- a/tools/include/linux/atomic.h +++ b/tools/include/linux/atomic.h @@ -4,6 +4,8 @@ #include +void atomic_long_set(atomic_long_t *v, long i); + /* atomic_cmpxchg_relaxed */ #ifndef atomic_cmpxchg_relaxed #define atomic_cmpxchg_relaxed atomic_cmpxchg diff --git a/tools/include/linux/cache.h b/tools/include/linux/cache.h new file mode 100644 index 0000000000000..9e9d585f0b9df --- /dev/null +++ b/tools/include/linux/cache.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_LINUX_CACHE_H +#define _TOOLS_LINUX_CACHE_H + +#define L1_CACHE_SHIFT 5 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +#define SMP_CACHE_BYTES L1_CACHE_BYTES + +#endif diff --git a/tools/include/linux/debugfs.h b/tools/include/linux/debugfs.h new file mode 100644 index 0000000000000..4ba06140b1bec --- /dev/null +++ b/tools/include/linux/debugfs.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_DEBUGFS_H +#define _TOOLS_DEBUGFS_H + +#endif diff --git a/tools/include/linux/gfp.h b/tools/include/linux/gfp.h index 22030756fbc0a..b238dbc9eb858 100644 --- a/tools/include/linux/gfp.h +++ b/tools/include/linux/gfp.h @@ -1,4 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_INCLUDE_LINUX_GFP_H #define _TOOLS_INCLUDE_LINUX_GFP_H +#include + +#define __GFP_BITS_SHIFT 26 +#define __GFP_BITS_MASK ((gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) + +#define __GFP_HIGH 0x20u +#define __GFP_IO 0x40u +#define __GFP_FS 0x80u +#define __GFP_NOWARN 0x200u +#define __GFP_ZERO 0x8000u +#define __GFP_ATOMIC 0x80000u +#define __GFP_ACCOUNT 0x100000u +#define __GFP_DIRECT_RECLAIM 0x400000u +#define __GFP_KSWAPD_RECLAIM 0x2000000u + +#define __GFP_RECLAIM (__GFP_DIRECT_RECLAIM | __GFP_KSWAPD_RECLAIM) + +#define GFP_ZONEMASK 0x0fu +#define GFP_ATOMIC (__GFP_HIGH | __GFP_ATOMIC | __GFP_KSWAPD_RECLAIM) +#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) +#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) + +static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) +{ + return !!(gfp_flags & __GFP_DIRECT_RECLAIM); +} + #endif /* _TOOLS_INCLUDE_LINUX_GFP_H */ diff --git a/tools/include/linux/io.h b/tools/include/linux/io.h new file mode 100644 index 0000000000000..e129871fe6610 --- /dev/null +++ b/tools/include/linux/io.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_IO_H +#define _TOOLS_IO_H + +#endif diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h index 9701e8307db02..4b0673bf52c2e 100644 --- a/tools/include/linux/kernel.h +++ b/tools/include/linux/kernel.h @@ -15,6 +15,8 @@ #define UINT_MAX (~0U) #endif +#define _RET_IP_ ((unsigned long)__builtin_return_address(0)) + #define PERF_ALIGN(x, a) __PERF_ALIGN_MASK(x, (typeof(x))(a)-1) #define __PERF_ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) @@ -51,6 +53,10 @@ _min1 < _min2 ? _min1 : _min2; }) #endif +#define max_t(type, x, y) max((type)x, (type)y) +#define min_t(type, x, y) min((type)x, (type)y) +#define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi) + #ifndef BUG_ON #ifdef NDEBUG #define BUG_ON(cond) do { if (cond) {} } while (0) diff --git a/tools/include/linux/mm.h b/tools/include/linux/mm.h new file mode 100644 index 0000000000000..a03d9bba51514 --- /dev/null +++ b/tools/include/linux/mm.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_LINUX_MM_H +#define _TOOLS_LINUX_MM_H + +#include +#include + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE - 1)) + +#define PHYS_ADDR_MAX (~(phys_addr_t)0) + +#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) +#define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a)) + +#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) + +#define __va(x) ((void *)((unsigned long)(x))) +#define __pa(x) ((unsigned long)(x)) + +#define pfn_to_page(pfn) ((void *)((pfn) * PAGE_SIZE)) + +#define phys_to_virt phys_to_virt +static inline void *phys_to_virt(unsigned long address) +{ + return __va(address); +} + +void reserve_bootmem_region(phys_addr_t start, phys_addr_t end); + +static inline void totalram_pages_inc(void) +{ +} + +static inline void totalram_pages_add(long count) +{ +} + +#endif diff --git a/tools/include/linux/pfn.h b/tools/include/linux/pfn.h new file mode 100644 index 0000000000000..7512a58189ebd --- /dev/null +++ b/tools/include/linux/pfn.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_LINUX_PFN_H_ +#define _TOOLS_LINUX_PFN_H_ + +#include + +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT) +#endif diff --git a/tools/testing/radix-tree/linux/slab.h b/tools/include/linux/slab.h similarity index 61% rename from tools/testing/radix-tree/linux/slab.h rename to tools/include/linux/slab.h index 2958830ce4d76..f41d8a0eb1a42 100644 --- a/tools/testing/radix-tree/linux/slab.h +++ b/tools/include/linux/slab.h @@ -1,20 +1,31 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef SLAB_H -#define SLAB_H +#ifndef _TOOLS_SLAB_H +#define _TOOLS_SLAB_H #include #include -#define SLAB_HWCACHE_ALIGN 1 #define SLAB_PANIC 2 #define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */ -void *kmalloc(size_t size, gfp_t); -void kfree(void *); +#define kzalloc_node(size, flags, node) kmalloc(size, flags) + +void *kmalloc(size_t size, gfp_t gfp); +void kfree(void *p); + +bool slab_is_available(void); + +enum slab_state { + DOWN, + PARTIAL, + PARTIAL_NODE, + UP, + FULL +}; static inline void *kzalloc(size_t size, gfp_t gfp) { - return kmalloc(size, gfp | __GFP_ZERO); + return kmalloc(size, gfp | __GFP_ZERO); } void *kmem_cache_alloc(struct kmem_cache *cachep, int flags); @@ -24,4 +35,4 @@ struct kmem_cache *kmem_cache_create(const char *name, unsigned int size, unsigned int align, unsigned int flags, void (*ctor)(void *)); -#endif /* SLAB_H */ +#endif /* _TOOLS_SLAB_H */ diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h index 6e14a533ab4e1..5908e58c35981 100644 --- a/tools/include/linux/types.h +++ b/tools/include/linux/types.h @@ -64,10 +64,20 @@ typedef __u64 __bitwise __be64; typedef __u16 __bitwise __sum16; typedef __u32 __bitwise __wsum; +#ifdef CONFIG_PHYS_ADDR_T_64BIT +typedef u64 phys_addr_t; +#else +typedef u32 phys_addr_t; +#endif + typedef struct { int counter; } atomic_t; +typedef struct { + long counter; +} atomic_long_t; + #ifndef __aligned_u64 # define __aligned_u64 __u64 __attribute__((aligned(8))) #endif diff --git a/tools/lib/slab.c b/tools/lib/slab.c new file mode 100644 index 0000000000000..959997fb0652f --- /dev/null +++ b/tools/lib/slab.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +#include +#include +#include +#include + +int kmalloc_nr_allocated; +int kmalloc_verbose; + +void *kmalloc(size_t size, gfp_t gfp) +{ + void *ret; + + if (!(gfp & __GFP_DIRECT_RECLAIM)) + return NULL; + + ret = malloc(size); + uatomic_inc(&kmalloc_nr_allocated); + if (kmalloc_verbose) + printf("Allocating %p from malloc\n", ret); + if (gfp & __GFP_ZERO) + memset(ret, 0, size); + return ret; +} + +void kfree(void *p) +{ + if (!p) + return; + uatomic_dec(&kmalloc_nr_allocated); + if (kmalloc_verbose) + printf("Freeing %p to malloc\n", p); + free(p); +} diff --git a/tools/testing/memblock/.gitignore b/tools/testing/memblock/.gitignore new file mode 100644 index 0000000000000..654338e0be52e --- /dev/null +++ b/tools/testing/memblock/.gitignore @@ -0,0 +1,4 @@ +main +memblock.c +linux/memblock.h +asm/cmpxchg.h diff --git a/tools/testing/memblock/Makefile b/tools/testing/memblock/Makefile new file mode 100644 index 0000000000000..29715327a2d3a --- /dev/null +++ b/tools/testing/memblock/Makefile @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Memblock simulator requires AddressSanitizer (libasan) and liburcu development +# packages installed +CFLAGS += -I. -I../../include -Wall -O2 -fsanitize=address \ + -fsanitize=undefined -D CONFIG_PHYS_ADDR_T_64BIT +LDFLAGS += -fsanitize=address -fsanitize=undefined +TARGETS = main +TEST_OFILES = tests/basic_api.o tests/common.o +DEP_OFILES = memblock.o lib/slab.o mmzone.o slab.o +OFILES = main.o $(DEP_OFILES) $(TEST_OFILES) +EXTR_SRC = ../../../mm/memblock.c + +ifeq ($(BUILD), 32) + CFLAGS += -m32 + LDFLAGS += -m32 +endif + +# Process user parameters +include scripts/Makefile.include + +main: $(OFILES) + +$(OFILES): include + +include: ../../../include/linux/memblock.h ../../include/linux/*.h \ + ../../include/asm/*.h + + @mkdir -p linux + test -L linux/memblock.h || ln -s ../../../../include/linux/memblock.h linux/memblock.h + test -L asm/cmpxchg.h || ln -s ../../../arch/x86/include/asm/cmpxchg.h asm/cmpxchg.h + +memblock.c: $(EXTR_SRC) + test -L memblock.c || ln -s $(EXTR_SRC) memblock.c + +clean: + $(RM) $(TARGETS) $(OFILES) linux/memblock.h memblock.c asm/cmpxchg.h + +help: + @echo 'Memblock simulator' + @echo '' + @echo 'Available targets:' + @echo ' main - Build the memblock simulator' + @echo ' clean - Remove generated files and symlinks in the directory' + @echo '' + @echo 'Configuration:' + @echo ' make NUMA=1 - simulate enabled NUMA' + @echo ' make MOVABLE_NODE=1 - override `movable_node_is_enabled`' + @echo ' definition to simulate movable NUMA nodes' + @echo ' make 32BIT_PHYS_ADDR_T=1 - Use 32 bit physical addresses' + +vpath %.c ../../lib + +.PHONY: clean include help diff --git a/tools/testing/memblock/asm/dma.h b/tools/testing/memblock/asm/dma.h new file mode 100644 index 0000000000000..13ff8e5d22ef6 --- /dev/null +++ b/tools/testing/memblock/asm/dma.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_DMA_H +#define _TOOLS_DMA_H + +#endif diff --git a/tools/testing/memblock/internal.h b/tools/testing/memblock/internal.h new file mode 100644 index 0000000000000..94b52a8718b55 --- /dev/null +++ b/tools/testing/memblock/internal.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _MM_INTERNAL_H +#define _MM_INTERNAL_H + +struct page {}; + +void memblock_free_pages(struct page *page, unsigned long pfn, + unsigned int order) +{ +} + +#endif diff --git a/tools/testing/memblock/lib/slab.c b/tools/testing/memblock/lib/slab.c new file mode 100644 index 0000000000000..6be6020328fbd --- /dev/null +++ b/tools/testing/memblock/lib/slab.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include + +enum slab_state slab_state; + +bool slab_is_available(void) +{ + return slab_state >= UP; +} diff --git a/tools/testing/memblock/linux/init.h b/tools/testing/memblock/linux/init.h new file mode 100644 index 0000000000000..828e0ee0bc6c4 --- /dev/null +++ b/tools/testing/memblock/linux/init.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_INIT_H +#define _LINUX_INIT_H + +#include +#include +#include + +#define __section(section) __attribute__((__section__(section))) + +#define __initconst +#define __meminit +#define __meminitdata +#define __refdata +#define __initdata + +struct obs_kernel_param { + const char *str; + int (*setup_func)(char *st); + int early; +}; + +#define __setup_param(str, unique_id, fn, early) \ + static const char __setup_str_##unique_id[] __initconst \ + __aligned(1) = str; \ + static struct obs_kernel_param __setup_##unique_id \ + __used __section(".init.setup") \ + __aligned(__alignof__(struct obs_kernel_param)) = \ + { __setup_str_##unique_id, fn, early } + +#define early_param(str, fn) \ + __setup_param(str, fn, fn, 1) + +#endif diff --git a/tools/testing/memblock/linux/kernel.h b/tools/testing/memblock/linux/kernel.h new file mode 100644 index 0000000000000..d2f148bd89022 --- /dev/null +++ b/tools/testing/memblock/linux/kernel.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _MEMBLOCK_LINUX_KERNEL_H +#define _MEMBLOCK_LINUX_KERNEL_H + +#include <../../include/linux/kernel.h> +#include +#include +#include +#include +#include + +#endif diff --git a/tools/testing/memblock/linux/kmemleak.h b/tools/testing/memblock/linux/kmemleak.h new file mode 100644 index 0000000000000..462f8c5e8aa09 --- /dev/null +++ b/tools/testing/memblock/linux/kmemleak.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _KMEMLEAK_H +#define _KMEMLEAK_H + +static inline void kmemleak_free_part_phys(phys_addr_t phys, size_t size) +{ +} + +static inline void kmemleak_alloc_phys(phys_addr_t phys, size_t size, + int min_count, gfp_t gfp) +{ +} + +static inline void dump_stack(void) +{ +} + +#endif diff --git a/tools/testing/memblock/linux/memory_hotplug.h b/tools/testing/memblock/linux/memory_hotplug.h new file mode 100644 index 0000000000000..47988765a2197 --- /dev/null +++ b/tools/testing/memblock/linux/memory_hotplug.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_MEMORY_HOTPLUG_H +#define _LINUX_MEMORY_HOTPLUG_H + +#include +#include +#include +#include + +static inline bool movable_node_is_enabled(void) +{ +#ifdef MOVABLE_NODE + return true; +#else + return false; +#endif +} + +#endif diff --git a/tools/testing/memblock/linux/mmzone.h b/tools/testing/memblock/linux/mmzone.h new file mode 100644 index 0000000000000..7c2eb5c9bb54d --- /dev/null +++ b/tools/testing/memblock/linux/mmzone.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_MMZONE_H +#define _TOOLS_MMZONE_H + +#include + +struct pglist_data *first_online_pgdat(void); +struct pglist_data *next_online_pgdat(struct pglist_data *pgdat); + +#define for_each_online_pgdat(pgdat) \ + for (pgdat = first_online_pgdat(); \ + pgdat; \ + pgdat = next_online_pgdat(pgdat)) + +enum zone_type { + __MAX_NR_ZONES +}; + +#define MAX_NR_ZONES __MAX_NR_ZONES +#define MAX_ORDER 11 +#define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1)) + +#define pageblock_order (MAX_ORDER - 1) +#define pageblock_nr_pages BIT(pageblock_order) + +struct zone { + atomic_long_t managed_pages; +}; + +typedef struct pglist_data { + struct zone node_zones[MAX_NR_ZONES]; + +} pg_data_t; + +#endif diff --git a/tools/testing/memblock/linux/printk.h b/tools/testing/memblock/linux/printk.h new file mode 100644 index 0000000000000..61af424d8c6c3 --- /dev/null +++ b/tools/testing/memblock/linux/printk.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _PRINTK_H +#define _PRINTK_H + +#include +#include + +/* + * memblock_dbg is called with u64 arguments that don't match the "%llu" + * specifier in printf. This results in warnings that cannot be fixed without + * modifying memblock.c, which we wish to avoid. As these messaged are not used + * in testing anyway, the mismatch can be ignored. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#define printk printf +#pragma GCC diagnostic push + +#define pr_info printk +#define pr_debug printk +#define pr_cont printk +#define pr_err printk +#define pr_warn printk + +#endif diff --git a/tools/testing/memblock/main.c b/tools/testing/memblock/main.c new file mode 100644 index 0000000000000..da65b0adee91e --- /dev/null +++ b/tools/testing/memblock/main.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "tests/basic_api.h" + +int main(int argc, char **argv) +{ + memblock_basic_checks(); + return 0; +} diff --git a/tools/testing/memblock/mmzone.c b/tools/testing/memblock/mmzone.c new file mode 100644 index 0000000000000..7b0909e8b759d --- /dev/null +++ b/tools/testing/memblock/mmzone.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include + +struct pglist_data *first_online_pgdat(void) +{ + return NULL; +} + +struct pglist_data *next_online_pgdat(struct pglist_data *pgdat) +{ + return NULL; +} + +void reserve_bootmem_region(phys_addr_t start, phys_addr_t end) +{ +} + +void atomic_long_set(atomic_long_t *v, long i) +{ +} diff --git a/tools/testing/memblock/scripts/Makefile.include b/tools/testing/memblock/scripts/Makefile.include new file mode 100644 index 0000000000000..699b0d6cda074 --- /dev/null +++ b/tools/testing/memblock/scripts/Makefile.include @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# Definitions for user-provided arguments + +# Simulate CONFIG_NUMA=y +ifeq ($(NUMA), 1) + CFLAGS += -D CONFIG_NUMA +endif + +# Simulate movable NUMA memory regions +ifeq ($(MOVABLE_NODE), 1) + CFLAGS += -D MOVABLE_NODE +endif + +# Use 32 bit physical addresses +ifeq ($(32BIT_PHYS_ADDR_T), 1) + CFLAGS += -U CONFIG_PHYS_ADDR_T_64BIT +endif diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c new file mode 100644 index 0000000000000..fbb989f6ddbf8 --- /dev/null +++ b/tools/testing/memblock/tests/basic_api.c @@ -0,0 +1,906 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include +#include +#include "basic_api.h" + +#define EXPECTED_MEMBLOCK_REGIONS 128 + +static int memblock_initialization_check(void) +{ + reset_memblock(); + + assert(memblock.memory.regions); + assert(memblock.memory.cnt == 1); + assert(memblock.memory.max == EXPECTED_MEMBLOCK_REGIONS); + assert(strcmp(memblock.memory.name, "memory") == 0); + + assert(memblock.reserved.regions); + assert(memblock.reserved.cnt == 1); + assert(memblock.memory.max == EXPECTED_MEMBLOCK_REGIONS); + assert(strcmp(memblock.reserved.name, "reserved") == 0); + + assert(!memblock.bottom_up); + assert(memblock.current_limit == MEMBLOCK_ALLOC_ANYWHERE); + + return 0; +} + +/* + * A simple test that adds a memory block of a specified base address + * and size to the collection of available memory regions (memblock.memory). + * It checks if a new entry was created and if region counter and total memory + * were correctly updated. + */ +static int memblock_add_simple_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.memory.regions[0]; + + struct region r = { + .base = SZ_1G, + .size = SZ_4M + }; + + reset_memblock(); + memblock_add(r.base, r.size); + + assert(rgn->base == r.base); + assert(rgn->size == r.size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == r.size); + + return 0; +} + +/* + * A simple test that adds a memory block of a specified base address, size + * NUMA node and memory flags to the collection of available memory regions. + * It checks if the new entry, region counter and total memory size have + * expected values. + */ +static int memblock_add_node_simple_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.memory.regions[0]; + + struct region r = { + .base = SZ_1M, + .size = SZ_16M + }; + + reset_memblock(); + memblock_add_node(r.base, r.size, 1, MEMBLOCK_HOTPLUG); + + assert(rgn->base == r.base); + assert(rgn->size == r.size); +#ifdef CONFIG_NUMA + assert(rgn->nid == 1); +#endif + assert(rgn->flags == MEMBLOCK_HOTPLUG); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == r.size); + + return 0; +} + +/* + * A test that tries to add two memory blocks that don't overlap with one + * another. It checks if two correctly initialized entries were added to the + * collection of available memory regions (memblock.memory) and if this + * change was reflected in memblock.memory's total size and region counter. + */ +static int memblock_add_disjoint_check(void) +{ + struct memblock_region *rgn1, *rgn2; + + rgn1 = &memblock.memory.regions[0]; + rgn2 = &memblock.memory.regions[1]; + + struct region r1 = { + .base = SZ_1G, + .size = SZ_8K + }; + struct region r2 = { + .base = SZ_1G + SZ_16K, + .size = SZ_8K + }; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_add(r2.base, r2.size); + + assert(rgn1->base == r1.base); + assert(rgn1->size == r1.size); + + assert(rgn2->base == r2.base); + assert(rgn2->size == r2.size); + + assert(memblock.memory.cnt == 2); + assert(memblock.memory.total_size == r1.size + r2.size); + + return 0; +} + +/* + * A test that tries to add two memory blocks, where the second one overlaps + * with the beginning of the first entry (that is r1.base < r2.base + r2.size). + * After this, it checks if two entries are merged into one region that starts + * at r2.base and has size of two regions minus their intersection. It also + * verifies the reported total size of the available memory and region counter. + */ +static int memblock_add_overlap_top_check(void) +{ + struct memblock_region *rgn; + phys_addr_t total_size; + + rgn = &memblock.memory.regions[0]; + + struct region r1 = { + .base = SZ_512M, + .size = SZ_1G + }; + struct region r2 = { + .base = SZ_256M, + .size = SZ_512M + }; + + total_size = (r1.base - r2.base) + r1.size; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_add(r2.base, r2.size); + + assert(rgn->base == r2.base); + assert(rgn->size == total_size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == total_size); + + return 0; +} + +/* + * A test that tries to add two memory blocks, where the second one overlaps + * with the end of the first entry (that is r2.base < r1.base + r1.size). + * After this, it checks if two entries are merged into one region that starts + * at r1.base and has size of two regions minus their intersection. It verifies + * that memblock can still see only one entry and has a correct total size of + * the available memory. + */ +static int memblock_add_overlap_bottom_check(void) +{ + struct memblock_region *rgn; + phys_addr_t total_size; + + rgn = &memblock.memory.regions[0]; + + struct region r1 = { + .base = SZ_128M, + .size = SZ_512M + }; + struct region r2 = { + .base = SZ_256M, + .size = SZ_1G + }; + + total_size = (r2.base - r1.base) + r2.size; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_add(r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == total_size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == total_size); + + return 0; +} + +/* + * A test that tries to add two memory blocks, where the second one is + * within the range of the first entry (that is r1.base < r2.base && + * r2.base + r2.size < r1.base + r1.size). It checks if two entries are merged + * into one region that stays the same. The counter and total size of available + * memory are expected to not be updated. + */ +static int memblock_add_within_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.memory.regions[0]; + + struct region r1 = { + .base = SZ_8M, + .size = SZ_32M + }; + struct region r2 = { + .base = SZ_16M, + .size = SZ_1M + }; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_add(r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == r1.size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == r1.size); + + return 0; +} + +/* + * A simple test that tries to add the same memory block twice. The counter + * and total size of available memory are expected to not be updated. + */ +static int memblock_add_twice_check(void) +{ + struct region r = { + .base = SZ_16K, + .size = SZ_2M + }; + + reset_memblock(); + + memblock_add(r.base, r.size); + memblock_add(r.base, r.size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == r.size); + + return 0; +} + +static int memblock_add_checks(void) +{ + memblock_add_simple_check(); + memblock_add_node_simple_check(); + memblock_add_disjoint_check(); + memblock_add_overlap_top_check(); + memblock_add_overlap_bottom_check(); + memblock_add_within_check(); + memblock_add_twice_check(); + + return 0; +} + + /* + * A simple test that marks a memory block of a specified base address + * and size as reserved and to the collection of reserved memory regions + * (memblock.reserved). It checks if a new entry was created and if region + * counter and total memory size were correctly updated. + */ +static int memblock_reserve_simple_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.reserved.regions[0]; + + struct region r = { + .base = SZ_2G, + .size = SZ_128M + }; + + reset_memblock(); + memblock_reserve(r.base, r.size); + + assert(rgn->base == r.base); + assert(rgn->size == r.size); + + return 0; +} + +/* + * A test that tries to mark two memory blocks that don't overlap as reserved + * and checks if two entries were correctly added to the collection of reserved + * memory regions (memblock.reserved) and if this change was reflected in + * memblock.reserved's total size and region counter. + */ +static int memblock_reserve_disjoint_check(void) +{ + struct memblock_region *rgn1, *rgn2; + + rgn1 = &memblock.reserved.regions[0]; + rgn2 = &memblock.reserved.regions[1]; + + struct region r1 = { + .base = SZ_256M, + .size = SZ_16M + }; + struct region r2 = { + .base = SZ_512M, + .size = SZ_512M + }; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_reserve(r2.base, r2.size); + + assert(rgn1->base == r1.base); + assert(rgn1->size == r1.size); + + assert(rgn2->base == r2.base); + assert(rgn2->size == r2.size); + + assert(memblock.reserved.cnt == 2); + assert(memblock.reserved.total_size == r1.size + r2.size); + + return 0; +} + +/* + * A test that tries to mark two memory blocks as reserved, where the + * second one overlaps with the beginning of the first (that is + * r1.base < r2.base + r2.size). + * It checks if two entries are merged into one region that starts at r2.base + * and has size of two regions minus their intersection. The test also verifies + * that memblock can still see only one entry and has a correct total size of + * the reserved memory. + */ +static int memblock_reserve_overlap_top_check(void) +{ + struct memblock_region *rgn; + phys_addr_t total_size; + + rgn = &memblock.reserved.regions[0]; + + struct region r1 = { + .base = SZ_1G, + .size = SZ_1G + }; + struct region r2 = { + .base = SZ_128M, + .size = SZ_1G + }; + + total_size = (r1.base - r2.base) + r1.size; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_reserve(r2.base, r2.size); + + assert(rgn->base == r2.base); + assert(rgn->size == total_size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == total_size); + + return 0; +} + +/* + * A test that tries to mark two memory blocks as reserved, where the + * second one overlaps with the end of the first entry (that is + * r2.base < r1.base + r1.size). + * It checks if two entries are merged into one region that starts at r1.base + * and has size of two regions minus their intersection. It verifies that + * memblock can still see only one entry and has a correct total size of the + * reserved memory. + */ +static int memblock_reserve_overlap_bottom_check(void) +{ + struct memblock_region *rgn; + phys_addr_t total_size; + + rgn = &memblock.reserved.regions[0]; + + struct region r1 = { + .base = SZ_2K, + .size = SZ_128K + }; + struct region r2 = { + .base = SZ_128K, + .size = SZ_128K + }; + + total_size = (r2.base - r1.base) + r2.size; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_reserve(r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == total_size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == total_size); + + return 0; +} + +/* + * A test that tries to mark two memory blocks as reserved, where the second + * one is within the range of the first entry (that is + * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)). + * It checks if two entries are merged into one region that stays the + * same. The counter and total size of available memory are expected to not be + * updated. + */ +static int memblock_reserve_within_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.reserved.regions[0]; + + struct region r1 = { + .base = SZ_1M, + .size = SZ_8M + }; + struct region r2 = { + .base = SZ_2M, + .size = SZ_64K + }; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_reserve(r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == r1.size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == r1.size); + + return 0; +} + +/* + * A simple test that tries to reserve the same memory block twice. + * The region counter and total size of reserved memory are expected to not + * be updated. + */ +static int memblock_reserve_twice_check(void) +{ + struct region r = { + .base = SZ_16K, + .size = SZ_2M + }; + + reset_memblock(); + + memblock_reserve(r.base, r.size); + memblock_reserve(r.base, r.size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == r.size); + + return 0; +} + +static int memblock_reserve_checks(void) +{ + memblock_reserve_simple_check(); + memblock_reserve_disjoint_check(); + memblock_reserve_overlap_top_check(); + memblock_reserve_overlap_bottom_check(); + memblock_reserve_within_check(); + memblock_reserve_twice_check(); + + return 0; +} + + /* + * A simple test that tries to remove the first entry of the array of + * available memory regions. By "removing" a region we mean overwriting it + * with the next region in memblock.memory. To check this is the case, the + * test adds two memory blocks and verifies that the value of the latter + * was used to erase r1 region. It also checks if the region counter and + * total size were updated to expected values. + */ +static int memblock_remove_simple_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.memory.regions[0]; + + struct region r1 = { + .base = SZ_2K, + .size = SZ_4K + }; + struct region r2 = { + .base = SZ_128K, + .size = SZ_4M + }; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_add(r2.base, r2.size); + memblock_remove(r1.base, r1.size); + + assert(rgn->base == r2.base); + assert(rgn->size == r2.size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == r2.size); + + return 0; +} + + /* + * A test that tries to remove a region that was not registered as available + * memory (i.e. has no corresponding entry in memblock.memory). It verifies + * that array, regions counter and total size were not modified. + */ +static int memblock_remove_absent_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.memory.regions[0]; + + struct region r1 = { + .base = SZ_512K, + .size = SZ_4M + }; + struct region r2 = { + .base = SZ_64M, + .size = SZ_1G + }; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_remove(r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == r1.size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == r1.size); + + return 0; +} + +/* + * A test that tries to remove a region which overlaps with the beginning of + * the already existing entry r1 (that is r1.base < r2.base + r2.size). It + * checks if only the intersection of both regions is removed from the available + * memory pool. The test also checks if the regions counter and total size are + * updated to expected values. + */ +static int memblock_remove_overlap_top_check(void) +{ + struct memblock_region *rgn; + phys_addr_t r1_end, r2_end, total_size; + + rgn = &memblock.memory.regions[0]; + + struct region r1 = { + .base = SZ_32M, + .size = SZ_32M + }; + struct region r2 = { + .base = SZ_16M, + .size = SZ_32M + }; + + r1_end = r1.base + r1.size; + r2_end = r2.base + r2.size; + total_size = r1_end - r2_end; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_remove(r2.base, r2.size); + + assert(rgn->base == r1.base + r2.base); + assert(rgn->size == total_size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == total_size); + + return 0; +} + +/* + * A test that tries to remove a region which overlaps with the end of the + * first entry (that is r2.base < r1.base + r1.size). It checks if only the + * intersection of both regions is removed from the available memory pool. + * The test also checks if the regions counter and total size are updated to + * expected values. + */ +static int memblock_remove_overlap_bottom_check(void) +{ + struct memblock_region *rgn; + phys_addr_t total_size; + + rgn = &memblock.memory.regions[0]; + + struct region r1 = { + .base = SZ_2M, + .size = SZ_64M + }; + struct region r2 = { + .base = SZ_32M, + .size = SZ_256M + }; + + total_size = r2.base - r1.base; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_remove(r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == total_size); + + assert(memblock.memory.cnt == 1); + assert(memblock.memory.total_size == total_size); + return 0; +} + +/* + * A test that tries to remove a region which is within the range of the + * already existing entry (that is + * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)). + * It checks if the region is split into two - one that ends at r2.base and + * second that starts at r2.base + size, with appropriate sizes. The test + * also checks if the region counter and total size were updated to + * expected values. + */ +static int memblock_remove_within_check(void) +{ + struct memblock_region *rgn1, *rgn2; + phys_addr_t r1_size, r2_size, total_size; + + rgn1 = &memblock.memory.regions[0]; + rgn2 = &memblock.memory.regions[1]; + + struct region r1 = { + .base = SZ_1M, + .size = SZ_32M + }; + struct region r2 = { + .base = SZ_16M, + .size = SZ_1M + }; + + r1_size = r2.base - r1.base; + r2_size = (r1.base + r1.size) - (r2.base + r2.size); + total_size = r1_size + r2_size; + + reset_memblock(); + memblock_add(r1.base, r1.size); + memblock_remove(r2.base, r2.size); + + assert(rgn1->base == r1.base); + assert(rgn1->size == r1_size); + + assert(rgn2->base == r2.base + r2.size); + assert(rgn2->size == r2_size); + + assert(memblock.memory.cnt == 2); + assert(memblock.memory.total_size == total_size); + + return 0; +} + +static int memblock_remove_checks(void) +{ + memblock_remove_simple_check(); + memblock_remove_absent_check(); + memblock_remove_overlap_top_check(); + memblock_remove_overlap_bottom_check(); + memblock_remove_within_check(); + + return 0; +} + +/* + * A simple test that tries to free a memory block that was marked earlier + * as reserved. By "freeing" a region we mean overwriting it with the next + * entry in memblock.reserved. To check this is the case, the test reserves + * two memory regions and verifies that the value of the latter was used to + * erase r1 region. + * The test also checks if the region counter and total size were updated. + */ +static int memblock_free_simple_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.reserved.regions[0]; + + struct region r1 = { + .base = SZ_4M, + .size = SZ_1M + }; + struct region r2 = { + .base = SZ_8M, + .size = SZ_1M + }; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_reserve(r2.base, r2.size); + memblock_free((void *)r1.base, r1.size); + + assert(rgn->base == r2.base); + assert(rgn->size == r2.size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == r2.size); + + return 0; +} + + /* + * A test that tries to free a region that was not marked as reserved + * (i.e. has no corresponding entry in memblock.reserved). It verifies + * that array, regions counter and total size were not modified. + */ +static int memblock_free_absent_check(void) +{ + struct memblock_region *rgn; + + rgn = &memblock.reserved.regions[0]; + + struct region r1 = { + .base = SZ_2M, + .size = SZ_8K + }; + struct region r2 = { + .base = SZ_16M, + .size = SZ_128M + }; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_free((void *)r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == r1.size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == r1.size); + + return 0; +} + +/* + * A test that tries to free a region which overlaps with the beginning of + * the already existing entry r1 (that is r1.base < r2.base + r2.size). It + * checks if only the intersection of both regions is freed. The test also + * checks if the regions counter and total size are updated to expected + * values. + */ +static int memblock_free_overlap_top_check(void) +{ + struct memblock_region *rgn; + phys_addr_t total_size; + + rgn = &memblock.reserved.regions[0]; + + struct region r1 = { + .base = SZ_8M, + .size = SZ_32M + }; + struct region r2 = { + .base = SZ_1M, + .size = SZ_8M + }; + + total_size = (r1.size + r1.base) - (r2.base + r2.size); + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_free((void *)r2.base, r2.size); + + assert(rgn->base == r2.base + r2.size); + assert(rgn->size == total_size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == total_size); + + return 0; +} + +/* + * A test that tries to free a region which overlaps with the end of the + * first entry (that is r2.base < r1.base + r1.size). It checks if only the + * intersection of both regions is freed. The test also checks if the + * regions counter and total size are updated to expected values. + */ +static int memblock_free_overlap_bottom_check(void) +{ + struct memblock_region *rgn; + phys_addr_t total_size; + + rgn = &memblock.reserved.regions[0]; + + struct region r1 = { + .base = SZ_8M, + .size = SZ_32M + }; + struct region r2 = { + .base = SZ_32M, + .size = SZ_32M + }; + + total_size = r2.base - r1.base; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_free((void *)r2.base, r2.size); + + assert(rgn->base == r1.base); + assert(rgn->size == total_size); + + assert(memblock.reserved.cnt == 1); + assert(memblock.reserved.total_size == total_size); + + return 0; +} + +/* + * A test that tries to free a region which is within the range of the + * already existing entry (that is + * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)). + * It checks if the region is split into two - one that ends at r2.base and + * second that starts at r2.base + size, with appropriate sizes. It is + * expected that the region counter and total size fields were updated t + * reflect that change. + */ +static int memblock_free_within_check(void) +{ + struct memblock_region *rgn1, *rgn2; + phys_addr_t r1_size, r2_size, total_size; + + rgn1 = &memblock.reserved.regions[0]; + rgn2 = &memblock.reserved.regions[1]; + + struct region r1 = { + .base = SZ_1M, + .size = SZ_8M + }; + struct region r2 = { + .base = SZ_4M, + .size = SZ_1M + }; + + r1_size = r2.base - r1.base; + r2_size = (r1.base + r1.size) - (r2.base + r2.size); + total_size = r1_size + r2_size; + + reset_memblock(); + memblock_reserve(r1.base, r1.size); + memblock_free((void *)r2.base, r2.size); + + assert(rgn1->base == r1.base); + assert(rgn1->size == r1_size); + + assert(rgn2->base == r2.base + r2.size); + assert(rgn2->size == r2_size); + + assert(memblock.reserved.cnt == 2); + assert(memblock.reserved.total_size == total_size); + + return 0; +} + +static int memblock_free_checks(void) +{ + memblock_free_simple_check(); + memblock_free_absent_check(); + memblock_free_overlap_top_check(); + memblock_free_overlap_bottom_check(); + memblock_free_within_check(); + + return 0; +} + +int memblock_basic_checks(void) +{ + memblock_initialization_check(); + memblock_add_checks(); + memblock_reserve_checks(); + memblock_remove_checks(); + memblock_free_checks(); + + return 0; +} diff --git a/tools/testing/memblock/tests/basic_api.h b/tools/testing/memblock/tests/basic_api.h new file mode 100644 index 0000000000000..1ceecfca1f47c --- /dev/null +++ b/tools/testing/memblock/tests/basic_api.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _MEMBLOCK_BASIC_H +#define _MEMBLOCK_BASIC_H + +#include +#include "common.h" + +int memblock_basic_checks(void); + +#endif diff --git a/tools/testing/memblock/tests/common.c b/tools/testing/memblock/tests/common.c new file mode 100644 index 0000000000000..03de6eab0c3c9 --- /dev/null +++ b/tools/testing/memblock/tests/common.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "tests/common.h" +#include + +#define INIT_MEMBLOCK_REGIONS 128 +#define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS + +void reset_memblock(void) +{ + memset(memblock.memory.regions, 0, + memblock.memory.cnt * sizeof(struct memblock_region)); + memset(memblock.reserved.regions, 0, + memblock.reserved.cnt * sizeof(struct memblock_region)); + + memblock.memory.cnt = 1; + memblock.memory.max = INIT_MEMBLOCK_REGIONS; + memblock.memory.name = "memory"; + memblock.memory.total_size = 0; + + memblock.reserved.cnt = 1; + memblock.reserved.max = INIT_MEMBLOCK_RESERVED_REGIONS; + memblock.reserved.name = "reserved"; + memblock.reserved.total_size = 0; + + memblock.bottom_up = false; + memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE; +} diff --git a/tools/testing/memblock/tests/common.h b/tools/testing/memblock/tests/common.h new file mode 100644 index 0000000000000..48efc4270ea17 --- /dev/null +++ b/tools/testing/memblock/tests/common.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _MEMBLOCK_TEST_H +#define _MEMBLOCK_TEST_H + +#include +#include + +struct region { + phys_addr_t base; + phys_addr_t size; +}; + +void reset_memblock(void); + +#endif diff --git a/tools/testing/radix-tree/Makefile b/tools/testing/radix-tree/Makefile index aa6abfe0749c1..c4ea4fbb0bfcd 100644 --- a/tools/testing/radix-tree/Makefile +++ b/tools/testing/radix-tree/Makefile @@ -5,7 +5,8 @@ CFLAGS += -I. -I../../include -g -Og -Wall -D_LGPL_SOURCE -fsanitize=address \ LDFLAGS += -fsanitize=address -fsanitize=undefined LDLIBS+= -lpthread -lurcu TARGETS = main idr-test multiorder xarray -CORE_OFILES := xarray.o radix-tree.o idr.o linux.o test.o find_bit.o bitmap.o +CORE_OFILES := xarray.o radix-tree.o idr.o linux.o test.o find_bit.o bitmap.o \ + slab.o OFILES = main.o $(CORE_OFILES) regression1.o regression2.o regression3.o \ regression4.o tag_check.o multiorder.o idr-test.o iteration_check.o \ iteration_check_2.o benchmark.o diff --git a/tools/testing/radix-tree/linux.c b/tools/testing/radix-tree/linux.c index 2d9c59df60de0..81539f5439546 100644 --- a/tools/testing/radix-tree/linux.c +++ b/tools/testing/radix-tree/linux.c @@ -14,7 +14,6 @@ int nr_allocated; int preempt_count; -int kmalloc_verbose; int test_verbose; struct kmem_cache { @@ -78,32 +77,6 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp) pthread_mutex_unlock(&cachep->lock); } -void *kmalloc(size_t size, gfp_t gfp) -{ - void *ret; - - if (!(gfp & __GFP_DIRECT_RECLAIM)) - return NULL; - - ret = malloc(size); - uatomic_inc(&nr_allocated); - if (kmalloc_verbose) - printf("Allocating %p from malloc\n", ret); - if (gfp & __GFP_ZERO) - memset(ret, 0, size); - return ret; -} - -void kfree(void *p) -{ - if (!p) - return; - uatomic_dec(&nr_allocated); - if (kmalloc_verbose) - printf("Freeing %p to malloc\n", p); - free(p); -} - struct kmem_cache * kmem_cache_create(const char *name, unsigned int size, unsigned int align, unsigned int flags, void (*ctor)(void *)) diff --git a/tools/testing/radix-tree/linux/gfp.h b/tools/testing/radix-tree/linux/gfp.h deleted file mode 100644 index 32159c08a52e5..0000000000000 --- a/tools/testing/radix-tree/linux/gfp.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _GFP_H -#define _GFP_H - -#include - -#define __GFP_BITS_SHIFT 26 -#define __GFP_BITS_MASK ((gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) - -#define __GFP_HIGH 0x20u -#define __GFP_IO 0x40u -#define __GFP_FS 0x80u -#define __GFP_NOWARN 0x200u -#define __GFP_ZERO 0x8000u -#define __GFP_ATOMIC 0x80000u -#define __GFP_ACCOUNT 0x100000u -#define __GFP_DIRECT_RECLAIM 0x400000u -#define __GFP_KSWAPD_RECLAIM 0x2000000u - -#define __GFP_RECLAIM (__GFP_DIRECT_RECLAIM|__GFP_KSWAPD_RECLAIM) - -#define GFP_ZONEMASK 0x0fu -#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM) -#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) -#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) - - -static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) -{ - return !!(gfp_flags & __GFP_DIRECT_RECLAIM); -} - -#endif