From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFEC7C3ABAA for ; Tue, 29 Apr 2025 09:07:35 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 3F8526B000A; Tue, 29 Apr 2025 05:07:30 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 3AC466B000C; Tue, 29 Apr 2025 05:07:30 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 160D16B000D; Tue, 29 Apr 2025 05:07:30 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id E72DA6B000A for ; Tue, 29 Apr 2025 05:07:29 -0400 (EDT) Received: from smtpin07.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id C285ABCD1C for ; Tue, 29 Apr 2025 09:07:31 +0000 (UTC) X-FDA: 83386503102.07.FA4D714 Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) by imf05.hostedemail.com (Postfix) with ESMTP id ED430100002 for ; Tue, 29 Apr 2025 09:07:29 +0000 (UTC) Authentication-Results: imf05.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=PUUiiWCA; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf05.hostedemail.com: domain of richard.weiyang@gmail.com designates 209.85.218.53 as permitted sender) smtp.mailfrom=richard.weiyang@gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1745917650; a=rsa-sha256; cv=none; b=H1mGCEbNKtvaD+VZXCvC3CpW2MZZVvqXggN9F+W2DB5keKpJJqUfhpg/Sz3UeZVQeQDVlc wGA7D/hfWt7ZrpWZFwnnGsZNBswngaJ8GRFW2YI46LlCMSPElUtyncAUoBEZyFsTMkSM4X h65j3XOhZIJx8md2fMANmg7P+uzoKtQ= ARC-Authentication-Results: i=1; imf05.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=PUUiiWCA; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf05.hostedemail.com: domain of richard.weiyang@gmail.com designates 209.85.218.53 as permitted sender) smtp.mailfrom=richard.weiyang@gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1745917650; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:in-reply-to: references:references:dkim-signature; bh=POrOhmmty1h2OV+JLi9aspsgrBKOXREGtwR5bXdV7b0=; b=a+Bb1Ic7rk9r1m7pAZ1RWJnY6pgoi1iD+VBvUpyhNokfUTjVMY4tfsgX5VZ9iFJmkhDTGB OUPEfMQ8xYlMuBUajgWzEMUzYbkPcgdhwDIlVFYEfxyCyZbWkZB4qZn7P64aYCq2YJH9aI Cku0U16q5YOGnnL2Y6AMR00aRvk2HK4= Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ac2af2f15d1so707891566b.1 for ; Tue, 29 Apr 2025 02:07:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1745917648; x=1746522448; darn=kvack.org; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=POrOhmmty1h2OV+JLi9aspsgrBKOXREGtwR5bXdV7b0=; b=PUUiiWCAsjHRO7SQE7JRf9zkNJFBkyg5GwW4MFqIDsXAJlfeIsP9FK+aOnt1F6+ME8 VfDtwSZOaqNKpsehLzyYDditsypXqsu/nTyqt6tgSbo8QUq33fGkAcBqYdvuqxCvjpro cXSj1qf9YfqqLXT6Rb3SVojhmnoECBN2Pw2GL9iu+MSUhxFYFt7VLFbRE9xckEmn3XRv 8hVr2OCVM1IRENXVo75cKj8GAPnCA5MbTq9JfUpVc98dypyyjaO9dRg4c603+KPvyWrf mKC6IDnTrVMES6XKpcAGOQ+ivdzRVsG6DyCGjqgxOgs+KK86r+iiQx0G5815xkbsYcrN OLLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745917648; x=1746522448; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=POrOhmmty1h2OV+JLi9aspsgrBKOXREGtwR5bXdV7b0=; b=GvsiCo9O/bswTtTyt4ST0id24Zuy6SRbTqKRYs8gejjuLURVd1riiw2jXyhz6kJcTp RfMCT6Jc5L2/RZHjiIwx3KZNDSdXaxjm/LAkkNPxF4VxoTDig0vTk2o8pHMdnXSMePtU tApNLDudK+jg1P9PHVP0GFHUP+sSfa8nFfUt/i/aME+cYNDP1SzeXTOckzeOvUj8PKfX gAeBDpErOSdFc/jmBeoznh26q55JAu+uvbuQRaAFiWOkSUP8rvZzC7TD4uKcdq7i/TpO wuAFDkE0FeMpH26pzvWF/nYTH6EHh+ELih3H7BER137KnvnPTNW3adSrI/q8Iq+4yKy9 vSLw== X-Forwarded-Encrypted: i=1; AJvYcCVTZI7axe2reYBma53LOgmlv0GUY7oJHhSGgAvfoo83Gja3F76DbtDd5Lz8uUJCSiwMuh/NVGU8/w==@kvack.org X-Gm-Message-State: AOJu0Yx8MDmq/zOHEbi3se/PGo66n7rjEzBQ4uT1YL42BOg6J+kyhepJ /D4SvgEae0LA6/+QzA2fkl0scjfBA4SxdzexVNzInBKUJPTNvdDX X-Gm-Gg: ASbGnct83kpjadBei8NRgNyD8zRFzIorosb/ceG7kBX3OR2AmnGjn4C/SCO92XSMJYM kBUi/dclD0935QdENHEQLGW6bPZv46b56xMCc6AVJ8uZICXgGezbHjfN4i6GnMPpybM6IlLtUUR R+khvtPBeKczCJ3ApiG+J+B4fcejzFlY5U6IOLtuJ6sQG2imlBVIn8vIRkSmk+NpMvn6RBGXFRV OJXPzEHbob9u1OpZLnZsAbyWtZy6rkENvKjV4uOOfkzLk4zRDLfQqkAL6BQQpD93PUQfZ+MULGr VYQniIHAf2Y+S4EG0nfNx3SDIyk70PYo72tAzmdv X-Google-Smtp-Source: AGHT+IEpiVTXz4d5T/igUT/j+yU8FHI6vrwTdyfoQ8r9A3dQTgMHXetkQvoB/5JiM4LOp4LcBNgBzg== X-Received: by 2002:a17:906:5781:b0:acb:39bb:f880 with SMTP id a640c23a62f3a-acec87b3c72mr160359066b.54.1745917648217; Tue, 29 Apr 2025 02:07:28 -0700 (PDT) Received: from localhost ([185.92.221.13]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ace6e4e7260sm743942266b.49.2025.04.29.02.07.26 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 29 Apr 2025 02:07:27 -0700 (PDT) From: Wei Yang To: akpm@linux-foundation.org Cc: david@redhat.com, lorenzo.stoakes@oracle.com, riel@surriel.com, vbabka@suse.cz, harry.yoo@oracle.com, jannh@google.com, baohua@kernel.org, linux-mm@kvack.org, Wei Yang Subject: [RFC Patch 3/5] anon_vma: add test for mergeable anon_vma Date: Tue, 29 Apr 2025 09:06:37 +0000 Message-Id: <20250429090639.784-4-richard.weiyang@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20250429090639.784-1-richard.weiyang@gmail.com> References: <20250429090639.784-1-richard.weiyang@gmail.com> X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: ED430100002 X-Stat-Signature: 4teiiruaon89bj5crbm7aern99fmywdf X-Rspam-User: X-HE-Tag: 1745917649-786019 X-HE-Meta: U2FsdGVkX1/m9Aj+kyfpJoI6aXbEOboX+GUPCEmWFAKQdfz4C4emSIjeyqbmj+m8nGp4SIfup4IOXiYBPBZAmtdqanwAOnfsgsRMyn45KuVYJti3UVUhFiFsAZOafEmqHfFUsryFWD2+tsxTyPSX2HXcWpdgz3gtEDBwLlShzNrLcJhVG5U6Eu7p4ZQROwg/NYjEEQggolGu6YvFIOMRVI6XBZ3eenT2cxIGi1kzHsX1Atly1EZGaCZD9VywnMZqTHxxhOTJPfQN+JEXHhe5SDUTP0UaUcd8wv0Gwz9Qbv8flr0CvxvrxDfM8xI/l4N6Uay6Srw8DcVIZbgcQxp3BErlvNOySqvIEtQUrX3pXENLi4LQaPjYX7JmQAv/WLmXmHBTgDrqoRCyb68gVddz9QX+HuURHnc6gGe7qLtOYjGUfF8+vMkpJ3oxp+wUCxRvN0F1LoGka+gRFlWsl/3efn682wHtoKJZ3380y33Rq6V989CyF0bS4uyZUiXhx6n3+cJzdF/Kj30Qfqu30iIUapTDCyvVBIPJ2iaZ5k9q3CnWUTh0o8HS7lmJOiVz56TSesgHxNvSYOItXvUmqd6E5RqieghUm6Sa5IAm3hl8QvBl1mfepptEIIo3MHq2WGXX2UwUZVN7zIE6LNGfFTeBtaNMJW8qDDZuILqG6YYTcn5eWNu0tCPIeOPi9UAC3K5757L3nAUpsvB6julAd0PW55/LHEBuWa/eiQN93sPMUQB+oz6YPxCLHLAbzRt1ippKXMn/EBc6HUSWnGaPWc04XHx/oN/VAHSQF5D3KPRM1CbqO+5fF1rDNBWN7ng6fh927NNVVWFkCAzEgTjbHPO2O0frNio1X98uVi/5V2yR57ZHbw7TCWboC0cqPYV3XBsoQiDsEaOgCoHykpUrTz1eMig919h1QQSlpkFp3Z1YffTx+4Kpubn3E4fbwJupXqeW4QA+kuczjDxubxPe4b3 Pn1+CRqr yjl0toNdzezniYIAl9sXyT+u1IrbcdlqGGG3upU+dOAlG5oCm5au4RPAbhsAzL6dra4dCAQpazexNRijrjLQo6NxdW2tbgJjOVCBkn5QvXm6B5Saa6Q3m5LoWGbabjrwwJ8/UUGGVGn2yxHhn58RW2yoHtBfVcSrbD88eckDyexNU4L61J0ZBNI4/tNgabwKabeHxoWGAQ5c+qmqgaJdctlKMVJ79WSnl/W0/APggC9d3IGKBHIw53vdKg2Rz271luAR302i5LOVJLU1+aAC+nvZRyE1S5cVObp5mOlZfRGdLtdDgCcKBV7WdEzbWDv6MrDWsXJVmLfe6KRr1cdYRZo0yjfonB/RFAB4VIdzTVJvoTNCg3UfGrgr4QSQkmQRijOFTuu0h/sQ7Lm51ZH6POiH+0B4PLdNYnGc4heoPoVU45G5VBHgZGopymeVv7/qC0i4EZ0nfmDteno7QLU7ftdOpsBBdXYxWDTINfz7U+U8ffIEfeO/nQQShUGmjz8hJNbeT3xZ/gfPcKxaTKRDnc7NhjgYYLBESZwcnLVjWbKHPXEqWQCV8P+MCe/VurYY78402Ygcxogwnw0vuRxpvBNFwLs/CqqCnOLXS3iNSjcbHIbiiqJ7sCmb7Pg== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add test to assert anon_vma is mergeable at the first level. Signed-off-by: Wei Yang Cc: Lorenzo Stoakes Cc: Jann Horn Cc: David Hildenbrand Cc: Barry Song --- tools/testing/anon_vma/anon_vma.c | 149 +++++++++++++++++++++ tools/testing/anon_vma/anon_vma_internal.h | 35 ++++- 2 files changed, 183 insertions(+), 1 deletion(-) diff --git a/tools/testing/anon_vma/anon_vma.c b/tools/testing/anon_vma/anon_vma.c index f3ca193857ec..2e6a1200e6c7 100644 --- a/tools/testing/anon_vma/anon_vma.c +++ b/tools/testing/anon_vma/anon_vma.c @@ -29,6 +29,7 @@ static struct mm_struct dummy_mm = { static int vmas_idx; static struct vm_area_struct *vmas[NUM_VMAS]; static struct kmem_cache *vm_area_cachep; +struct vm_area_struct *mergeable_vma = NULL; static void vma_ctor(void *data) { @@ -79,6 +80,7 @@ void cleanup(void) } vmas_idx = 0; + mergeable_vma = NULL; } static bool test_simple_fault(void) @@ -408,6 +410,152 @@ static bool test_fork_grand_child(void) return true; } +static bool test_mergeable_vma(void) +{ + struct vm_area_struct *root_vma, *child_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 anonymous vma. */ + __anon_vma_prepare(root_vma); + bitmap_set(expected, root_vma->index, 1); + root_anon_vma = root_vma->anon_vma; + ASSERT_NE(NULL, root_anon_vma); + ASSERT_EQ(1, root_anon_vma->num_active_vmas); + + mergeable_vma = root_vma; + + vma1 = alloc_vma(0x5000, 0x7000, 5); + /* First fault on next adjacent anonymous vma. */ + /* + * root_anon_vma + * +-----------+ + * | | + * +-----------+ + * \ + * \------------------+ + * \ root_vma \ vma1 + * \ +-----------+ \ +-----------+ + * > | | > | | + * +-----------+ +-----------+ + */ + __anon_vma_prepare(vma1); + bitmap_set(expected, vma1->index, 1); + ASSERT_EQ(vma1->anon_vma, root_anon_vma); + ASSERT_EQ(2, root_anon_vma->num_active_vmas); + + vma2 = alloc_vma(0x2000, 0x3000, 2); + /* First fault on previous adjacent anonymous vma. */ + /* + * root_anon_vma + * +-----------+ + * | | + * +-----------+ + * \ + * \------------------+------------------+ + * \ vma2 \ root_vma \ vma1 + * \ +-----------+ \ +-----------+ \ +-----------+ + * > | | > | | > | | + * +-----------+ +-----------+ +-----------+ + */ + __anon_vma_prepare(vma2); + bitmap_set(expected, vma2->index, 1); + ASSERT_EQ(vma2->anon_vma, root_anon_vma); + ASSERT_EQ(3, root_anon_vma->num_active_vmas); + dump_anon_vma_interval_tree(root_anon_vma); + + anon_vma_interval_tree_foreach(avc, &root_anon_vma->rb_root, 2, 7) { + bitmap_set(found, avc->vma->index, 1); + } + /* Expect to find all vmas in range [2, 7] */ + ASSERT_TRUE(bitmap_equal(expected, found, 10)); + + /* Expect to find only root_vma in range [3, 4] */ + anon_vma_interval_tree_foreach(avc, &root_anon_vma->rb_root, 3, 4) { + ASSERT_EQ(avc->vma, root_vma); + } + + /* unmap adjacent vmas before fork */ + unlink_anon_vmas(vma1); + unlink_anon_vmas(vma2); + ASSERT_EQ(1, root_anon_vma->num_active_vmas); + + /* Fork a child from root_vma */ + /* + * root_anon_vma root_vma + * +-----------+ +-----------+ + * | | ---> | | + * +-----------+ +-----------+ + * \ + * \ child_vma + * \ +-----------+ + * > | | + * +-----------+ + */ + child_vma = alloc_vma(0x3000, 0x5000, 3); + anon_vma_fork(child_vma, root_vma); + ASSERT_NE(NULL, child_vma->anon_vma); + /* Parent/Root is root_vma->anon_vma */ + ASSERT_EQ(child_vma->anon_vma->parent, root_vma->anon_vma); + ASSERT_EQ(child_vma->anon_vma->root, root_vma->anon_vma); + + mergeable_vma = child_vma; + + vma1 = alloc_vma(0x5000, 0x7000, 5); + /* First fault on next adjacent anonymous vma in child. */ + /* + * vma1->anon_vma vma1 + * +-----------+ +-----------+ + * | | ---> | | + * +-----------+ +-----------+ + */ + __anon_vma_prepare(vma1); + ASSERT_NE(vma1->anon_vma, child_vma->anon_vma); + ASSERT_EQ(1, child_vma->anon_vma->num_active_vmas); + ASSERT_EQ(1, root_anon_vma->num_active_vmas); + + vma2 = alloc_vma(0x2000, 0x3000, 2); + /* First fault on previous adjacent anonymous vma in child. */ + /* + * vma2->anon_vma vma2 + * +-----------+ +-----------+ + * | | ---> | | + * +-----------+ +-----------+ + */ + __anon_vma_prepare(vma2); + ASSERT_NE(vma2->anon_vma, child_vma->anon_vma); + ASSERT_EQ(1, child_vma->anon_vma->num_active_vmas); + ASSERT_EQ(1, root_anon_vma->num_active_vmas); + + /* Expect to find only 'child_vma' in range [2, 7] */ + anon_vma_interval_tree_foreach(avc, &child_vma->anon_vma->rb_root, 2, 7) { + ASSERT_EQ(avc->vma, child_vma); + } + + cleanup(); + + ASSERT_EQ(0, nr_allocated); + return true; +} + int main(void) { int num_tests = 0, num_fail = 0; @@ -428,6 +576,7 @@ int main(void) TEST(simple_fork); TEST(fork_two); TEST(fork_grand_child); + TEST(mergeable_vma); #undef TEST diff --git a/tools/testing/anon_vma/anon_vma_internal.h b/tools/testing/anon_vma/anon_vma_internal.h index 296c1df71f7c..a761048a2f34 100644 --- a/tools/testing/anon_vma/anon_vma_internal.h +++ b/tools/testing/anon_vma/anon_vma_internal.h @@ -33,11 +33,44 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem) return 0; } -static inline struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma) +extern struct vm_area_struct *mergeable_vma; + +static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b) { + return a->vm_end == b->vm_start && + b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT); +} + +static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, + struct vm_area_struct *a, + struct vm_area_struct *b) +{ + if (anon_vma_compatible(a, b)) { + struct anon_vma *anon_vma = READ_ONCE(old->anon_vma); + + if (anon_vma && list_is_singular(&old->anon_vma_chain)) + return anon_vma; + } return NULL; } +static inline struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma) +{ + struct anon_vma *anon_vma = NULL; + + if (!mergeable_vma) + return NULL; + + /* Try next first. */ + if (mergeable_vma->vm_start >= vma->vm_end) { + anon_vma = reusable_anon_vma(mergeable_vma, vma, mergeable_vma); + if (anon_vma) + return anon_vma; + } + + return reusable_anon_vma(mergeable_vma, mergeable_vma, vma); +} + #ifndef pgoff_t #define pgoff_t unsigned long #endif -- 2.34.1