From: Rebecca Mckeever <remckee0@gmail.com>
To: "Huang, Shaoqin" <shaoqin.huang@intel.com>
Cc: Mike Rapoport <rppt@kernel.org>,
Karolina Drobnik <karolinadrobnik@gmail.com>,
David Hildenbrand <david@redhat.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] memblock test: Add test to memblock_add() 129th region
Date: Thu, 4 Aug 2022 00:34:38 -0500 [thread overview]
Message-ID: <YutabjAN+hJwUaoF@bertie> (raw)
In-Reply-To: <4c8def19-650e-7bc3-a581-3ce2b7c0b3cf@intel.com>
On Tue, Aug 02, 2022 at 03:38:37PM +0800, Huang, Shaoqin wrote:
>
>
> On 8/2/2022 3:15 PM, Mike Rapoport wrote:
> > On Mon, Aug 01, 2022 at 02:48:36PM +0800, shaoqin.huang@intel.com wrote:
> > > From: Shaoqin Huang <shaoqin.huang@intel.com>
> > >
> > > Add 129th region into the memblock, and this will trigger the
> > > memblock_double_array() function, this needs valid memory regions. So
> > > using dummy_physical_memory_init() to allocate some valid memory, when
> > > memblock_double_array() choose a new memory region from memory.regions,
> > > it will always choose a valid memory region if we add all valid memory
> > > region, so the memblock_double_array() must success.
> > >
> > > Another thing should be done is to restore the memory.regions after
> > > memblock_double_array(), due to now the memory.regions is pointing to a
> > > memory region allocated by dummy_physical_memory_init(). And it will
> > > affect the subsequent tests if we don't restore the memory region. So
> > > Simply record the origin region, and restore it after the test.
> > >
> > > Signed-off-by: Shaoqin Huang <shaoqin.huang@intel.com>
> > > ---
> > > Changelog:
> > > ----------
> > > v2:
> > > - Use ASSERT_EQ() to replace assert().
> > > - Not to expose memory_block, and add a function get_memory_block_base() to
> > > get the memory_block.base.
> > > - Add two functions for common usage, and now it has been used by this patch
> > > to allocate many valid memory regions and free them at the end.
> > >
> > > tools/testing/memblock/tests/basic_api.c | 54 ++++++++++++++++++++++++
> > > tools/testing/memblock/tests/common.c | 38 +++++++++++++++--
> > > tools/testing/memblock/tests/common.h | 6 +++
> > > 3 files changed, 95 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
> > > index 66f46f261e66..46948d5a975e 100644
> > > --- a/tools/testing/memblock/tests/basic_api.c
> > > +++ b/tools/testing/memblock/tests/basic_api.c
> > > @@ -326,6 +326,59 @@ static int memblock_add_twice_check(void)
> > > return 0;
> > > }
> > > +static int memblock_add_many_check(void)
> > > +{
> > > + void *base[INIT_MEMBLOCK_REGIONS + 1];
> > > + void *orig_region;
> > > + struct region r = {
> > > + .base = SZ_16K,
> > > + .size = MEM_SIZE,
> > > + };
> > > +
> > > + PREFIX_PUSH();
> > > +
> > > + reset_memblock_regions();
> > > + memblock_allow_resize();
> > > +
> > > + dummy_physical_memory_many_init(base, INIT_MEMBLOCK_REGIONS);
> >
> > Why do we need this?
>
> I want to memblock_add() 128 regions that every region has a valid
> "physical" memory. So it can make sure the memblock_double_array() success
> when add a 129-th region.
>
> In the last patch, I didn't put this function here, I just memblock_add()
> 128 region at here. And after I think if we can encapsulate it to a
> function, later it can be used to init some valid memory regions into the
> memblock.
>
> And if no others may be use this functions, the function is not needed.
>
> >
> > dummy_physical_memory_init() allocates the "physical" memory, so to trigger
> > memblock_double_array() it's enough to memblock_add() 129 non-intersecting
> > chunks in the range [memory_block.base, memory_block.base + MEM_SIZE].
> > If MEM_SIZE of 16k won't be enough, it can be increased.
> >
>
> Yes. And now MEM_SIZE of 16k is enough, no need to increase it now.
>
I experimented with only calling dummy_physical_memory_init() once at the
beginning and then adding all 129 regions into the memory allocated with
that call. I found that it only works if at least one of the regions is
SZ_16K or larger. I think this is because memblock_double_array() needs to
find a contiguous region large enough to hold
PAGE_ALIGN(new regions array). If all the regions are SZ_8K or smaller, I
get the error message:
memblock: Failed to double memory array from 128 to 256 entries !
What I did was increase MEM_SIZE to SZ_32K, then memblock_add a SZ_16K
region after calling dummy_physical_memory_init() once. Then, I made the
remaining regions SZ_16, with a SZ_16 gap between each region.
> > > +
> > > + orig_region = memblock.memory.regions;
> > > +
> > > + /* This adds the 129 memory_region, and makes it double array. */
> > > + dummy_physical_memory_init();
> > > + append_memblock();
> > > + base[INIT_MEMBLOCK_REGIONS] = get_memory_block_base();
> > > +
> > > + ASSERT_EQ(memblock.memory.cnt, INIT_MEMBLOCK_REGIONS + 1);
> > > + ASSERT_EQ(memblock.memory.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE);
> > > + ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2);
> > > +
> > > + /* The base is very small, so it should be insert to the first region. */
> > > + memblock_add(r.base, r.size);
> > > + ASSERT_EQ(memblock.memory.regions[0].base, r.base);
> > > + ASSERT_EQ(memblock.memory.regions[0].size, r.size);
> > > +
> > > + ASSERT_EQ(memblock.memory.cnt, INIT_MEMBLOCK_REGIONS + 2);
> > > + ASSERT_EQ(memblock.memory.total_size, (INIT_MEMBLOCK_REGIONS + 2) * MEM_SIZE);
> > > + ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2);
> > > +
> > > + /* Free these allocated memory. */
> > > + dummy_physical_memory_many_cleanup(base, INIT_MEMBLOCK_REGIONS + 1);
> > > +
> > > + /*
> > > + * The current memory.regions is occupying a range of memory that
> > > + * allocated from dummy_physical_memory_init(). After free the memory,
> > > + * we must not use it. So restore the origin memory region to make sure
> > > + * the tests can run as normal and not affected by the double array.
> > > + */
> > > + memblock.memory.regions = orig_region;
> > > + memblock.memory.cnt = INIT_MEMBLOCK_REGIONS;
> > > +
> > > + test_pass_pop();
> > > +
> > > + return 0;
> > > +}
> > > +
> > > static int memblock_add_checks(void)
> > > {
> > > prefix_reset();
> > > @@ -339,6 +392,7 @@ static int memblock_add_checks(void)
> > > memblock_add_overlap_bottom_check();
> > > memblock_add_within_check();
> > > memblock_add_twice_check();
> > > + memblock_add_many_check();
> > > prefix_pop();
> > > diff --git a/tools/testing/memblock/tests/common.c b/tools/testing/memblock/tests/common.c
> > > index e43b2676af81..960b3ce07696 100644
> > > --- a/tools/testing/memblock/tests/common.c
> > > +++ b/tools/testing/memblock/tests/common.c
> > > @@ -5,8 +5,6 @@
> > > #include <linux/memory_hotplug.h>
> > > #include <linux/build_bug.h>
> > > -#define INIT_MEMBLOCK_REGIONS 128
> > > -#define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS
> > > #define PREFIXES_MAX 15
> > > #define DELIM ": "
> > > @@ -58,10 +56,20 @@ void reset_memblock_attributes(void)
> > > memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE;
> > > }
> > > +void *get_memory_block_base(void)
> > > +{
> > > + return memory_block.base;
> > > +}
> > > +
> > > +void append_memblock(void)
> > > +{
> > > + memblock_add((phys_addr_t)memory_block.base, MEM_SIZE);
> > > +}
> > > +
> > > void setup_memblock(void)
> > > {
> > > reset_memblock_regions();
> > > - memblock_add((phys_addr_t)memory_block.base, MEM_SIZE);
> > > + append_memblock();
> > > }
> > > void dummy_physical_memory_init(void)
> > > @@ -75,6 +83,30 @@ void dummy_physical_memory_cleanup(void)
> > > free(memory_block.base);
> > > }
> > > +void dummy_physical_memory_many_init(void *base[], int cnt)
> > > +{
> > > + int i;
> > > +
> > > + for (i = 0; i < cnt; i++) {
> > > + dummy_physical_memory_init();
> > > + append_memblock();
> > > + base[i] = memory_block.base;
> > > +
> > > + ASSERT_EQ(memblock.memory.cnt, i + 1);
> > > + ASSERT_EQ(memblock.memory.total_size, (i + 1) * MEM_SIZE);
> > > + }
> > > +}
> > > +
> > > +void dummy_physical_memory_many_cleanup(void *base[], int cnt)
> > > +{
> > > + int i;
> > > +
> > > + for (i = 0; i < cnt; i++) {
> > > + memory_block.base = base[i];
> > > + dummy_physical_memory_cleanup();
> > > + }
> > > +}
> > > +
> > > static void usage(const char *prog)
> > > {
> > > BUILD_BUG_ON(ARRAY_SIZE(help_opts) != ARRAY_SIZE(long_opts) - 1);
> > > diff --git a/tools/testing/memblock/tests/common.h b/tools/testing/memblock/tests/common.h
> > > index 3e7f23d341d7..848900aa8db6 100644
> > > --- a/tools/testing/memblock/tests/common.h
> > > +++ b/tools/testing/memblock/tests/common.h
> > > @@ -11,6 +11,8 @@
> > > #include <../selftests/kselftest.h>
> > > #define MEM_SIZE SZ_16K
> > > +#define INIT_MEMBLOCK_REGIONS 128
> > > +#define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS
> > > /**
> > > * ASSERT_EQ():
> > > @@ -68,8 +70,12 @@ struct region {
> > > void reset_memblock_regions(void);
> > > void reset_memblock_attributes(void);
> > > void setup_memblock(void);
> > > +void append_memblock(void);
> > > +void *get_memory_block_base(void);
> > > void dummy_physical_memory_init(void);
> > > void dummy_physical_memory_cleanup(void);
> > > +void dummy_physical_memory_many_init(void *base[], int cnt);
> > > +void dummy_physical_memory_many_cleanup(void *base[], int cnt);
> > > void parse_args(int argc, char **argv);
> > > void test_fail(void);
> > > --
> > > 2.30.2
> > >
> > >
> >
Thanks,
Rebecca
prev parent reply other threads:[~2022-08-04 5:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-01 6:48 [PATCH v2] memblock test: Add test to memblock_add() 129th region shaoqin.huang
2022-08-02 7:15 ` Mike Rapoport
2022-08-02 7:38 ` Huang, Shaoqin
2022-08-04 5:34 ` Rebecca Mckeever [this message]
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=YutabjAN+hJwUaoF@bertie \
--to=remckee0@gmail.com \
--cc=david@redhat.com \
--cc=karolinadrobnik@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=rppt@kernel.org \
--cc=shaoqin.huang@intel.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.