linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/16] Introduce memblock simulator
@ 2022-01-27 13:21 Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib Karolina Drobnik
                   ` (15 more replies)
  0 siblings, 16 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Memblock is a boot time memory allocator, which allows managing memory
regions before the actual memory management is initialized. Because it is
used so early during the booting process, testing and debugging it is
difficult. As memblock has few kernel dependencies, it is possible to
simulate its runtime behaviour in userspace after stubbing a couple of
structs and functions.

This series of patches adds an initial version of a test suite for
memblock, which is a part of tools/testing infrastructure. Checks included
here test the basic functionality of memblock, which is memory regions
management - adding/removing available regions, marking them as reserved
or freeing them.

To run the tests, build the main target and run it:

$ make; ./main

A successful run produces no output. Also, It is possible to override
different configuration parameters. For example, to simulate enabled NUMA,
use:

$ make NUMA=1

For the full list of options, see `make help`.

The future work will include tests for memory allocation done via
memblock_alloc_* and memblock_phys_alloc_* family of functions. It will
also focus on improving the test suite by adding dedicated test targets
for each group of API functions and verbose output.

For a refresher on memblock, see Boot time memory management
documentation page[1] and "Getting to know memblock"[2] blog post.

Patchset structure:

* Patch 1 extracts stub definitions of kmalloc/kfree from the radix-tree
  testing suite, so they can be used in other tests, including memblock
  simulator
* Patches 2-4 update tools headers to include missing definitions needed
  by memblock (e.g. phys_addr_t typedef)
* Patches 5-9 add new files to tools/include, some with dummy/downsized
  definitions
* Patch 10 adds the basic project with local stubs that are closely
  connected to memblock
* Patch 11 adds a reset function, which is used as a part of the test
  setup. This functionality is needed, as memblock is reused in each check
* Patches 12-16 add basic test cases for the core memblock functionalities

[1] - https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html
[2] - https://insecuremode.com/post/2021/12/14/getting-to-know-memblock.html

Karolina Drobnik (16):
  tools: Move gfp.h and slab.h from radix-tree to lib
  tools/include: Add phys_addr_t to types.h
  tools/include: Add _RET_IP_ and math definitions to kernel.h
  tools/include: Update atomic.h header
  tools/include: Add mm.h file
  tools/include: Add cache.h stub
  tools/include: Add io.h stub
  tools/include: Add pfn.h stub
  tools/include: Add debugfs.h stub
  memblock tests: Add skeleton of the memblock simulator
  memblock tests: Add memblock reset function
  memblock tests: Add memblock_add tests
  memblock tests: Add memblock_reserve tests
  memblock tests: Add memblock_remove tests
  memblock tests: Add memblock_add_node test
  memblock tests: Add memblock_free tests

 MAINTAINERS                                   |   1 +
 tools/include/linux/atomic.h                  |   4 +
 tools/include/linux/cache.h                   |  10 +
 tools/include/linux/debugfs.h                 |   5 +
 tools/include/linux/gfp.h                     |  28 +
 tools/include/linux/io.h                      |   5 +
 tools/include/linux/kernel.h                  |   6 +
 tools/include/linux/mm.h                      |  42 +
 tools/include/linux/pfn.h                     |  10 +
 .../radix-tree => include}/linux/slab.h       |  25 +-
 tools/include/linux/types.h                   |   6 +
 tools/lib/slab.c                              |  38 +
 tools/testing/memblock/.gitignore             |   6 +
 tools/testing/memblock/Makefile               |  53 ++
 tools/testing/memblock/asm/dma.h              |   5 +
 tools/testing/memblock/internal.h             |  12 +
 tools/testing/memblock/lib/slab.c             |   9 +
 tools/testing/memblock/linux/init.h           |  34 +
 tools/testing/memblock/linux/kernel.h         |  12 +
 tools/testing/memblock/linux/kmemleak.h       |  18 +
 tools/testing/memblock/linux/memory_hotplug.h |  19 +
 tools/testing/memblock/linux/mmzone.h         |  35 +
 tools/testing/memblock/linux/printk.h         |  25 +
 tools/testing/memblock/main.c                 |   8 +
 tools/testing/memblock/mmzone.c               |  20 +
 .../testing/memblock/scripts/Makefile.include |  17 +
 tools/testing/memblock/tests/basic_api.c      | 896 ++++++++++++++++++
 tools/testing/memblock/tests/basic_api.h      |  10 +
 tools/testing/memblock/tests/common.c         |  27 +
 tools/testing/memblock/tests/common.h         |  15 +
 tools/testing/radix-tree/Makefile             |   3 +-
 tools/testing/radix-tree/linux.c              |  27 -
 tools/testing/radix-tree/linux/gfp.h          |  33 -
 33 files changed, 1396 insertions(+), 68 deletions(-)
 create mode 100644 tools/include/linux/cache.h
 create mode 100644 tools/include/linux/debugfs.h
 create mode 100644 tools/include/linux/io.h
 create mode 100644 tools/include/linux/mm.h
 create mode 100644 tools/include/linux/pfn.h
 rename tools/{testing/radix-tree => include}/linux/slab.h (61%)
 create mode 100644 tools/lib/slab.c
 create mode 100644 tools/testing/memblock/.gitignore
 create mode 100644 tools/testing/memblock/Makefile
 create mode 100644 tools/testing/memblock/asm/dma.h
 create mode 100644 tools/testing/memblock/internal.h
 create mode 100644 tools/testing/memblock/lib/slab.c
 create mode 100644 tools/testing/memblock/linux/init.h
 create mode 100644 tools/testing/memblock/linux/kernel.h
 create mode 100644 tools/testing/memblock/linux/kmemleak.h
 create mode 100644 tools/testing/memblock/linux/memory_hotplug.h
 create mode 100644 tools/testing/memblock/linux/mmzone.h
 create mode 100644 tools/testing/memblock/linux/printk.h
 create mode 100644 tools/testing/memblock/main.c
 create mode 100644 tools/testing/memblock/mmzone.c
 create mode 100644 tools/testing/memblock/scripts/Makefile.include
 create mode 100644 tools/testing/memblock/tests/basic_api.c
 create mode 100644 tools/testing/memblock/tests/basic_api.h
 create mode 100644 tools/testing/memblock/tests/common.c
 create mode 100644 tools/testing/memblock/tests/common.h
 delete mode 100644 tools/testing/radix-tree/linux/gfp.h

--
2.30.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:28   ` Matthew Wilcox
  2022-01-27 13:36   ` Matthew Wilcox
  2022-01-27 13:21 ` [PATCH 02/16] tools/include: Add phys_addr_t to types.h Karolina Drobnik
                   ` (14 subsequent siblings)
  15 siblings, 2 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Merge radix-tree definitions from gfp.h and slab.h with these
in tools/lib, so they can be used in other test suites.
Fix style issues in slab.h. Update radix-tree test files.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/gfp.h                     | 28 ++++++++++++++
 .../radix-tree => include}/linux/slab.h       | 15 ++++----
 tools/lib/slab.c                              | 38 +++++++++++++++++++
 tools/testing/radix-tree/Makefile             |  3 +-
 tools/testing/radix-tree/linux.c              | 27 -------------
 tools/testing/radix-tree/linux/gfp.h          | 33 ----------------
 6 files changed, 76 insertions(+), 68 deletions(-)
 rename tools/{testing/radix-tree => include}/linux/slab.h (68%)
 create mode 100644 tools/lib/slab.c
 delete mode 100644 tools/testing/radix-tree/linux/gfp.h

diff --git a/tools/include/linux/gfp.h b/tools/include/linux/gfp.h
index 22030756fbc0..4dce3cddd134 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 <linux/types.h>
+
+#define __GFP_ZERO		0x8000u
+#define __GFP_DIRECT_RECLAIM	0x400000u
+
+#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_ATOMIC		0x80000u
+#define __GFP_ACCOUNT		0x100000u
+#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/testing/radix-tree/linux/slab.h b/tools/include/linux/slab.h
similarity index 68%
rename from tools/testing/radix-tree/linux/slab.h
rename to tools/include/linux/slab.h
index 2958830ce4d7..07d7930d4003 100644
--- a/tools/testing/radix-tree/linux/slab.h
+++ b/tools/include/linux/slab.h
@@ -1,20 +1,21 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef SLAB_H
-#define SLAB_H
+#ifndef _TOOLS_SLAB_H
+#define _TOOLS_SLAB_H
 
 #include <linux/types.h>
 #include <linux/gfp.h>
 
-#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);
 
 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 +25,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/lib/slab.c b/tools/lib/slab.c
new file mode 100644
index 000000000000..959997fb0652
--- /dev/null
+++ b/tools/lib/slab.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <string.h>
+
+#include <urcu/uatomic.h>
+#include <linux/slab.h>
+#include <malloc.h>
+#include <linux/gfp.h>
+
+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/radix-tree/Makefile b/tools/testing/radix-tree/Makefile
index aa6abfe0749c..c4ea4fbb0bfc 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 2d9c59df60de..81539f543954 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 32159c08a52e..000000000000
--- 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 <linux/types.h>
-
-#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
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 02/16] tools/include: Add phys_addr_t to types.h
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h Karolina Drobnik
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Update types.h file to include phys_addr_t typedef so it can
be used in testing.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/types.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h
index 6e14a533ab4e..35cedaf191e8 100644
--- a/tools/include/linux/types.h
+++ b/tools/include/linux/types.h
@@ -64,6 +64,12 @@ 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;
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 02/16] tools/include: Add phys_addr_t to types.h Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:54   ` Matthew Wilcox
  2022-01-27 13:21 ` [PATCH 04/16] tools/include: Update atomic.h header Karolina Drobnik
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add max_t, min_t and clamp functions, together with _RET_IP_
definition, so they can be used in testing.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/kernel.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h
index 9701e8307db0..4b0673bf52c2 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)
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 04/16] tools/include: Update atomic.h header
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (2 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:56   ` Matthew Wilcox
  2022-01-27 13:21 ` [PATCH 05/16] tools/include: Add mm.h file Karolina Drobnik
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add atomic_long_t typedef and atomic_long_set function so they
 can be used in testing.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/atomic.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h
index 00a6c4ca562b..5d2431889606 100644
--- a/tools/include/linux/atomic.h
+++ b/tools/include/linux/atomic.h
@@ -4,6 +4,10 @@
 
 #include <asm/atomic.h>
 
+typedef atomic_t atomic_long_t;
+
+void atomic_long_set(atomic_long_t *v, long i);
+
 /* atomic_cmpxchg_relaxed */
 #ifndef atomic_cmpxchg_relaxed
 #define  atomic_cmpxchg_relaxed		atomic_cmpxchg
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 05/16] tools/include: Add mm.h file
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (3 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 04/16] tools/include: Update atomic.h header Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 06/16] tools/include: Add cache.h stub Karolina Drobnik
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add a stubbed mm.h file with dummy page-related definitions,
memory alignment and physical to virtual address conversions,
so they can be used in testing.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/mm.h | 42 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 tools/include/linux/mm.h

diff --git a/tools/include/linux/mm.h b/tools/include/linux/mm.h
new file mode 100644
index 000000000000..a03d9bba5151
--- /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 <linux/mmzone.h>
+#include <uapi/linux/const.h>
+
+#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
--
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 06/16] tools/include: Add cache.h stub
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (4 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 05/16] tools/include: Add mm.h file Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 14:00   ` Matthew Wilcox
  2022-01-27 13:21 ` [PATCH 07/16] tools/include: Add io.h stub Karolina Drobnik
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add a dummy version of the cache header.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/cache.h | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 tools/include/linux/cache.h

diff --git a/tools/include/linux/cache.h b/tools/include/linux/cache.h
new file mode 100644
index 000000000000..ff010a11f47d
--- /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		BIT(L1_CACHE_SHIFT)
+
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+
+#endif
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 07/16] tools/include: Add io.h stub
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (5 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 06/16] tools/include: Add cache.h stub Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 14:09   ` Matthew Wilcox
  2022-01-27 13:21 ` [PATCH 08/16] tools/include: Add pfn.h stub Karolina Drobnik
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add a dummy io.h header.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/io.h | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 tools/include/linux/io.h

diff --git a/tools/include/linux/io.h b/tools/include/linux/io.h
new file mode 100644
index 000000000000..e129871fe661
--- /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
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 08/16] tools/include: Add pfn.h stub
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (6 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 07/16] tools/include: Add io.h stub Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 09/16] tools/include: Add debugfs.h stub Karolina Drobnik
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add a stubbed pfn header with definitions used in testing.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/pfn.h | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 tools/include/linux/pfn.h

diff --git a/tools/include/linux/pfn.h b/tools/include/linux/pfn.h
new file mode 100644
index 000000000000..7512a58189eb
--- /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 <linux/mm.h>
+
+#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
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 09/16] tools/include: Add debugfs.h stub
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (7 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 08/16] tools/include: Add pfn.h stub Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator Karolina Drobnik
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add a dummy debugfs.h header.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/include/linux/debugfs.h | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 tools/include/linux/debugfs.h

diff --git a/tools/include/linux/debugfs.h b/tools/include/linux/debugfs.h
new file mode 100644
index 000000000000..4ba06140b1be
--- /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
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (8 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 09/16] tools/include: Add debugfs.h stub Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 14:02   ` Matthew Wilcox
  2022-01-27 14:06   ` Matthew Wilcox
  2022-01-27 13:21 ` [PATCH 11/16] memblock tests: Add memblock reset function Karolina Drobnik
                   ` (5 subsequent siblings)
  15 siblings, 2 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add basic project files, together with local stubs of required headers.
Update tools/include/slab.h to include definitions used by memblock.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 MAINTAINERS                                   |  1 +
 tools/include/linux/slab.h                    | 10 ++++
 tools/testing/memblock/.gitignore             |  6 +++
 tools/testing/memblock/Makefile               | 51 +++++++++++++++++++
 tools/testing/memblock/asm/dma.h              |  5 ++
 tools/testing/memblock/internal.h             | 12 +++++
 tools/testing/memblock/lib/slab.c             |  9 ++++
 tools/testing/memblock/linux/init.h           | 34 +++++++++++++
 tools/testing/memblock/linux/kernel.h         | 12 +++++
 tools/testing/memblock/linux/kmemleak.h       | 18 +++++++
 tools/testing/memblock/linux/memory_hotplug.h | 19 +++++++
 tools/testing/memblock/linux/mmzone.h         | 35 +++++++++++++
 tools/testing/memblock/linux/printk.h         | 25 +++++++++
 tools/testing/memblock/main.c                 |  6 +++
 tools/testing/memblock/mmzone.c               | 20 ++++++++
 .../testing/memblock/scripts/Makefile.include | 17 +++++++
 16 files changed, 280 insertions(+)
 create mode 100644 tools/testing/memblock/.gitignore
 create mode 100644 tools/testing/memblock/Makefile
 create mode 100644 tools/testing/memblock/asm/dma.h
 create mode 100644 tools/testing/memblock/internal.h
 create mode 100644 tools/testing/memblock/lib/slab.c
 create mode 100644 tools/testing/memblock/linux/init.h
 create mode 100644 tools/testing/memblock/linux/kernel.h
 create mode 100644 tools/testing/memblock/linux/kmemleak.h
 create mode 100644 tools/testing/memblock/linux/memory_hotplug.h
 create mode 100644 tools/testing/memblock/linux/mmzone.h
 create mode 100644 tools/testing/memblock/linux/printk.h
 create mode 100644 tools/testing/memblock/main.c
 create mode 100644 tools/testing/memblock/mmzone.c
 create mode 100644 tools/testing/memblock/scripts/Makefile.include

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..602dc6e9ebad 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12402,6 +12402,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 <krzysztof.kozlowski@canonical.com>
diff --git a/tools/include/linux/slab.h b/tools/include/linux/slab.h
index 07d7930d4003..f41d8a0eb1a4 100644
--- a/tools/include/linux/slab.h
+++ b/tools/include/linux/slab.h
@@ -13,6 +13,16 @@
 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);
diff --git a/tools/testing/memblock/.gitignore b/tools/testing/memblock/.gitignore
new file mode 100644
index 000000000000..5b80ece3d135
--- /dev/null
+++ b/tools/testing/memblock/.gitignore
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+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 000000000000..35105923f235
--- /dev/null
+++ b/tools/testing/memblock/Makefile
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Memblock simulator requires AddressSanitizer (libasan) and liburcu libraries
+CFLAGS += -I. -I../../include -Wall -O2 -fsanitize=address \
+	  -fsanitize=undefined -D CONFIG_PHYS_ADDR_T_64BIT
+LDFLAGS += -fsanitize=address -fsanitize=undefined
+TARGETS = main
+OFILES = main.o memblock.o lib/slab.o mmzone.o slab.o
+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 000000000000..13ff8e5d22ef
--- /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 000000000000..94b52a8718b5
--- /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 000000000000..6be6020328fb
--- /dev/null
+++ b/tools/testing/memblock/lib/slab.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/slab.h>
+
+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 000000000000..8c09788dfeb1
--- /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 <linux/compiler.h>
+#include <asm/export.h>
+#include <linux/memory_hotplug.h>
+
+#define __section(section)              __attribute__((__section__(section)))
+
+#define __initconst	__section(".init.rodata")
+#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 000000000000..d2f148bd8902
--- /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 <linux/errno.h>
+#include <string.h>
+#include <linux/printk.h>
+#include <linux/linkage.h>
+#include <linux/kconfig.h>
+
+#endif
diff --git a/tools/testing/memblock/linux/kmemleak.h b/tools/testing/memblock/linux/kmemleak.h
new file mode 100644
index 000000000000..462f8c5e8aa0
--- /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 000000000000..47988765a219
--- /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 <linux/numa.h>
+#include <linux/pfn.h>
+#include <linux/cache.h>
+#include <linux/types.h>
+
+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 000000000000..7c2eb5c9bb54
--- /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 <linux/atomic.h>
+
+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 000000000000..61af424d8c6c
--- /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 <stdio.h>
+#include <asm/bug.h>
+
+/*
+ * 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 000000000000..62958da35d0f
--- /dev/null
+++ b/tools/testing/memblock/main.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+int main(int argc, char **argv)
+{
+	return 0;
+}
diff --git a/tools/testing/memblock/mmzone.c b/tools/testing/memblock/mmzone.c
new file mode 100644
index 000000000000..7b0909e8b759
--- /dev/null
+++ b/tools/testing/memblock/mmzone.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/mmzone.h>
+
+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 000000000000..699b0d6cda07
--- /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
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 11/16] memblock tests: Add memblock reset function
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (9 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 12/16] memblock tests: Add memblock_add tests Karolina Drobnik
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Memblock simulator needs to be able to reset memblock data structures
between different test cases. Add a function that sets all fields to
their default values.

Add a test checking if memblock is being initialized to expected values.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/testing/memblock/Makefile          |  4 ++-
 tools/testing/memblock/main.c            |  2 ++
 tools/testing/memblock/tests/basic_api.c | 32 ++++++++++++++++++++++++
 tools/testing/memblock/tests/basic_api.h | 10 ++++++++
 tools/testing/memblock/tests/common.c    | 27 ++++++++++++++++++++
 tools/testing/memblock/tests/common.h    | 15 +++++++++++
 6 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/memblock/tests/basic_api.c
 create mode 100644 tools/testing/memblock/tests/basic_api.h
 create mode 100644 tools/testing/memblock/tests/common.c
 create mode 100644 tools/testing/memblock/tests/common.h

diff --git a/tools/testing/memblock/Makefile b/tools/testing/memblock/Makefile
index 35105923f235..31c4ef625ede 100644
--- a/tools/testing/memblock/Makefile
+++ b/tools/testing/memblock/Makefile
@@ -5,7 +5,9 @@ CFLAGS += -I. -I../../include -Wall -O2 -fsanitize=address \
 	  -fsanitize=undefined -D CONFIG_PHYS_ADDR_T_64BIT
 LDFLAGS += -fsanitize=address -fsanitize=undefined
 TARGETS = main
-OFILES = main.o memblock.o lib/slab.o mmzone.o slab.o
+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)
diff --git a/tools/testing/memblock/main.c b/tools/testing/memblock/main.c
index 62958da35d0f..da65b0adee91 100644
--- a/tools/testing/memblock/main.c
+++ b/tools/testing/memblock/main.c
@@ -1,6 +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/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
new file mode 100644
index 000000000000..7f2597b3dd4d
--- /dev/null
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <string.h>
+#include <linux/memblock.h>
+#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;
+}
+
+int memblock_basic_checks(void)
+{
+	memblock_initialization_check();
+	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 000000000000..1ceecfca1f47
--- /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 <assert.h>
+#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 000000000000..03de6eab0c3c
--- /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 <string.h>
+
+#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 000000000000..48efc4270ea1
--- /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 <linux/types.h>
+#include <linux/memblock.h>
+
+struct region {
+	phys_addr_t base;
+	phys_addr_t size;
+};
+
+void reset_memblock(void);
+
+#endif
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 12/16] memblock tests: Add memblock_add tests
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (10 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 11/16] memblock tests: Add memblock reset function Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 13/16] memblock tests: Add memblock_reserve tests Karolina Drobnik
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add checks for adding a new region in different scenarios:
 - The region does not overlap with existing entries
 - The region overlaps with one of the previous entries: from the top
  (its end address is bigger than the base of the existing region) or
  from the bottom (its base address is smaller than the end address of
  one of the regions)
 - The region is within an already defined region
 - The same region is added twice to the collection of available memory
   regions

Add checks for memblock initialization to verify it sets memblock data
structures to expected values.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/testing/memblock/tests/basic_api.c | 215 +++++++++++++++++++++++
 1 file changed, 215 insertions(+)

diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
index 7f2597b3dd4d..6c047b7b31ab 100644
--- a/tools/testing/memblock/tests/basic_api.c
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 #include <string.h>
 #include <linux/memblock.h>
+#include <linux/sizes.h>
 #include "basic_api.h"
 
 #define EXPECTED_MEMBLOCK_REGIONS			128
@@ -25,8 +26,222 @@ static int memblock_initialization_check(void)
 	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 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_disjoint_check();
+	memblock_add_overlap_top_check();
+	memblock_add_overlap_bottom_check();
+	memblock_add_within_check();
+	memblock_add_twice_check();
+
+	return 0;
+}
+
 int memblock_basic_checks(void)
 {
 	memblock_initialization_check();
+	memblock_add_checks();
 	return 0;
 }
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 13/16] memblock tests: Add memblock_reserve tests
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (11 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 12/16] memblock tests: Add memblock_add tests Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 14/16] memblock tests: Add memblock_remove tests Karolina Drobnik
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add checks for marking a region as reserved in different scenarios:
 - The region does not overlap with existing entries
 - The region overlaps with one of the previous entries: from the top
   (its end address is bigger than the base of the existing region) or
   from the bottom (its base address is smaller than the end address of
   one of the regions)
 - The region is within an already defined region
 - The same region is marked as reserved twice

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/testing/memblock/tests/basic_api.c | 213 +++++++++++++++++++++++
 1 file changed, 213 insertions(+)

diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
index 6c047b7b31ab..b055ff262d23 100644
--- a/tools/testing/memblock/tests/basic_api.c
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -239,9 +239,222 @@ static int memblock_add_checks(void)
 	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;
+}
+
 int memblock_basic_checks(void)
 {
 	memblock_initialization_check();
 	memblock_add_checks();
+	memblock_reserve_checks();
+
 	return 0;
 }
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 14/16] memblock tests: Add memblock_remove tests
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (12 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 13/16] memblock tests: Add memblock_reserve tests Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 15/16] memblock tests: Add memblock_add_node test Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 16/16] memblock tests: Add memblock_free tests Karolina Drobnik
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add checks for removing a region from available memory in different
scenarios:
 - The requested region matches one in the collection of available
   memory regions
 - The requested region does not exist in memblock.memory
 - The region overlaps with one of the entries: from the top (its end
   address is bigger than the base of the existing region) or from the
   bottom (its base address is smaller than the end address of one of
   the regions)
 - The region is within an already defined region

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/testing/memblock/tests/basic_api.c | 203 +++++++++++++++++++++++
 1 file changed, 203 insertions(+)

diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
index b055ff262d23..96af80bf9df9 100644
--- a/tools/testing/memblock/tests/basic_api.c
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -450,11 +450,214 @@ static int memblock_reserve_checks(void)
 	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;
+}
+
 int memblock_basic_checks(void)
 {
 	memblock_initialization_check();
 	memblock_add_checks();
 	memblock_reserve_checks();
+	memblock_remove_checks();
 
 	return 0;
 }
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 15/16] memblock tests: Add memblock_add_node test
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (13 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 14/16] memblock tests: Add memblock_remove tests Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  2022-01-27 13:21 ` [PATCH 16/16] memblock tests: Add memblock_free tests Karolina Drobnik
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add a simple test for NUMA-aware variant of memblock_add function.

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/testing/memblock/tests/basic_api.c | 34 ++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
index 96af80bf9df9..02eb88358a58 100644
--- a/tools/testing/memblock/tests/basic_api.c
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -55,6 +55,39 @@ static int memblock_add_simple_check(void)
 	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
@@ -230,6 +263,7 @@ static int memblock_add_twice_check(void)
 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();
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 16/16] memblock tests: Add memblock_free tests
  2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
                   ` (14 preceding siblings ...)
  2022-01-27 13:21 ` [PATCH 15/16] memblock tests: Add memblock_add_node test Karolina Drobnik
@ 2022-01-27 13:21 ` Karolina Drobnik
  15 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-27 13:21 UTC (permalink / raw)
  To: linux-mm; +Cc: akpm, mike.rapoport, linux-kernel, Karolina Drobnik

Add checks for removing a region from reserved memory in different
scenarios:
 - The requested region matches one in the collection of reserved
   memory regions
 - The requested region does not exist in memblock.reserved
 - The region overlaps with one of the entries: from the top (its
   end address is bigger than the base of the existing region) or
   from the bottom (its base address is smaller than the end address
   of one of the regions)
 - The region is within an already defined region

Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
---
 tools/testing/memblock/tests/basic_api.c | 199 +++++++++++++++++++++++
 1 file changed, 199 insertions(+)

diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
index 02eb88358a58..568b05b52883 100644
--- a/tools/testing/memblock/tests/basic_api.c
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -686,12 +686,211 @@ static int memblock_remove_checks(void)
 	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;
 }
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib
  2022-01-27 13:21 ` [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib Karolina Drobnik
@ 2022-01-27 13:28   ` Matthew Wilcox
  2022-01-28 11:00     ` Karolina Drobnik
  2022-01-27 13:36   ` Matthew Wilcox
  1 sibling, 1 reply; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 13:28 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:19PM +0100, Karolina Drobnik wrote:
> +#include <linux/types.h>
> +
> +#define __GFP_ZERO		0x8000u
> +#define __GFP_DIRECT_RECLAIM	0x400000u
> +
> +#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_ATOMIC		0x80000u
> +#define __GFP_ACCOUNT		0x100000u
> +#define __GFP_KSWAPD_RECLAIM	0x2000000u

Why have you reordered the bits here?

> -#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

The original ordering makes more sense to me (but then it would; I did
it)


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib
  2022-01-27 13:21 ` [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib Karolina Drobnik
  2022-01-27 13:28   ` Matthew Wilcox
@ 2022-01-27 13:36   ` Matthew Wilcox
  2022-01-28 11:02     ` Karolina Drobnik
  1 sibling, 1 reply; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 13:36 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:19PM +0100, Karolina Drobnik wrote:
> diff --git a/tools/testing/radix-tree/linux.c b/tools/testing/radix-tree/linux.c
> index 2d9c59df60de..81539f543954 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 *))

I don't think it makes much sense to move kmalloc() and not to move
the kmem_cache* functions.  They're all provided by slab in the kernel
proper, so while you don't use them, I think keeping all the memory
allocation functions together is preferable.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h
  2022-01-27 13:21 ` [PATCH 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h Karolina Drobnik
@ 2022-01-27 13:54   ` Matthew Wilcox
  2022-01-28 11:05     ` Karolina Drobnik
  0 siblings, 1 reply; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 13:54 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:21PM +0100, Karolina Drobnik wrote:
> Add max_t, min_t and clamp functions, together with _RET_IP_
> definition, so they can be used in testing.

Rather than adding our own definitions of min/max/clamp, have
you considered using #include "../../../include/linux/minmax.h"?
In my experience reusing this kind of "leaf" header works out
better than duplicating it.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 04/16] tools/include: Update atomic.h header
  2022-01-27 13:21 ` [PATCH 04/16] tools/include: Update atomic.h header Karolina Drobnik
@ 2022-01-27 13:56   ` Matthew Wilcox
  2022-01-28 11:08     ` Karolina Drobnik
  0 siblings, 1 reply; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 13:56 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:22PM +0100, Karolina Drobnik wrote:
> Add atomic_long_t typedef and atomic_long_set function so they
>  can be used in testing.
> 
> Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
> ---
>  tools/include/linux/atomic.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h
> index 00a6c4ca562b..5d2431889606 100644
> --- a/tools/include/linux/atomic.h
> +++ b/tools/include/linux/atomic.h
> @@ -4,6 +4,10 @@
>  
>  #include <asm/atomic.h>
>  
> +typedef atomic_t atomic_long_t;

Given this:

typedef struct {
        int counter;
} atomic_t;

your definition seems wrong.  Why not add atomic_long_t to types.h,
adjacent to atomic_t?


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 06/16] tools/include: Add cache.h stub
  2022-01-27 13:21 ` [PATCH 06/16] tools/include: Add cache.h stub Karolina Drobnik
@ 2022-01-27 14:00   ` Matthew Wilcox
  2022-01-28 11:13     ` Karolina Drobnik
  0 siblings, 1 reply; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 14:00 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:24PM +0100, Karolina Drobnik wrote:
> +++ 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		BIT(L1_CACHE_SHIFT)
> +
> +#define SMP_CACHE_BYTES L1_CACHE_BYTES
> +
> +#endif

You've added an implicit dependency on include/vdso/bits.h which seems
unpleasant ...


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator
  2022-01-27 13:21 ` [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator Karolina Drobnik
@ 2022-01-27 14:02   ` Matthew Wilcox
  2022-01-27 14:06   ` Matthew Wilcox
  1 sibling, 0 replies; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 14:02 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:28PM +0100, Karolina Drobnik wrote:
> +++ b/tools/testing/memblock/.gitignore
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +main
> +memblock.c
> +linux/memblock.h
> +asm/cmpxchg.h

Don't put SPDX information in a .gitignore file.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator
  2022-01-27 13:21 ` [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator Karolina Drobnik
  2022-01-27 14:02   ` Matthew Wilcox
@ 2022-01-27 14:06   ` Matthew Wilcox
  2022-01-28 11:25     ` Karolina Drobnik
  1 sibling, 1 reply; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 14:06 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:28PM +0100, Karolina Drobnik wrote:
> +# Memblock simulator requires AddressSanitizer (libasan) and liburcu libraries

Stale comment?  You don't seem to actually use liburcu.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-27 13:21 ` [PATCH 07/16] tools/include: Add io.h stub Karolina Drobnik
@ 2022-01-27 14:09   ` Matthew Wilcox
  2022-01-28 11:21     ` Karolina Drobnik
  0 siblings, 1 reply; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-27 14:09 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, Jan 27, 2022 at 02:21:25PM +0100, Karolina Drobnik wrote:
> Add a dummy io.h header.

Rather begs the question of what memblock.c needs from linux/io.h.
Wouldn't it be better to:

+++ b/mm/memblock.c
@@ -18,7 +18,6 @@
 #include <linux/memblock.h>

 #include <asm/sections.h>
-#include <linux/io.h>

 #include "internal.h"


(allmodconfig on x86-64 builds fine with this; I have not done an
extended sweep of other arches / build options).


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib
  2022-01-27 13:28   ` Matthew Wilcox
@ 2022-01-28 11:00     ` Karolina Drobnik
  0 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 11:00 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

Hi Matthew,

Many thanks for your review.

On Thu, 2022-01-27 at 13:28 +0000, Matthew Wilcox wrote:
> On Thu, Jan 27, 2022 at 02:21:19PM +0100, Karolina Drobnik wrote:
> > +#include <linux/types.h>
> > +
> > +#define __GFP_ZERO             0x8000u
> > +#define __GFP_DIRECT_RECLAIM   0x400000u
> > +
> > +#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_ATOMIC           0x80000u
> > +#define __GFP_ACCOUNT          0x100000u
> > +#define __GFP_KSWAPD_RECLAIM   0x2000000u
> 
> Why have you reordered the bits here?

I probably mixed them up when I tried to merge the stubs I did for
memblock and the files that were already there. I'll fix it in v2.

> > -#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
> 
> The original ordering makes more sense to me (but then it would; I
> did
> it)




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib
  2022-01-27 13:36   ` Matthew Wilcox
@ 2022-01-28 11:02     ` Karolina Drobnik
  2022-01-28 17:30       ` Karolina Drobnik
  0 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 11:02 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, 2022-01-27 at 13:36 +0000, Matthew Wilcox wrote:
> On Thu, Jan 27, 2022 at 02:21:19PM +0100, Karolina Drobnik wrote:
> > diff --git a/tools/testing/radix-tree/linux.c
> > b/tools/testing/radix-tree/linux.c
> > index 2d9c59df60de..81539f543954 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 *))
> 
> I don't think it makes much sense to move kmalloc() and not to move
> the kmem_cache* functions.  They're all provided by slab in the
> kernel
> proper, so while you don't use them, I think keeping all the memory
> allocation functions together is preferable.

I wasn't sure if these functions would be used by other test suites, so
I left them here. But I can move them if you think it's better to keep
them together.




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h
  2022-01-27 13:54   ` Matthew Wilcox
@ 2022-01-28 11:05     ` Karolina Drobnik
  0 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 11:05 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, 2022-01-27 at 13:54 +0000, Matthew Wilcox wrote:
> On Thu, Jan 27, 2022 at 02:21:21PM +0100, Karolina Drobnik wrote:
> > Add max_t, min_t and clamp functions, together with _RET_IP_
> > definition, so they can be used in testing.
> 
> Rather than adding our own definitions of min/max/clamp, have
> you considered using #include "../../../include/linux/minmax.h"?

I tried doing it in the very beginning and couldn't get it to compile.
Now, I see it's because in minmax.h we use __UNIQUE_ID, which is
undefined because of "#ifdef __KERNEL__" in include/linux/compiler.h.

> In my experience reusing this kind of "leaf" header works out
> better than duplicating it.

I like this approach as well, and I tried to use it in other memblock
headers. Still, as it's not that straightforward here, and I went for
duplication.




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 04/16] tools/include: Update atomic.h header
  2022-01-27 13:56   ` Matthew Wilcox
@ 2022-01-28 11:08     ` Karolina Drobnik
  0 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 11:08 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, 2022-01-27 at 13:56 +0000, Matthew Wilcox wrote:
> On Thu, Jan 27, 2022 at 02:21:22PM +0100, Karolina Drobnik wrote:
> > Add atomic_long_t typedef and atomic_long_set function so they
> >  can be used in testing.
> > 
> > Signed-off-by: Karolina Drobnik <karolinadrobnik@gmail.com>
> > ---
> >  tools/include/linux/atomic.h | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/tools/include/linux/atomic.h
> > b/tools/include/linux/atomic.h
> > index 00a6c4ca562b..5d2431889606 100644
> > --- a/tools/include/linux/atomic.h
> > +++ b/tools/include/linux/atomic.h
> > @@ -4,6 +4,10 @@
> >  
> >  #include <asm/atomic.h>
> >  
> > +typedef atomic_t atomic_long_t;
> 
> Given this:
> 
> typedef struct {
>         int counter;
> } atomic_t;
> 
> your definition seems wrong.  Why not add atomic_long_t to types.h,
> adjacent to atomic_t?

Hmm, that sounds like a better idea. Will do that, thank you.



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 06/16] tools/include: Add cache.h stub
  2022-01-27 14:00   ` Matthew Wilcox
@ 2022-01-28 11:13     ` Karolina Drobnik
  2022-01-28 13:10       ` Matthew Wilcox
  0 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 11:13 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, 2022-01-27 at 14:00 +0000, Matthew Wilcox wrote:
> On Thu, Jan 27, 2022 at 02:21:24PM +0100, Karolina Drobnik wrote:
> > +++ 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         BIT(L1_CACHE_SHIFT)
> > +
> > +#define SMP_CACHE_BYTES L1_CACHE_BYTES
> > +
> > +#endif
> 
> You've added an implicit dependency on include/vdso/bits.h which
> seems
> unpleasant ...

I'll admit that I just tried to make checkpatch.pl happy with this
change. But you're right, adding such a dependency is undesirable. I
can define it as (1 << L1_CACHE_SHIFT) and ignore the warning.

Is it fine to do so for tools/testing code?



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-27 14:09   ` Matthew Wilcox
@ 2022-01-28 11:21     ` Karolina Drobnik
  2022-01-30 16:10       ` Mike Rapoport
  0 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 11:21 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, 2022-01-27 at 14:09 +0000, Matthew Wilcox wrote:
> On Thu, Jan 27, 2022 at 02:21:25PM +0100, Karolina Drobnik wrote:
> > Add a dummy io.h header.
> 
> Rather begs the question of what memblock.c needs from linux/io.h.
> 
> Wouldn't it be better to:
> 
> +++ b/mm/memblock.c
> @@ -18,7 +18,6 @@
>  #include <linux/memblock.h>
> 
>  #include <asm/sections.h>
> -#include <linux/io.h>
> 
>  #include "internal.h"
> 

That was something I considered in the very beginning, but didn't have
a chance to verify it works for all architectures. I can take a look
after I'm finished with other v2 changes.

> (allmodconfig on x86-64 builds fine with this; I have not done an
> extended sweep of other arches / build options).




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator
  2022-01-27 14:06   ` Matthew Wilcox
@ 2022-01-28 11:25     ` Karolina Drobnik
  2022-01-28 13:11       ` Matthew Wilcox
  0 siblings, 1 reply; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 11:25 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Thu, 2022-01-27 at 14:06 +0000, Matthew Wilcox wrote:
> On Thu, Jan 27, 2022 at 02:21:28PM +0100, Karolina Drobnik wrote:
> > +# Memblock simulator requires AddressSanitizer (libasan) and
> > liburcu libraries
> 
> Stale comment?  You don't seem to actually use liburcu.

I'm using uatomic_inc and uatomic_dec in tools/lib/slab.c. But, you're
right, memblock simulator doesn't use liburcu per se but uses code that
requires it. I wasn't sure where and how to communicate it, so I added
this comment here.



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 06/16] tools/include: Add cache.h stub
  2022-01-28 11:13     ` Karolina Drobnik
@ 2022-01-28 13:10       ` Matthew Wilcox
  0 siblings, 0 replies; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-28 13:10 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Fri, Jan 28, 2022 at 12:13:54PM +0100, Karolina Drobnik wrote:
> On Thu, 2022-01-27 at 14:00 +0000, Matthew Wilcox wrote:
> > On Thu, Jan 27, 2022 at 02:21:24PM +0100, Karolina Drobnik wrote:
> > > +++ 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         BIT(L1_CACHE_SHIFT)
> > > +
> > > +#define SMP_CACHE_BYTES L1_CACHE_BYTES
> > > +
> > > +#endif
> > 
> > You've added an implicit dependency on include/vdso/bits.h which
> > seems
> > unpleasant ...
> 
> I'll admit that I just tried to make checkpatch.pl happy with this
> change. But you're right, adding such a dependency is undesirable. I
> can define it as (1 << L1_CACHE_SHIFT) and ignore the warning.
> 
> Is it fine to do so for tools/testing code?

checkpatch warnings are recommendations.  Only fix checkpatch errors.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator
  2022-01-28 11:25     ` Karolina Drobnik
@ 2022-01-28 13:11       ` Matthew Wilcox
  0 siblings, 0 replies; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-28 13:11 UTC (permalink / raw)
  To: Karolina Drobnik; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Fri, Jan 28, 2022 at 12:25:55PM +0100, Karolina Drobnik wrote:
> On Thu, 2022-01-27 at 14:06 +0000, Matthew Wilcox wrote:
> > On Thu, Jan 27, 2022 at 02:21:28PM +0100, Karolina Drobnik wrote:
> > > +# Memblock simulator requires AddressSanitizer (libasan) and
> > > liburcu libraries
> > 
> > Stale comment?  You don't seem to actually use liburcu.
> 
> I'm using uatomic_inc and uatomic_dec in tools/lib/slab.c. But, you're
> right, memblock simulator doesn't use liburcu per se but uses code that
> requires it. I wasn't sure where and how to communicate it, so I added
> this comment here.

I thought the comment was stale because you don't link against liburcu.
Maybe you can use uatomic_inc() without adding -lurcu to the link step.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib
  2022-01-28 11:02     ` Karolina Drobnik
@ 2022-01-28 17:30       ` Karolina Drobnik
  0 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-28 17:30 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel

On Fri, 2022-01-28 at 12:02 +0100, Karolina Drobnik wrote:
> On Thu, 2022-01-27 at 13:36 +0000, Matthew Wilcox wrote:
> > I don't think it makes much sense to move kmalloc() and not to move
> > the kmem_cache* functions.  They're all provided by slab in the
> > kernel
> > proper, so while you don't use them, I think keeping all the memory
> > allocation functions together is preferable.
> 
> I wasn't sure if these functions would be used by other test suites,
> so
> I left them here. But I can move them if you think it's better to
> keep
> them together.
> 

OK, now I can see why this wouldn't work - kmem_cache_alloc and
kmem_cache_free operate on radix_tree_node struct, making it specific
to this test suite.

So, for this patch, I'm going to tidy up the gfp.h header but leave
radix-tree/linux.c and lib/slab.c as they are now.




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-28 11:21     ` Karolina Drobnik
@ 2022-01-30 16:10       ` Mike Rapoport
  2022-01-30 17:53         ` Matthew Wilcox
  2022-01-31 10:54         ` Karolina Drobnik
  0 siblings, 2 replies; 43+ messages in thread
From: Mike Rapoport @ 2022-01-30 16:10 UTC (permalink / raw)
  To: Karolina Drobnik
  Cc: Matthew Wilcox, linux-mm, akpm, mike.rapoport, linux-kernel

On Fri, Jan 28, 2022 at 12:21:59PM +0100, Karolina Drobnik wrote:
> On Thu, 2022-01-27 at 14:09 +0000, Matthew Wilcox wrote:
> > On Thu, Jan 27, 2022 at 02:21:25PM +0100, Karolina Drobnik wrote:
> > > Add a dummy io.h header.
> > 
> > Rather begs the question of what memblock.c needs from linux/io.h.
> > 
> > Wouldn't it be better to:
> > 
> > +++ b/mm/memblock.c
> > @@ -18,7 +18,6 @@
> >  #include <linux/memblock.h>
> > 
> >  #include <asm/sections.h>
> > -#include <linux/io.h>
> > 
> >  #include "internal.h"
> > 
> 
> That was something I considered in the very beginning, but didn't have
> a chance to verify it works for all architectures. I can take a look
> after I'm finished with other v2 changes.
> 
> > (allmodconfig on x86-64 builds fine with this; I have not done an
> > extended sweep of other arches / build options).

I did a sweep for defconfigs for all arches and all were fine.

Karolina, please send the formal patch. Let's see how kbuild bot reacts.

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-30 16:10       ` Mike Rapoport
@ 2022-01-30 17:53         ` Matthew Wilcox
  2022-01-30 19:00           ` Mike Rapoport
                             ` (2 more replies)
  2022-01-31 10:54         ` Karolina Drobnik
  1 sibling, 3 replies; 43+ messages in thread
From: Matthew Wilcox @ 2022-01-30 17:53 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Karolina Drobnik, linux-mm, akpm, mike.rapoport, linux-kernel,
	Arnd Bergmann

On Sun, Jan 30, 2022 at 06:10:00PM +0200, Mike Rapoport wrote:
> On Fri, Jan 28, 2022 at 12:21:59PM +0100, Karolina Drobnik wrote:
> > On Thu, 2022-01-27 at 14:09 +0000, Matthew Wilcox wrote:
> > > On Thu, Jan 27, 2022 at 02:21:25PM +0100, Karolina Drobnik wrote:
> > > > Add a dummy io.h header.
> > > 
> > > Rather begs the question of what memblock.c needs from linux/io.h.
> > > 
> > > Wouldn't it be better to:
> > > 
> > > +++ b/mm/memblock.c
> > > @@ -18,7 +18,6 @@
> > >  #include <linux/memblock.h>
> > > 
> > >  #include <asm/sections.h>
> > > -#include <linux/io.h>
> > > 
> > >  #include "internal.h"
> > > 
> > 
> > That was something I considered in the very beginning, but didn't have
> > a chance to verify it works for all architectures. I can take a look
> > after I'm finished with other v2 changes.
> > 
> > > (allmodconfig on x86-64 builds fine with this; I have not done an
> > > extended sweep of other arches / build options).
> 
> I did a sweep for defconfigs for all arches and all were fine.

Thanks for doing the sweep, Mike.

I think I found a deeper problem which is masked due to our maze of
header files:

include/asm-generic/io.h:#ifndef virt_to_phys
include/asm-generic/io.h:#define virt_to_phys virt_to_phys

so there's an assumption that <asm/io.h> defines virt_to_phys().
You can see that in a number of architectures, eg:

arch/alpha/include/asm/io.h:static inline unsigned long virt_to_phys(volatile void *address)
arch/ia64/include/asm/io.h:#define virt_to_phys virt_to_phys
arch/mips/include/asm/io.h:#define virt_to_phys virt_to_phys
arch/nios2/include/asm/io.h:#define virt_to_phys(vaddr) \
arch/parisc/include/asm/io.h:#define virt_to_phys(a) ((unsigned long)__pa(a))
arch/powerpc/include/asm/io.h:#define virt_to_phys virt_to_phys
arch/sh/include/asm/io.h:#define virt_to_phys(address)  ((unsigned long)(address))
arch/x86/include/asm/io.h:#define virt_to_phys virt_to_phys

That's clearly not the right place to define it.  Two architectures
put it in asm/memory.h:

arch/arm/include/asm/memory.h:#define virt_to_phys virt_to_phys
arch/arm64/include/asm/memory.h:#define virt_to_phys virt_to_phys

then:

arch/m68k/include/asm/virtconvert.h:#define virt_to_phys virt_to_phys
arch/sparc/include/asm/page_32.h:#define virt_to_phys           __pa
arch/sparc/include/asm/page_64.h:#define virt_to_phys __pa

This needs to be properly sorted out, but I don't want to tell Karolina
that's now her job as a prerequisite for merging this patchset; that
would be unfair.

Cc'ing Arnd.  This is the kind of awful mess that he loves fixing ;-)


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-30 17:53         ` Matthew Wilcox
@ 2022-01-30 19:00           ` Mike Rapoport
  2022-01-31 10:55           ` Karolina Drobnik
  2022-01-31 13:30           ` Arnd Bergmann
  2 siblings, 0 replies; 43+ messages in thread
From: Mike Rapoport @ 2022-01-30 19:00 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Karolina Drobnik, linux-mm, akpm, mike.rapoport, linux-kernel,
	Arnd Bergmann

On Sun, Jan 30, 2022 at 05:53:24PM +0000, Matthew Wilcox wrote:
> On Sun, Jan 30, 2022 at 06:10:00PM +0200, Mike Rapoport wrote:
> > On Fri, Jan 28, 2022 at 12:21:59PM +0100, Karolina Drobnik wrote:
> > > On Thu, 2022-01-27 at 14:09 +0000, Matthew Wilcox wrote:
> > > > On Thu, Jan 27, 2022 at 02:21:25PM +0100, Karolina Drobnik wrote:
> > > > > Add a dummy io.h header.
> > > > 
> > > > Rather begs the question of what memblock.c needs from linux/io.h.
> > > > 
> > > > Wouldn't it be better to:
> > > > 
> > > > +++ b/mm/memblock.c
> > > > @@ -18,7 +18,6 @@
> > > >  #include <linux/memblock.h>
> > > > 
> > > >  #include <asm/sections.h>
> > > > -#include <linux/io.h>
> > > > 
> > > >  #include "internal.h"
> > > > 
> > > 
> > > That was something I considered in the very beginning, but didn't have
> > > a chance to verify it works for all architectures. I can take a look
> > > after I'm finished with other v2 changes.
> > > 
> > > > (allmodconfig on x86-64 builds fine with this; I have not done an
> > > > extended sweep of other arches / build options).
> > 
> > I did a sweep for defconfigs for all arches and all were fine.
> 
> Thanks for doing the sweep, Mike.
> 
> I think I found a deeper problem which is masked due to our maze of
> header files:
> 
> include/asm-generic/io.h:#ifndef virt_to_phys
> include/asm-generic/io.h:#define virt_to_phys virt_to_phys
> 
> so there's an assumption that <asm/io.h> defines virt_to_phys().
> You can see that in a number of architectures, eg:
> 
> arch/alpha/include/asm/io.h:static inline unsigned long virt_to_phys(volatile void *address)
> arch/ia64/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/mips/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/nios2/include/asm/io.h:#define virt_to_phys(vaddr) \
> arch/parisc/include/asm/io.h:#define virt_to_phys(a) ((unsigned long)__pa(a))
> arch/powerpc/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/sh/include/asm/io.h:#define virt_to_phys(address)  ((unsigned long)(address))
> arch/x86/include/asm/io.h:#define virt_to_phys virt_to_phys
> 
> That's clearly not the right place to define it.  Two architectures
> put it in asm/memory.h:
> 
> arch/arm/include/asm/memory.h:#define virt_to_phys virt_to_phys
> arch/arm64/include/asm/memory.h:#define virt_to_phys virt_to_phys
> 
> then:
> 
> arch/m68k/include/asm/virtconvert.h:#define virt_to_phys virt_to_phys
> arch/sparc/include/asm/page_32.h:#define virt_to_phys           __pa
> arch/sparc/include/asm/page_64.h:#define virt_to_phys __pa

I'd say sparc picked the most appropriate header for it. memory.h could
also work fine, but it's only present on some arches.
I'll take a deeper look, thanks for checking this.
 
> This needs to be properly sorted out, but I don't want to tell Karolina
> that's now her job as a prerequisite for merging this patchset; that
> would be unfair.
 
Totally agree.

> Cc'ing Arnd.  This is the kind of awful mess that he loves fixing ;-)

Heh, me too :)

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-30 16:10       ` Mike Rapoport
  2022-01-30 17:53         ` Matthew Wilcox
@ 2022-01-31 10:54         ` Karolina Drobnik
  1 sibling, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-31 10:54 UTC (permalink / raw)
  To: Mike Rapoport; +Cc: Matthew Wilcox, linux-mm, akpm, mike.rapoport, linux-kernel

Hi Mike,

On Sun, 2022-01-30 at 18:10 +0200, Mike Rapoport wrote:
> On Fri, Jan 28, 2022 at 12:21:59PM +0100, Karolina Drobnik wrote:
> > On Thu, 2022-01-27 at 14:09 +0000, Matthew Wilcox wrote:
> > > On Thu, Jan 27, 2022 at 02:21:25PM +0100, Karolina Drobnik wrote:
> > > > Add a dummy io.h header.
> > > 
> > > Rather begs the question of what memblock.c needs from
> > > linux/io.h.
> > > 
> > > Wouldn't it be better to:
> > > 
> > > +++ b/mm/memblock.c
> > > @@ -18,7 +18,6 @@
> > >  #include <linux/memblock.h>
> > > 
> > >  #include <asm/sections.h>
> > > -#include <linux/io.h>
> > > 
> > >  #include "internal.h"
> > > 
> > 
> > That was something I considered in the very beginning, but didn't
> > have
> > a chance to verify it works for all architectures. I can take a
> > look
> > after I'm finished with other v2 changes.
> > 
> > > (allmodconfig on x86-64 builds fine with this; I have not done an
> > > extended sweep of other arches / build options).
> 
> I did a sweep for defconfigs for all arches and all were fine.

Thanks for doing the sweep, it's very helpful.

> Karolina, please send the formal patch. Let's see how kbuild bot
> reacts.

OK, will send something later today.


All the best,
Karolina



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-30 17:53         ` Matthew Wilcox
  2022-01-30 19:00           ` Mike Rapoport
@ 2022-01-31 10:55           ` Karolina Drobnik
  2022-01-31 13:30           ` Arnd Bergmann
  2 siblings, 0 replies; 43+ messages in thread
From: Karolina Drobnik @ 2022-01-31 10:55 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, akpm, mike.rapoport, linux-kernel, Arnd Bergmann

Hi Matthew,

On Sun, 2022-01-30 at 17:53 +0000, Matthew Wilcox wrote:
> I think I found a deeper problem which is masked due to our maze of
> header files:
> 
> include/asm-generic/io.h:#ifndef virt_to_phys
> include/asm-generic/io.h:#define virt_to_phys virt_to_phys
> 
> so there's an assumption that <asm/io.h> defines virt_to_phys().
> You can see that in a number of architectures, eg:
> 
> arch/alpha/include/asm/io.h:static inline unsigned long
> virt_to_phys(volatile void *address)
> arch/ia64/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/mips/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/nios2/include/asm/io.h:#define virt_to_phys(vaddr) \
> arch/parisc/include/asm/io.h:#define virt_to_phys(a) ((unsigned
> long)__pa(a))
> arch/powerpc/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/sh/include/asm/io.h:#define virt_to_phys(address)  ((unsigned
> long)(address))
> arch/x86/include/asm/io.h:#define virt_to_phys virt_to_phys
> 
> That's clearly not the right place to define it.  Two architectures
> put it in asm/memory.h:
> 
> arch/arm/include/asm/memory.h:#define virt_to_phys virt_to_phys
> arch/arm64/include/asm/memory.h:#define virt_to_phys virt_to_phys
> 
> then:
> 
> arch/m68k/include/asm/virtconvert.h:#define virt_to_phys virt_to_phys
> arch/sparc/include/asm/page_32.h:#define virt_to_phys           __pa
> arch/sparc/include/asm/page_64.h:#define virt_to_phys __pa

Oh, that's a lot...thank you for checking it. The simulator has its own
mm stubs, so it shouldn't be impacted by such a clean up, correct?

> This needs to be properly sorted out, but I don't want to tell
> Karolina that's now her job as a prerequisite for merging this
> patchset; that would be unfair.

Thanks. Also, I think I'm not be the best person to (efficiently) sort
this out :)


All the best,
Karolina



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-30 17:53         ` Matthew Wilcox
  2022-01-30 19:00           ` Mike Rapoport
  2022-01-31 10:55           ` Karolina Drobnik
@ 2022-01-31 13:30           ` Arnd Bergmann
  2022-01-31 15:18             ` Mike Rapoport
  2 siblings, 1 reply; 43+ messages in thread
From: Arnd Bergmann @ 2022-01-31 13:30 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Mike Rapoport, Karolina Drobnik, Linux-MM, Andrew Morton,
	Mike Rapoport, Linux Kernel Mailing List, Arnd Bergmann,
	Ingo Molnar

On Sun, Jan 30, 2022 at 6:53 PM Matthew Wilcox <willy@infradead.org> wrote:

> Thanks for doing the sweep, Mike.
>
> I think I found a deeper problem which is masked due to our maze of
> header files:
>
> include/asm-generic/io.h:#ifndef virt_to_phys
> include/asm-generic/io.h:#define virt_to_phys virt_to_phys
>
> so there's an assumption that <asm/io.h> defines virt_to_phys().
> You can see that in a number of architectures, eg:
>
> arch/alpha/include/asm/io.h:static inline unsigned long virt_to_phys(volatile void *address)
> arch/ia64/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/mips/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/nios2/include/asm/io.h:#define virt_to_phys(vaddr) \
> arch/parisc/include/asm/io.h:#define virt_to_phys(a) ((unsigned long)__pa(a))
> arch/powerpc/include/asm/io.h:#define virt_to_phys virt_to_phys
> arch/sh/include/asm/io.h:#define virt_to_phys(address)  ((unsigned long)(address))
> arch/x86/include/asm/io.h:#define virt_to_phys virt_to_phys
>
> That's clearly not the right place to define it.  Two architectures
> put it in asm/memory.h:
>
> arch/arm/include/asm/memory.h:#define virt_to_phys virt_to_phys
> arch/arm64/include/asm/memory.h:#define virt_to_phys virt_to_phys
>
> then:
>
> arch/m68k/include/asm/virtconvert.h:#define virt_to_phys virt_to_phys
> arch/sparc/include/asm/page_32.h:#define virt_to_phys           __pa
> arch/sparc/include/asm/page_64.h:#define virt_to_phys __pa
>
> This needs to be properly sorted out, but I don't want to tell Karolina
> that's now her job as a prerequisite for merging this patchset; that
> would be unfair.
>
> Cc'ing Arnd.  This is the kind of awful mess that he loves fixing ;-)

Adding Ingo as well. I'm in the middle of getting his fast-headers tree
to work well on a couple of other architectures, and the memory.h/page.h/io.h
mess is one of the  tricky bits in there, both in his series and in my
follow-ups.

What makes this bit even worse is that the architectures also not just
inconsistent about where they put __va/__pa and
virt_to_phys/phys_to_virt, they are also inconsistent about which of the
two pairs is based on the other, so any way you touch it means you
will break something, and changing it now will likely require a tricky
rebase of Ingo's patches.

Ingo, do you happen to have patches already that could be isolated
from your series to address this? Maybe we can add the
linux/mm_page_address.h header first and require that each
architecture puts these macros into asm/page_address.h.
We need to isolate these anyway, because the page addresses
are used in a lot of places that don't need to include any of the
remaining headers (page.h, mm.h, memory.h, io.h) that pull in
hundreds more.

          Arnd


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-31 13:30           ` Arnd Bergmann
@ 2022-01-31 15:18             ` Mike Rapoport
  2022-01-31 16:26               ` Arnd Bergmann
  0 siblings, 1 reply; 43+ messages in thread
From: Mike Rapoport @ 2022-01-31 15:18 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Matthew Wilcox, Karolina Drobnik, Linux-MM, Andrew Morton,
	Mike Rapoport, Linux Kernel Mailing List, Ingo Molnar

On Mon, Jan 31, 2022 at 02:30:32PM +0100, Arnd Bergmann wrote:
> On Sun, Jan 30, 2022 at 6:53 PM Matthew Wilcox <willy@infradead.org> wrote:
> 
> > Thanks for doing the sweep, Mike.
> >
> > I think I found a deeper problem which is masked due to our maze of
> > header files:
> >
> > include/asm-generic/io.h:#ifndef virt_to_phys
> > include/asm-generic/io.h:#define virt_to_phys virt_to_phys
> >
> > so there's an assumption that <asm/io.h> defines virt_to_phys().
> > You can see that in a number of architectures, eg:
> >
> > arch/alpha/include/asm/io.h:static inline unsigned long virt_to_phys(volatile void *address)
> > arch/ia64/include/asm/io.h:#define virt_to_phys virt_to_phys
> > arch/mips/include/asm/io.h:#define virt_to_phys virt_to_phys
> > arch/nios2/include/asm/io.h:#define virt_to_phys(vaddr) \
> > arch/parisc/include/asm/io.h:#define virt_to_phys(a) ((unsigned long)__pa(a))
> > arch/powerpc/include/asm/io.h:#define virt_to_phys virt_to_phys
> > arch/sh/include/asm/io.h:#define virt_to_phys(address)  ((unsigned long)(address))
> > arch/x86/include/asm/io.h:#define virt_to_phys virt_to_phys
> >
> > That's clearly not the right place to define it.  Two architectures
> > put it in asm/memory.h:
> >
> > arch/arm/include/asm/memory.h:#define virt_to_phys virt_to_phys
> > arch/arm64/include/asm/memory.h:#define virt_to_phys virt_to_phys
> >
> > then:
> >
> > arch/m68k/include/asm/virtconvert.h:#define virt_to_phys virt_to_phys
> > arch/sparc/include/asm/page_32.h:#define virt_to_phys           __pa
> > arch/sparc/include/asm/page_64.h:#define virt_to_phys __pa
> >
> > This needs to be properly sorted out, but I don't want to tell Karolina
> > that's now her job as a prerequisite for merging this patchset; that
> > would be unfair.
> >
> > Cc'ing Arnd.  This is the kind of awful mess that he loves fixing ;-)
> 
> Adding Ingo as well. I'm in the middle of getting his fast-headers tree
> to work well on a couple of other architectures, and the memory.h/page.h/io.h
> mess is one of the  tricky bits in there, both in his series and in my
> follow-ups.
> 
> What makes this bit even worse is that the architectures also not just
> inconsistent about where they put __va/__pa and
> virt_to_phys/phys_to_virt, they are also inconsistent about which of the
> two pairs is based on the other, so any way you touch it means you
> will break something, and changing it now will likely require a tricky
> rebase of Ingo's patches.

Hmm, whatever we'll do with these conversions, it will be tricky for Ingo's
tree...

> Ingo, do you happen to have patches already that could be isolated
> from your series to address this? Maybe we can add the
> linux/mm_page_address.h header first and require that each
> architecture puts these macros into asm/page_address.h.
> We need to isolate these anyway, because the page addresses
> are used in a lot of places that don't need to include any of the
> remaining headers (page.h, mm.h, memory.h, io.h) that pull in
> hundreds more.

I peeked at Ingo's tree and there is this:

commit 3426911a3f83 (headers/deps: io/arch: Move the address translation
APIs from <asm/io.h> to <asm/io_extra.h>)
(https://git.kernel.org/pub/scm/linux/kernel/git/mingo/tip.git/commit/?id=3426911a3f833930d92f3aebe349f09a513375d9)

It moves virt_to_phys and phys_to_virt on x86 to a new header.

I actually liked m68k's name for a header with virt_to_phys/phys_to_virt
definitions - virtconvert.h.

As an experiment I pulled out address translations from
arch/arm/include/memory.h to arch/arm/include/virtconvert.h, it wasn't that
bad:

 arch/arm/include/asm/dma-mapping.h |   2 +
 arch/arm/include/asm/io.h          |   1 +
 arch/arm/include/asm/memory.h      | 244 ----------------------------------
 arch/arm/include/asm/pgtable.h     |   1 +
 arch/arm/include/asm/virtconvert.h | 264 +++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/psci_smp.c         |   1 +
 6 files changed, 269 insertions(+), 244 deletions(-)

(https://git.kernel.org/rppt/linux/c/4c34ec16319fc85280aad89d7a74df845c1614fc)

>           Arnd

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 07/16] tools/include: Add io.h stub
  2022-01-31 15:18             ` Mike Rapoport
@ 2022-01-31 16:26               ` Arnd Bergmann
  0 siblings, 0 replies; 43+ messages in thread
From: Arnd Bergmann @ 2022-01-31 16:26 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Arnd Bergmann, Matthew Wilcox, Karolina Drobnik, Linux-MM,
	Andrew Morton, Mike Rapoport, Linux Kernel Mailing List,
	Ingo Molnar

On Mon, Jan 31, 2022 at 4:18 PM Mike Rapoport <rppt@kernel.org> wrote:
> On Mon, Jan 31, 2022 at 02:30:32PM +0100, Arnd Bergmann wrote:
> > On Sun, Jan 30, 2022 at 6:53 PM Matthew Wilcox <willy@infradead.org> wrote:

> I actually liked m68k's name for a header with virt_to_phys/phys_to_virt
> definitions - virtconvert.h.
>
> As an experiment I pulled out address translations from
> arch/arm/include/memory.h to arch/arm/include/virtconvert.h, it wasn't that
> bad:
>
>  arch/arm/include/asm/dma-mapping.h |   2 +
>  arch/arm/include/asm/io.h          |   1 +
>  arch/arm/include/asm/memory.h      | 244 ----------------------------------
>  arch/arm/include/asm/pgtable.h     |   1 +
>  arch/arm/include/asm/virtconvert.h | 264 +++++++++++++++++++++++++++++++++++++
>  arch/arm/kernel/psci_smp.c         |   1 +
>  6 files changed, 269 insertions(+), 244 deletions(-)
>
> (https://git.kernel.org/rppt/linux/c/4c34ec16319fc85280aad89d7a74df845c1614fc)

Right, that doesn't look too bad, especially since it seems you managed to avoid
any further indirect inlcudes. Doing the same consistently for all architectures
may end up a bit harder but would be a great help.

       Arnd


^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2022-01-31 16:27 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-27 13:21 [PATCH 00/16] Introduce memblock simulator Karolina Drobnik
2022-01-27 13:21 ` [PATCH 01/16] tools: Move gfp.h and slab.h from radix-tree to lib Karolina Drobnik
2022-01-27 13:28   ` Matthew Wilcox
2022-01-28 11:00     ` Karolina Drobnik
2022-01-27 13:36   ` Matthew Wilcox
2022-01-28 11:02     ` Karolina Drobnik
2022-01-28 17:30       ` Karolina Drobnik
2022-01-27 13:21 ` [PATCH 02/16] tools/include: Add phys_addr_t to types.h Karolina Drobnik
2022-01-27 13:21 ` [PATCH 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h Karolina Drobnik
2022-01-27 13:54   ` Matthew Wilcox
2022-01-28 11:05     ` Karolina Drobnik
2022-01-27 13:21 ` [PATCH 04/16] tools/include: Update atomic.h header Karolina Drobnik
2022-01-27 13:56   ` Matthew Wilcox
2022-01-28 11:08     ` Karolina Drobnik
2022-01-27 13:21 ` [PATCH 05/16] tools/include: Add mm.h file Karolina Drobnik
2022-01-27 13:21 ` [PATCH 06/16] tools/include: Add cache.h stub Karolina Drobnik
2022-01-27 14:00   ` Matthew Wilcox
2022-01-28 11:13     ` Karolina Drobnik
2022-01-28 13:10       ` Matthew Wilcox
2022-01-27 13:21 ` [PATCH 07/16] tools/include: Add io.h stub Karolina Drobnik
2022-01-27 14:09   ` Matthew Wilcox
2022-01-28 11:21     ` Karolina Drobnik
2022-01-30 16:10       ` Mike Rapoport
2022-01-30 17:53         ` Matthew Wilcox
2022-01-30 19:00           ` Mike Rapoport
2022-01-31 10:55           ` Karolina Drobnik
2022-01-31 13:30           ` Arnd Bergmann
2022-01-31 15:18             ` Mike Rapoport
2022-01-31 16:26               ` Arnd Bergmann
2022-01-31 10:54         ` Karolina Drobnik
2022-01-27 13:21 ` [PATCH 08/16] tools/include: Add pfn.h stub Karolina Drobnik
2022-01-27 13:21 ` [PATCH 09/16] tools/include: Add debugfs.h stub Karolina Drobnik
2022-01-27 13:21 ` [PATCH 10/16] memblock tests: Add skeleton of the memblock simulator Karolina Drobnik
2022-01-27 14:02   ` Matthew Wilcox
2022-01-27 14:06   ` Matthew Wilcox
2022-01-28 11:25     ` Karolina Drobnik
2022-01-28 13:11       ` Matthew Wilcox
2022-01-27 13:21 ` [PATCH 11/16] memblock tests: Add memblock reset function Karolina Drobnik
2022-01-27 13:21 ` [PATCH 12/16] memblock tests: Add memblock_add tests Karolina Drobnik
2022-01-27 13:21 ` [PATCH 13/16] memblock tests: Add memblock_reserve tests Karolina Drobnik
2022-01-27 13:21 ` [PATCH 14/16] memblock tests: Add memblock_remove tests Karolina Drobnik
2022-01-27 13:21 ` [PATCH 15/16] memblock tests: Add memblock_add_node test Karolina Drobnik
2022-01-27 13:21 ` [PATCH 16/16] memblock tests: Add memblock_free tests Karolina Drobnik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).