linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
To: Wei Yang <richard.weiyang@gmail.com>
Cc: akpm@linux-foundation.org, david@redhat.com, riel@surriel.com,
	vbabka@suse.cz, harry.yoo@oracle.com, jannh@google.com,
	baohua@kernel.org, linux-mm@kvack.org
Subject: Re: [RFC Patch 2/5] anon_vma: add skeleton code for userland testing of anon_vma logic
Date: Thu, 1 May 2025 10:41:54 +0100	[thread overview]
Message-ID: <def14f74-70ea-4bf1-8de6-e2224243be5d@lucifer.local> (raw)
In-Reply-To: <20250501013127.rzaos7co7b63so4r@master>

On Thu, May 01, 2025 at 01:31:27AM +0000, Wei Yang wrote:
> On Tue, Apr 29, 2025 at 09:06:36AM +0000, Wei Yang wrote:
> [...]
> >+
> >+static bool test_fork_grand_child(void)
> >+{
> >+	struct vm_area_struct *root_vma, *grand_vma, *vma1, *vma2;
> >+	struct anon_vma_chain *avc;
> >+	struct anon_vma *root_anon_vma;
> >+	DECLARE_BITMAP(expected, 10);
> >+	DECLARE_BITMAP(found, 10);
> >+
> >+	bitmap_zero(expected, 10);
> >+	bitmap_zero(found, 10);
> >+
> >+	/*
> >+	 *  root_anon_vma      root_vma
> >+	 *  +-----------+      +-----------+
> >+	 *  |           | ---> |           |
> >+	 *  +-----------+      +-----------+
> >+	 */
> >+
> >+	root_vma = alloc_vma(0x3000, 0x5000, 3);
> >+	/* First fault on parent anonymous vma. */
> >+	__anon_vma_prepare(root_vma);
> >+	root_anon_vma = root_vma->anon_vma;
> >+	ASSERT_NE(NULL, root_anon_vma);
> >+	bitmap_set(expected, root_vma->index, 1);
> >+
> >+	/* First fork */
> >+	/*
> >+	 *  root_anon_vma      root_vma
> >+	 *  +-----------+      +-----------+
> >+	 *  |           | ---> |           |
> >+	 *  +-----------+      +-----------+
> >+	 *                \
> >+	 *                 \   vma1
> >+	 *                  \  +-----------+
> >+	 *                   > |           |
> >+	 *                     +-----------+
> >+	 */
> >+	vma1 = alloc_vma(0x3000, 0x5000, 3);
> >+	anon_vma_fork(vma1, root_vma);
> >+	ASSERT_NE(NULL, vma1->anon_vma);
> >+	bitmap_set(expected, vma1->index, 1);
> >+	/* Parent/Root is root_vma->anon_vma */
> >+	ASSERT_EQ(vma1->anon_vma->parent, root_vma->anon_vma);
> >+	ASSERT_EQ(vma1->anon_vma->root, root_vma->anon_vma);
> >+
> >+	/* Second fork */
> >+	/*
> >+	 *  root_anon_vma      root_vma
> >+	 *  +-----------+      +-----------+
> >+	 *  |           | ---> |           |
> >+	 *  +-----------+      +-----------+
> >+	 *               \
> >+	 *                \------------------+
> >+	 *                 \   vma1           \   vma2
> >+	 *                  \  +-----------+   \  +-----------+
> >+	 *                   > |           |    > |           |
> >+	 *                     +-----------+      +-----------+
> >+	 */
> >+	vma2 = alloc_vma(0x3000, 0x5000, 3);
> >+	anon_vma_fork(vma2, root_vma);
> >+	ASSERT_NE(NULL, vma2->anon_vma);
> >+	bitmap_set(expected, vma2->index, 1);
> >+	/* Parent/Root is root_vma->anon_vma */
> >+	ASSERT_EQ(vma2->anon_vma->parent, root_vma->anon_vma);
> >+	ASSERT_EQ(vma2->anon_vma->root, root_vma->anon_vma);
> >+	dump_anon_vma_interval_tree(root_vma->anon_vma);
> >+
> >+	/* Fork grand child from second child */
> >+	/*
> >+	 *  root_anon_vma      root_vma
> >+	 *  +-----------+      +-----------+
> >+	 *  |           | ---> |           |
> >+	 *  +-----------+      +-----------+
> >+	 *               \
> >+	 *                \------------------+
> >+	 *                |\   vma1           \   vma2
> >+	 *                | \  +-----------+   \  +-----------+
> >+	 *                |  > |           |    > |           |
> >+	 *                |    +-----------+      +-----------+
> >+	 *                \
> >+	 *                 \   grand_vma
> >+	 *                  \  +-----------+
> >+	 *                   > |           |
> >+	 *                     +-----------+
> >+	 */
> >+	grand_vma = alloc_vma(0x3000, 0x5000, 3);
> >+	anon_vma_fork(grand_vma, vma2);
> >+	ASSERT_NE(NULL, grand_vma->anon_vma);
> >+	bitmap_set(expected, grand_vma->index, 1);
> >+	/* Root is root_vma->anon_vma */
> >+	ASSERT_EQ(grand_vma->anon_vma->root, root_vma->anon_vma);
> >+	/* Parent is vma2->anon_vma */
> >+	ASSERT_EQ(grand_vma->anon_vma->parent, vma2->anon_vma);
>
> Hi, Lorenzo
>
> Here is the case I am talking about in another thread[1].
>
> The naming is a little different from that.
>
>   * root_vma  is VMA A
>   * vma2      is VMA B
>   * grand_vma is VMA C
>
> If you add following debug code here.
>
> ```
> 	printf("root num_children %d\n", root_vma->anon_vma->num_children);
> 	printf("vma2 num_children %d\n", vma2->anon_vma->num_children);
> 	printf("grand_vma num_children %d\n", grand_vma->anon_vma->num_children);
> ```
>
> You would see vma2 num_children is 1, but it has a child.
>
> If I missed something, feel free to correct me.
>
> [1]: https://lkml.kernel.org/r/20250501011845.ktbfgymor4oz5sok@master
>

See the thread over there. This explanation isn't quite right, and the
diagram is wrong, but indeed anon_vma reuse is a thing that needs
addressing.

Having looked at this more I'm not a huge fan of these tests, you're
essentially open-coding fork over and over again, any change in overlying
fork logic will break.

The VMA and maple tree, etc. unit tests work much better as the whole thing
essentially can be separated out, but in this case you really can't. This
is obviously in addition to the aforementioned issues with causing
separation in an area where I want to try to unify.

So I definitely think that, again, you'd be better off looking at tests as
suggested by David, but moreover I think looking at bugs etc. is more
helpful.

This report was in effect reporting a bug before it happened so all good
for this kind of thing :>) and that is _always_ welcome. But do try to be
more direct and to the point if you can be.

Thanks!


> >+
> >+	/* Expect to find only vmas from second fork */
> >+	anon_vma_interval_tree_foreach(avc, &vma2->anon_vma->rb_root, 3, 4) {
> >+		ASSERT_TRUE(avc->vma == vma2 || avc->vma == grand_vma);
> >+	}
> >+
> >+	anon_vma_interval_tree_foreach(avc, &root_vma->anon_vma->rb_root, 3, 4) {
> >+		bitmap_set(found, avc->vma->index, 1);
> >+	}
> >+	/* Expect to find all vma including child and grand child. */
> >+	ASSERT_TRUE(bitmap_equal(expected, found, 10));
> >+
> >+	/* Root process exit or unmap root_vma. */
> >+	/*
> >+	 *  root_anon_vma
> >+	 *  +-----------+
> >+	 *  |           |
> >+	 *  +-----------+
> >+	 *               \
> >+	 *                \------------------+
> >+	 *                |\   vma1           \   vma2
> >+	 *                | \  +-----------+   \  +-----------+
> >+	 *                |  > |           |    > |           |
> >+	 *                |    +-----------+      +-----------+
> >+	 *                \
> >+	 *                 \   grand_vma
> >+	 *                  \  +-----------+
> >+	 *                   > |           |
> >+	 *                     +-----------+
> >+	 */
> >+	bitmap_clear(expected, root_vma->index, 1);
> >+	unlink_anon_vmas(root_vma);
> >+	ASSERT_EQ(0, root_anon_vma->num_active_vmas);
> >+
> >+	bitmap_zero(found, 10);
> >+	anon_vma_interval_tree_foreach(avc, &root_anon_vma->rb_root, 3, 4) {
> >+		bitmap_set(found, avc->vma->index, 1);
> >+	}
> >+	/* Expect to find all vmas even root_vma released. */
> >+	ASSERT_TRUE(bitmap_equal(expected, found, 10));
> >+
> >+	cleanup();
> >+
> >+	ASSERT_EQ(0, nr_allocated);
> >+	return true;
> >+}
> >+
>
>
> --
> Wei Yang
> Help you, Help me
>


  reply	other threads:[~2025-05-01  9:42 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-29  9:06 [RFC Patch 0/5] Make anon_vma operations testable Wei Yang
2025-04-29  9:06 ` [RFC Patch 1/5] mm: move anon_vma manipulation functions to own file Wei Yang
2025-04-29  9:06 ` [RFC Patch 2/5] anon_vma: add skeleton code for userland testing of anon_vma logic Wei Yang
2025-05-01  1:31   ` Wei Yang
2025-05-01  9:41     ` Lorenzo Stoakes [this message]
2025-05-01 14:45       ` Wei Yang
2025-04-29  9:06 ` [RFC Patch 3/5] anon_vma: add test for mergeable anon_vma Wei Yang
2025-04-29  9:06 ` [RFC Patch 4/5] anon_vma: add test for reusable anon_vma Wei Yang
2025-04-29  9:06 ` [RFC Patch 5/5] anon_vma: add test to assert no double-reuse Wei Yang
2025-04-29  9:31 ` [RFC Patch 0/5] Make anon_vma operations testable Lorenzo Stoakes
2025-04-29  9:38   ` David Hildenbrand
2025-04-29  9:41     ` Lorenzo Stoakes
2025-04-29 23:56       ` Wei Yang
2025-04-30  7:47         ` David Hildenbrand
2025-04-30 15:44           ` Wei Yang
2025-04-30 21:36             ` David Hildenbrand
2025-05-14  1:23           ` Wei Yang
2025-05-27  6:34             ` Wei Yang
2025-05-27 11:31               ` David Hildenbrand
2025-05-28  1:17                 ` Wei Yang
2025-05-30  2:11                 ` Wei Yang
2025-05-30  8:00                   ` David Hildenbrand
2025-05-30 14:05                     ` Wei Yang
2025-05-30 14:39                       ` David Hildenbrand
2025-05-30 23:23                         ` Wei Yang
2025-06-03 21:31                           ` David Hildenbrand
2025-04-29 23:15   ` Wei Yang
2025-04-30 14:38     ` Lorenzo Stoakes
2025-04-30 15:41       ` Wei Yang

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=def14f74-70ea-4bf1-8de6-e2224243be5d@lucifer.local \
    --to=lorenzo.stoakes@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=baohua@kernel.org \
    --cc=david@redhat.com \
    --cc=harry.yoo@oracle.com \
    --cc=jannh@google.com \
    --cc=linux-mm@kvack.org \
    --cc=richard.weiyang@gmail.com \
    --cc=riel@surriel.com \
    --cc=vbabka@suse.cz \
    /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