linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Karolina Drobnik <karolinadrobnik@gmail.com>
To: linux-mm@kvack.org
Cc: akpm@linux-foundation.org, rppt@kernel.org,
	linux-kernel@vger.kernel.org,
	Karolina Drobnik <karolinadrobnik@gmail.com>
Subject: [PATCH v2 16/16] memblock tests: Add memblock_free tests
Date: Wed,  2 Feb 2022 12:03:15 +0100	[thread overview]
Message-ID: <30af95c82754ad8029404c3b528a5ef1c05d1ed6.1643796665.git.karolinadrobnik@gmail.com> (raw)
In-Reply-To: <cover.1643796665.git.karolinadrobnik@gmail.com>

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



  parent reply	other threads:[~2022-02-02 11:04 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-02 11:02 [PATCH v2 00/16] Introduce memblock simulator Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 01/16] tools: Move gfp.h and slab.h from radix-tree to lib Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 02/16] tools/include: Add phys_addr_t to types.h Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 03/16] tools/include: Add _RET_IP_ and math definitions to kernel.h Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 04/16] tools/include: Update atomic definitions Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 05/16] tools/include: Add mm.h file Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 06/16] tools/include: Add cache.h stub Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 07/16] tools/include: Add io.h stub Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 08/16] tools/include: Add pfn.h stub Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 09/16] tools/include: Add debugfs.h stub Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 10/16] memblock tests: Add skeleton of the memblock simulator Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 11/16] memblock tests: Add memblock reset function Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 12/16] memblock tests: Add memblock_add tests Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 13/16] memblock tests: Add memblock_reserve tests Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 14/16] memblock tests: Add memblock_remove tests Karolina Drobnik
2022-02-02 11:03 ` [PATCH v2 15/16] memblock tests: Add memblock_add_node test Karolina Drobnik
2022-02-02 11:03 ` Karolina Drobnik [this message]
2022-02-09  7:30 ` [PATCH v2 00/16] Introduce memblock simulator Mike Rapoport

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=30af95c82754ad8029404c3b528a5ef1c05d1ed6.1643796665.git.karolinadrobnik@gmail.com \
    --to=karolinadrobnik@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=rppt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).