From patchwork Fri Apr 18 17:49:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057555 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 14ACEC369CA for ; Fri, 18 Apr 2025 17:50:10 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id BF9BE6B02A3; Fri, 18 Apr 2025 13:50:07 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B80C86B02A4; Fri, 18 Apr 2025 13:50:07 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 985376B02A5; Fri, 18 Apr 2025 13:50:07 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 688AC6B02A3 for ; Fri, 18 Apr 2025 13:50:07 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id C0051C0A4C for ; Fri, 18 Apr 2025 17:50:08 +0000 (UTC) X-FDA: 83347903296.05.7F6F40A Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) by imf03.hostedemail.com (Postfix) with ESMTP id EA3B72000E for ; Fri, 18 Apr 2025 17:50:06 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="QVb/G0yW"; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf03.hostedemail.com: domain of 3zZACaAYKCEAuwtgpdiqqing.eqonkpwz-oomxcem.qti@flex--surenb.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3zZACaAYKCEAuwtgpdiqqing.eqonkpwz-oomxcem.qti@flex--surenb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998607; a=rsa-sha256; cv=none; b=judM3a+fjnicuOrt6DJzDH5558BYexgdmreGcMEYyhEs7+fbUFQAPb/IxrQ/4yR1Ewnou1 28GHkzzsbkTbNjDi38l3W4gdbkDjkcZOlpspmlcEvXqQb5S+ezPot0cNol5zXdD8YrI2qM b79j4yeA7rOpkEX4GmSZfe6yNr0XZUY= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="QVb/G0yW"; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf03.hostedemail.com: domain of 3zZACaAYKCEAuwtgpdiqqing.eqonkpwz-oomxcem.qti@flex--surenb.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3zZACaAYKCEAuwtgpdiqqing.eqonkpwz-oomxcem.qti@flex--surenb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998607; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=mgDRBr7EHzoWVxJpYPL/4eCyatCNp0mNaqALeY1G7/4=; b=ZmH/R8Rz9ibwIwQ1cZ+0cPdOfQDJXpZjuVfvcR6vX7YpXUp6SJM2dxhP/8CiBbmG7AxYKq t8WU/9qWRZ3ReCCO87y3aDPEvQd2eAn4VZ1cWcwjyBM4sNk4+CoUJl+iD0oF/9yGGuYYoO b/encY7Gl54OlOhonKoZkWL/0WTmOik= Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-3087a704c6bso1069980a91.2 for ; Fri, 18 Apr 2025 10:50:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998606; x=1745603406; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=mgDRBr7EHzoWVxJpYPL/4eCyatCNp0mNaqALeY1G7/4=; b=QVb/G0yW+5vrlQz29L1z72oZCB5sE+00xHp5rhDBN8L4a5J0e7/yLX9d911WtXxgtz ZbEYhaXeD0GAlKLhD8nnfYUb+67/qsRLzXnq/kTfvvHQbmgXrTY+Ba1MRaPnj/hByCYr U0IjxlA3BXZa3yKSG/op1Mz6NHKSnbGfyrTLlSHs+Mgt7L+hBmpLidNWFCOcTTgSmxyX nZ3PxvD8fSe900IhX53XTB+hMMeexSDCdSFqPdpngo8RRdS5jAnhIQK6+MNFwuu1A8f8 35GZq1Rs1JXh1aKdP0CRbOEO4fDb/RpIXJp2pylPwRyCr9FirlZk/h05GfrzwLrXc26p 4HRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998606; x=1745603406; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mgDRBr7EHzoWVxJpYPL/4eCyatCNp0mNaqALeY1G7/4=; b=izVXYNyJx7vRD9JV8bZnODfMqn7h18G1ZF9UXyvvWnxNxDyNDHPBkrAdaeUmwbgq9L Uiv6ghj2RJf5DKXlmPt2Sqoe3WXacB0fF/BADGe/Vms6gMhZETNBmtBO/4hOWpAmy7Gf sl2wHN1XQCBU047Iw3mgw7sApZ9XMpkJ58MT5N33F3MVc2Vgt9M2GpnU/rQPMQTFdZUy tWJ4cL8QQlr6MXqKuyr+sjLDGQiX8uRoJRQT6ns+PwOmRyvi5V2gHLRT2g12i3mECE0N 7CLnhdescbvQfCd6zVLTDDlYebj+rnTO4tW5AI5R2bROqlqmVTJ+7WJxIcSpa6v1OFQK 8lxw== X-Forwarded-Encrypted: i=1; AJvYcCWm+AQg2DIuscMrg4BPhCvdMTs0yvajPghzu7J0Bem+jxKccBRng1zYl7ETKcKB/mB+BFMvHWLMsw==@kvack.org X-Gm-Message-State: AOJu0YwaGaYyQL9uXHCZRHf9L+99w6YOHzO5+C8Oug6cadtk3S15hENM tV1GeQcrthVKAqFnjLwISUt95Rfs3hvkukcio+q5Bqwr+RkYcaNwLHz6f/c+MDPf0UaMrro5sbF xOA== X-Google-Smtp-Source: AGHT+IHcSsp6fTq+P5mdogx2xA//Oy5g0EOLyOHv8vpLXb30G0tARWpAdcWwAIgGOvySdxYbnBMETRGuhIU= X-Received: from pjbnb11.prod.google.com ([2002:a17:90b:35cb:b0:2fc:201d:6026]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2b90:b0:2fe:80cb:ac05 with SMTP id 98e67ed59e1d1-3087bb48d7bmr5606678a91.9.1744998605831; Fri, 18 Apr 2025 10:50:05 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:52 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-2-surenb@google.com> Subject: [PATCH v3 1/8] selftests/proc: add /proc/pid/maps tearing from vma split test From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Rspam-User: X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: EA3B72000E X-Stat-Signature: twjxyxnbrutq5ciq3rnoziabt9rs6ocd X-HE-Tag: 1744998606-881836 X-HE-Meta: U2FsdGVkX19HqJYPzt6TPyZjkGSUfKBgp0WsFqf8pm4VaFZAzDMGW1d2knUqcJOA3t/b2/6jXDz89xuIDU3lf4XO790W08e1uUgVIlffsTjFYKPLToyDfWjKHBVVM2SbI0/Wlq/XZ7EkJZDCHm/hWUYNvt2x3IDl9LKeD3JGzX8qnkLNJGvoWqRi3EdT8YPjrSDC7DT8/IVOz95xKesV1ekuakCLezMmSF8coaB9Y+SazxMoS4h0PsB0FatcYz4epgVXa9L0GytV3fai3lSiJd6y1EO/FJFOSNoJeWw2pQpa9YReIFs9KT8eJIso5bYG5ko8WJh9fSZ9NqeX1qFn5tIj5/JPLzjtkB8MbWa6wGO1IvrZZWgwYWpPGtUQ+Lp+LIklRKgQdsMTU2OBuFMKCnARmhNyoWh0NJDZpJ/EjllhLdqHP4LiXFwJ4OW5yYUmpsuY2VnsVce0Mid/qfpQ2aBfv+MQy1HiZaWRwxZD8PsSXbdAkv1+0YsDpnyB4n419GwBiTe1+gYqxlW05VJpiAj9nzo0GIfX8EEU7THt0KPVe1g5cvAVnsUc2paapH5Uzpn4jlRco74UuojKMVPVz+GEIHBZTF9mobe6CPRhrntjI1bVu7yoIKnZ7KVTDv9po7+RndZf4iugIOP5mMSqObgUf+X1MScR29M7FxJ7yfiZdb3OS64yNd4EnKC8Fg/xPkvZCZTMzMKHBbXTY1TnL/RKgaAk+bpeDHtGPmoqtvyt68aPEcoxtDqdemXhZ/mqSZg1KsJAQBs29O5HwxPgjpG2uwcohK7L+pf5IGkILCQbueYfOpSBkN8eY23j0zQ70gA0KRC6krtORBMrWC+q/HADPD5cfMLEeCW+hwO89MFhOkR3s2eLM3YFKd369rjpcBdA9nuCEz+TgkfYXdD+5GJprk4q+1ODdunZTfrRLpl/+ZngTYAsw3xD9w2kdiTMgfzhJXeKyVtSHlyvxNi s3PBlBa+ EcFHMGvUWkvjtg2BMCE7IjyAfxKhe2MFX32aC6KvVKCSAQKfsQfC7nuttHxUbO74UV1N84RMsbxg3DyrW6O/WYLYawXL39P7mN6p0AgqOOollsrDlNolU2fVJI4corkhuA4GeQjKnkTYX8aL220Vyk6HEYpJq91bzuh8fAPRG/6xlMqRMsVuTH2XuSAog+0GZYX2MIhL/lsvgXhafT5lpD8OVr3TUS5WfNGSgp6lFXzD8N9k/7P/y9ekrRs6cdRLrDLP0EnmEI04JjhUYhPJOxyWcpdNrpHHp6zvx+rNBnC4FyaJPJ4ZgRbzl7Tp1ppWUZ2kh1rEvjEkxQZfNhYTk9Vb2BdeLfh4AN0z2+TfGR5odV8V7fp9Z4/UiVUulGEbvv2UBRi8JV0LVOr4YD1s+X7TBifG+Ez0UEv36uWBByFWYkz03xhVprsez4y1Jv+FnYqv1b9VtqRzac8ljqa+p8uJd8MLpyT4WctcfeAwM+bVM4D5pJJNP+o/U4/y1UuH3HWTM3kSUH3fXRy8pzstzEC2r/sbImjZMF3IQojZoFFCpxCE= 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: The content of /proc/pid/maps is generated page-by-page with mmap_lock read lock (or other synchronization mechanism) being dropped in between these pages. This means that the reader can occasionally retrieve inconsistent information if the data used for file generation is being concurrently changed. For /proc/pid/maps that means it's possible to read inconsistent data if vmas or vma tree are concurrently modified. A simple example is when a vma gets split or merged. If such action happens while /proc/pid/maps is read and this vma happens to be at the edge of the two pages being generated, the readers can see the same vma twice: once before it got modified and second time after the modification. This is considered acceptable if the same vma is seen twice and userspace can deal with this situation. What is unacceptable is if we see a hole in the place occupied by a vma, for example as a result of a vma being replaced with another one, leaving the space temporarily empty. Implement a test that reads /proc/pid/maps of a forked child process and checks data consistency at the edge of two pages. Child process constantly modifies its address space in a way that affects the vma located at the end of the first page when /proc/pid/maps is read by the parent process. The parent checks the last vma of the first page and the first vma of the last page for consistency with the split/merge results. Since the test is designed to create a race between the file reader and vma tree modifier, we need multiple iterations to catch invalid results. To limit the time test is run, introduce a command line parameter specifying the duration of the test in seconds. For example, the following command will allow this concurrency test to run for 10 seconds: proc-pid-vm -d 10 The default test duration is set to 5 seconds. Signed-off-by: Suren Baghdasaryan --- tools/testing/selftests/proc/proc-pid-vm.c | 430 ++++++++++++++++++++- 1 file changed, 429 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index d04685771952..6e3f06376a1f 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c @@ -27,6 +27,7 @@ #undef NDEBUG #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +72,8 @@ static void make_private_tmp(void) } } +static unsigned long test_duration_sec = 5UL; +static int page_size; static pid_t pid = -1; static void ate(void) { @@ -281,11 +285,431 @@ static void vsyscall(void) } } -int main(void) +/* /proc/pid/maps parsing routines */ +struct page_content { + char *data; + ssize_t size; +}; + +#define LINE_MAX_SIZE 256 + +struct line_content { + char text[LINE_MAX_SIZE]; + unsigned long start_addr; + unsigned long end_addr; +}; + +static void read_two_pages(int maps_fd, struct page_content *page1, + struct page_content *page2) +{ + ssize_t bytes_read; + + assert(lseek(maps_fd, 0, SEEK_SET) >= 0); + bytes_read = read(maps_fd, page1->data, page_size); + assert(bytes_read > 0 && bytes_read < page_size); + page1->size = bytes_read; + + bytes_read = read(maps_fd, page2->data, page_size); + assert(bytes_read > 0 && bytes_read < page_size); + page2->size = bytes_read; +} + +static void copy_first_line(struct page_content *page, char *first_line) +{ + char *pos = strchr(page->data, '\n'); + + strncpy(first_line, page->data, pos - page->data); + first_line[pos - page->data] = '\0'; +} + +static void copy_last_line(struct page_content *page, char *last_line) +{ + /* Get the last line in the first page */ + const char *end = page->data + page->size - 1; + /* skip last newline */ + const char *pos = end - 1; + + /* search previous newline */ + while (pos[-1] != '\n') + pos--; + strncpy(last_line, pos, end - pos); + last_line[end - pos] = '\0'; +} + +/* Read the last line of the first page and the first line of the second page */ +static void read_boundary_lines(int maps_fd, struct page_content *page1, + struct page_content *page2, + struct line_content *last_line, + struct line_content *first_line) +{ + read_two_pages(maps_fd, page1, page2); + + copy_last_line(page1, last_line->text); + copy_first_line(page2, first_line->text); + + assert(sscanf(last_line->text, "%lx-%lx", &last_line->start_addr, + &last_line->end_addr) == 2); + assert(sscanf(first_line->text, "%lx-%lx", &first_line->start_addr, + &first_line->end_addr) == 2); +} + +/* Thread synchronization routines */ +enum test_state { + INIT, + CHILD_READY, + PARENT_READY, + SETUP_READY, + SETUP_MODIFY_MAPS, + SETUP_MAPS_MODIFIED, + SETUP_RESTORE_MAPS, + SETUP_MAPS_RESTORED, + TEST_READY, + TEST_DONE, +}; + +struct vma_modifier_info; + +typedef void (*vma_modifier_op)(const struct vma_modifier_info *mod_info); +typedef void (*vma_mod_result_check_op)(struct line_content *mod_last_line, + struct line_content *mod_first_line, + struct line_content *restored_last_line, + struct line_content *restored_first_line); + +struct vma_modifier_info { + int vma_count; + void *addr; + int prot; + void *next_addr; + vma_modifier_op vma_modify; + vma_modifier_op vma_restore; + vma_mod_result_check_op vma_mod_check; + pthread_mutex_t sync_lock; + pthread_cond_t sync_cond; + enum test_state curr_state; + bool exit; + void *child_mapped_addr[]; +}; + +static void wait_for_state(struct vma_modifier_info *mod_info, enum test_state state) +{ + pthread_mutex_lock(&mod_info->sync_lock); + while (mod_info->curr_state != state) + pthread_cond_wait(&mod_info->sync_cond, &mod_info->sync_lock); + pthread_mutex_unlock(&mod_info->sync_lock); +} + +static void signal_state(struct vma_modifier_info *mod_info, enum test_state state) +{ + pthread_mutex_lock(&mod_info->sync_lock); + mod_info->curr_state = state; + pthread_cond_signal(&mod_info->sync_cond); + pthread_mutex_unlock(&mod_info->sync_lock); +} + +/* VMA modification routines */ +static void *child_vma_modifier(struct vma_modifier_info *mod_info) +{ + int prot = PROT_READ | PROT_WRITE; + int i; + + for (i = 0; i < mod_info->vma_count; i++) { + mod_info->child_mapped_addr[i] = mmap(NULL, page_size * 3, prot, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(mod_info->child_mapped_addr[i] != MAP_FAILED); + /* change protection in adjacent maps to prevent merging */ + prot ^= PROT_WRITE; + } + signal_state(mod_info, CHILD_READY); + wait_for_state(mod_info, PARENT_READY); + while (true) { + signal_state(mod_info, SETUP_READY); + wait_for_state(mod_info, SETUP_MODIFY_MAPS); + if (mod_info->exit) + break; + + mod_info->vma_modify(mod_info); + signal_state(mod_info, SETUP_MAPS_MODIFIED); + wait_for_state(mod_info, SETUP_RESTORE_MAPS); + mod_info->vma_restore(mod_info); + signal_state(mod_info, SETUP_MAPS_RESTORED); + + wait_for_state(mod_info, TEST_READY); + while (mod_info->curr_state != TEST_DONE) { + mod_info->vma_modify(mod_info); + mod_info->vma_restore(mod_info); + } + } + for (i = 0; i < mod_info->vma_count; i++) + munmap(mod_info->child_mapped_addr[i], page_size * 3); + + return NULL; +} + +static void stop_vma_modifier(struct vma_modifier_info *mod_info) +{ + wait_for_state(mod_info, SETUP_READY); + mod_info->exit = true; + signal_state(mod_info, SETUP_MODIFY_MAPS); +} + +static void capture_mod_pattern(int maps_fd, + struct vma_modifier_info *mod_info, + struct page_content *page1, + struct page_content *page2, + struct line_content *last_line, + struct line_content *first_line, + struct line_content *mod_last_line, + struct line_content *mod_first_line, + struct line_content *restored_last_line, + struct line_content *restored_first_line) +{ + signal_state(mod_info, SETUP_MODIFY_MAPS); + wait_for_state(mod_info, SETUP_MAPS_MODIFIED); + + /* Copy last line of the first page and first line of the last page */ + read_boundary_lines(maps_fd, page1, page2, mod_last_line, mod_first_line); + + signal_state(mod_info, SETUP_RESTORE_MAPS); + wait_for_state(mod_info, SETUP_MAPS_RESTORED); + + /* Copy last line of the first page and first line of the last page */ + read_boundary_lines(maps_fd, page1, page2, restored_last_line, restored_first_line); + + mod_info->vma_mod_check(mod_last_line, mod_first_line, + restored_last_line, restored_first_line); + + /* + * The content of these lines after modify+resore should be the same + * as the original. + */ + assert(strcmp(restored_last_line->text, last_line->text) == 0); + assert(strcmp(restored_first_line->text, first_line->text) == 0); +} + +static inline void split_vma(const struct vma_modifier_info *mod_info) +{ + assert(mmap(mod_info->addr, page_size, mod_info->prot | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0) != MAP_FAILED); +} + +static inline void merge_vma(const struct vma_modifier_info *mod_info) +{ + assert(mmap(mod_info->addr, page_size, mod_info->prot, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0) != MAP_FAILED); +} + +static inline void check_split_result(struct line_content *mod_last_line, + struct line_content *mod_first_line, + struct line_content *restored_last_line, + struct line_content *restored_first_line) +{ + /* Make sure vmas at the boundaries are changing */ + assert(strcmp(mod_last_line->text, restored_last_line->text) != 0); + assert(strcmp(mod_first_line->text, restored_first_line->text) != 0); +} + +static void test_maps_tearing_from_split(int maps_fd, + struct vma_modifier_info *mod_info, + struct page_content *page1, + struct page_content *page2, + struct line_content *last_line, + struct line_content *first_line) +{ + struct line_content split_last_line; + struct line_content split_first_line; + struct line_content restored_last_line; + struct line_content restored_first_line; + + wait_for_state(mod_info, SETUP_READY); + + /* re-read the file to avoid using stale data from previous test */ + read_boundary_lines(maps_fd, page1, page2, last_line, first_line); + + mod_info->vma_modify = split_vma; + mod_info->vma_restore = merge_vma; + mod_info->vma_mod_check = check_split_result; + + capture_mod_pattern(maps_fd, mod_info, page1, page2, last_line, first_line, + &split_last_line, &split_first_line, + &restored_last_line, &restored_first_line); + + /* Now start concurrent modifications for test_duration_sec */ + signal_state(mod_info, TEST_READY); + + struct line_content new_last_line; + struct line_content new_first_line; + struct timespec start_ts, end_ts; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); + do { + bool last_line_changed; + bool first_line_changed; + + read_boundary_lines(maps_fd, page1, page2, &new_last_line, &new_first_line); + + /* Check if we read vmas after split */ + if (!strcmp(new_last_line.text, split_last_line.text)) { + /* + * The vmas should be consistent with split results, + * however if vma was concurrently restored after a + * split, it can be reported twice (first the original + * split one, then the same vma but extended after the + * merge) because we found it as the next vma again. + * In that case new first line will be the same as the + * last restored line. + */ + assert(!strcmp(new_first_line.text, split_first_line.text) || + !strcmp(new_first_line.text, restored_last_line.text)); + } else { + /* The vmas should be consistent with merge results */ + assert(!strcmp(new_last_line.text, restored_last_line.text) && + !strcmp(new_first_line.text, restored_first_line.text)); + } + /* + * First and last lines should change in unison. If the last + * line changed then the first line should change as well and + * vice versa. + */ + last_line_changed = strcmp(new_last_line.text, last_line->text) != 0; + first_line_changed = strcmp(new_first_line.text, first_line->text) != 0; + assert(last_line_changed == first_line_changed); + + clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); + } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); + + /* Signal the modifyer thread to stop and wait until it exits */ + signal_state(mod_info, TEST_DONE); +} + +static int test_maps_tearing(void) +{ + struct vma_modifier_info *mod_info; + pthread_mutexattr_t mutex_attr; + pthread_condattr_t cond_attr; + int shared_mem_size; + char fname[32]; + int vma_count; + int maps_fd; + int status; + pid_t pid; + + /* + * Have to map enough vmas for /proc/pid/maps to containt more than one + * page worth of vmas. Assume at least 32 bytes per line in maps output + */ + vma_count = page_size / 32 + 1; + shared_mem_size = sizeof(struct vma_modifier_info) + vma_count * sizeof(void *); + + /* map shared memory for communication with the child process */ + mod_info = (struct vma_modifier_info *)mmap(NULL, shared_mem_size, + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); + + assert(mod_info != MAP_FAILED); + + /* Initialize shared members */ + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); + assert(!pthread_mutex_init(&mod_info->sync_lock, &mutex_attr)); + pthread_condattr_init(&cond_attr); + pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); + assert(!pthread_cond_init(&mod_info->sync_cond, &cond_attr)); + mod_info->vma_count = vma_count; + mod_info->curr_state = INIT; + mod_info->exit = false; + + pid = fork(); + if (!pid) { + /* Child process */ + child_vma_modifier(mod_info); + return 0; + } + + sprintf(fname, "/proc/%d/maps", pid); + maps_fd = open(fname, O_RDONLY); + assert(maps_fd != -1); + + /* Wait for the child to map the VMAs */ + wait_for_state(mod_info, CHILD_READY); + + /* Read first two pages */ + struct page_content page1; + struct page_content page2; + + page1.data = malloc(page_size); + assert(page1.data); + page2.data = malloc(page_size); + assert(page2.data); + + struct line_content last_line; + struct line_content first_line; + + read_boundary_lines(maps_fd, &page1, &page2, &last_line, &first_line); + + /* + * Find the addresses corresponding to the last line in the first page + * and the first line in the last page. + */ + mod_info->addr = NULL; + mod_info->next_addr = NULL; + for (int i = 0; i < mod_info->vma_count; i++) { + if (mod_info->child_mapped_addr[i] == (void *)last_line.start_addr) { + mod_info->addr = mod_info->child_mapped_addr[i]; + mod_info->prot = PROT_READ; + /* Even VMAs have write permission */ + if ((i % 2) == 0) + mod_info->prot |= PROT_WRITE; + } else if (mod_info->child_mapped_addr[i] == (void *)first_line.start_addr) { + mod_info->next_addr = mod_info->child_mapped_addr[i]; + } + + if (mod_info->addr && mod_info->next_addr) + break; + } + assert(mod_info->addr && mod_info->next_addr); + + signal_state(mod_info, PARENT_READY); + + test_maps_tearing_from_split(maps_fd, mod_info, &page1, &page2, + &last_line, &first_line); + + stop_vma_modifier(mod_info); + + free(page2.data); + free(page1.data); + + for (int i = 0; i < vma_count; i++) + munmap(mod_info->child_mapped_addr[i], page_size); + close(maps_fd); + waitpid(pid, &status, 0); + munmap(mod_info, shared_mem_size); + + return 0; +} + +int usage(void) +{ + fprintf(stderr, "Userland /proc/pid/{s}maps test cases\n"); + fprintf(stderr, " -d: Duration for time-consuming tests\n"); + fprintf(stderr, " -h: Help screen\n"); + exit(-1); +} + +int main(int argc, char **argv) { int pipefd[2]; int exec_fd; + int opt; + + while ((opt = getopt(argc, argv, "d:h")) != -1) { + if (opt == 'd') + test_duration_sec = strtoul(optarg, NULL, 0); + else if (opt == 'h') + usage(); + } + page_size = sysconf(_SC_PAGESIZE); vsyscall(); switch (g_vsyscall) { case 0: @@ -578,6 +1002,10 @@ int main(void) assert(err == -ENOENT); } + /* Test tearing in /proc/$PID/maps */ + if (test_maps_tearing()) + return 1; + return 0; } #else From patchwork Fri Apr 18 17:49:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057556 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 264FCC369AB for ; Fri, 18 Apr 2025 17:50:12 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CE8A76B02A5; Fri, 18 Apr 2025 13:50:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C6DC16B02A7; Fri, 18 Apr 2025 13:50:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AC4BD6B02A9; Fri, 18 Apr 2025 13:50:09 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 88CEE6B02A5 for ; Fri, 18 Apr 2025 13:50:09 -0400 (EDT) Received: from smtpin14.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 9E72480A99 for ; Fri, 18 Apr 2025 17:50:10 +0000 (UTC) X-FDA: 83347903380.14.24C4FCA Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) by imf09.hostedemail.com (Postfix) with ESMTP id 08C3F14000D for ; Fri, 18 Apr 2025 17:50:08 +0000 (UTC) Authentication-Results: imf09.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=qz8c2cQY; spf=pass (imf09.hostedemail.com: domain of 3z5ACaAYKCEIwyvirfksskpi.gsqpmry1-qqozego.svk@flex--surenb.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3z5ACaAYKCEIwyvirfksskpi.gsqpmry1-qqozego.svk@flex--surenb.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998609; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=NX95Q4Cv9wzSD/gXCZRQ7iUBrYCRAWvVBL1zZlzjT0w=; b=4vgGlJyT51K2FddG2eL5BRecABQPr1RlLaHue4/ghxH1/CkGSUpevSI8Y1GiaGToxp/Q7n Ej14p2XtLqJZ4e8CDz7yYgfnJ7YQsvBvr4paQOXzllEDmllvu1hy3cw9WIMc5kSsaxdtT4 8J7kOdcvct5KQMfe5G6y7MkjMWfMoFU= ARC-Authentication-Results: i=1; imf09.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=qz8c2cQY; spf=pass (imf09.hostedemail.com: domain of 3z5ACaAYKCEIwyvirfksskpi.gsqpmry1-qqozego.svk@flex--surenb.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3z5ACaAYKCEIwyvirfksskpi.gsqpmry1-qqozego.svk@flex--surenb.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998609; a=rsa-sha256; cv=none; b=uGutA3PsP+hd6vgB0VNz/x2hdkGxZY5NcVlT1E0JnWjD3JY4TX4I3XycGDXoMd5jAIZV65 BELjD0TTc/GkwV4z+4NiCZo6c+WrA58ZubnQdFzft2jRqP+/B5ytylRkafQ9Ut2Uq0xd1a edV5p/ofVtEE16yu6pBkMI1tHrlfE5A= Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-2ff7cf599beso1966355a91.0 for ; Fri, 18 Apr 2025 10:50:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998608; x=1745603408; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=NX95Q4Cv9wzSD/gXCZRQ7iUBrYCRAWvVBL1zZlzjT0w=; b=qz8c2cQYKyeUaCmOaXhxRZD2/3Rrlz9jVRpsV2JOkV++BW3BKmoyLYiAz30N/04s67 ZI8dtGpuAqJd+8m8QnD5hx5sxp+ueiCkaYQBWzCk9Pta0GZSMgmF+X2F8WtQrdy0f9l2 O/RIvgPJt4gkiRg8/3hKukHL8bevB+Y6WB5E0IYucRvsWWDydNFkmNspjPrfTrmSkoWU sFqhY/vni2Zt7M9PyP5W4V3DiA6yn+8dETwaiBC3aPhlceOW+LXL6kOj52wKQxPKje++ vhbDVUGE1HgVaIOH6YVQNZhMffCi7/ALCSiOpJe0+MtDJTOiLmwS6c0VYctmF/lqY+JD k9xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998608; x=1745603408; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NX95Q4Cv9wzSD/gXCZRQ7iUBrYCRAWvVBL1zZlzjT0w=; b=llXExG+OJDyC4d1fO0GUM0oreJkxh0wBginO3Um8hoInBDpVI/t3A+lka+41Lmle/d q/Z7q+5YsbsBOhAaaeMhWw3In1zNRlxu0WJcJ584xnuAXXltGaRnArEdXuVrZ2prb6O3 6ZAomkg3nTGkDFnGMMUOYCCDfL0JYuM3EBl2WG2CFjHSssts6eYmOT0KJbjyg+Bj93e0 UczSqSolDFGOgLhaxb2FSSxmcWnYLIHmYatXj2Sv7IHC+ZYZ+U6KrDHZYP2bhlmJz5iy uSyVNtLbIbfsFx6U8t35j0ouwY6e62H7I2EXSR6ELAa9ftbLfP8QsO13irZ4xxI65d5h 2o6w== X-Forwarded-Encrypted: i=1; AJvYcCWSBmAOZz8h4soe8T9Z7RSKnG+qJ+viwqdIkSVEOBmg3zIDhF4yv+UVJ6Eh++5QWy2i5THZDc3cwA==@kvack.org X-Gm-Message-State: AOJu0YxBdDYcazPheK3it7Ny4Kre9M3CDu1hiCFxi9hfLkbf4ATZHqYu MiRbMW0OHu9wAiCqjH/E8NNqstU6y3GaAxZ8ce+KN9a55zrbzXeFQ9TNssPItTILPRLCqQpMsbl zTg== X-Google-Smtp-Source: AGHT+IFpXjxxv3q6WygkdxKZ0NcMoXnZ0n+s0fsiF2xjhvVMd0DnZR58HYYN8GWJayn2FJMme4MlbLuDSV4= X-Received: from pjyp13.prod.google.com ([2002:a17:90a:e70d:b0:2fc:2ee0:d38a]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:5404:b0:305:2d68:8d39 with SMTP id 98e67ed59e1d1-3087bb571a2mr6196148a91.12.1744998607909; Fri, 18 Apr 2025 10:50:07 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:53 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-3-surenb@google.com> Subject: [PATCH v3 2/8] selftests/proc: extend /proc/pid/maps tearing test to include vma resizing From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Stat-Signature: 97ceisfyuij8jqbgjyscgp666ap7jq35 X-Rspamd-Server: rspam01 X-Rspamd-Queue-Id: 08C3F14000D X-Rspam-User: X-HE-Tag: 1744998608-872686 X-HE-Meta: U2FsdGVkX1+gVZqhdPkFf2+guwV1t91bNz1L6QdBj3enB1+BeCz59WfKCO5vL4YcOt0Bu3CZyZ/w7ljfNEP5yyyIRbQNu+qLFLkxO4v2xjHWu51+qTRjNJnBScU50OR66YDig3QNsfbFM3dwVRdJgfVqg4f1HsjYBzJG62NY6S4ax1mSfl+O0GleX8Re3+1YhAzLx/lM8bMqFvLZD7uJWQ8tpwZZWKlbzZN82eIf5nRYZXCj9Gf/obqaG9KiqdXRTrwdIlTPyP5glaPPlhM3zA0lnHXp+F5kHx0lzz3n8GdTpeBBZmLI0pSehO/hy9MsdIPHthPg2v6/a9KMLuHaQw9imfNFFwOUqmzV0JYvVa5DGOr6/cGVPhCletwa/J33o6P2n6qgH+/OsOLW0K7zQ+R90wXlyF48SFCNqedCd0WtBfySLRNj0aZq+NYOBMqyXJ758KnyiX1jc6oIaaopp6ntA5Plkfpnay8e0KwFV+eB67C+pSnDnem2KS9WO/mBrpJCDpLD7QANOpLve9drtRfMDz+a2+KKvhPukAwVEgzSmp8JAKBRsdCzL/lsxN/mtSRES15AG1CKoyxdRjQKsWD6J484K31qnJ+Y0dVxAD95E0QH/GMHkp9y4D8rBZwLBAHX76vvEB6SOZ69K7BYBCoROIUluzc7iyss3LC/MWCctzkeu9mpaeAE2NQqPDNQWzyvETRUi8Trk/1fa9UzC+brrKwpmYk+eK+kiakdqS8JxYRtOwENaFF3EV4TxZu6H1tREiZxl8FfN2nNgOFrm9fa1EXvWU2wNnARWKN7pw//HdlUclTyVIkLRRghzl1AB2hwYXpF7mcJ8aUDsL4AWNkZlqFHCU+Zww05AFni6DnEf+QMXmAMxKUvGzCdDOIGKQa6FAx1Ogz7MD6i1tVAki1dy/a3DwxxDVvTM1ci6GDPRsLostp8KfDeEcBPi17CiRCupZWvfU6GzjNCwFA Xho3R51C iMll/X4b+Yf3TraS3+C7I1r3/bxIx+wIS38ApNH3E61H+zN4vEfCVEyFIvPJuZfQ05J0lH5vQmaUinFpWhPFjuNOghfKuQZIVvnFYB+bPNBZapqY2WvYjf8rkRXXGyOV9T02wb2hAZCeYGNe36h3D07hYgcqur0x4SIPMeHbTi4dc9qI3nuBmt6MMUsgbM3I/UA79wH834wGHEr6QgurZ+lYAOeW6Jo0WDa5HcgRzIcRrMvDeaqU2AjYghQ916Gzeszy4 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000001, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Test that /proc/pid/maps does not report unexpected holes in the address space when a vma at the edge of the page is being concurrently remapped. This remapping results in the vma shrinking and expanding from under the reader. We should always see either shrunk or expanded (original) version of the vma. Signed-off-by: Suren Baghdasaryan --- tools/testing/selftests/proc/proc-pid-vm.c | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index 6e3f06376a1f..39842e4ec45f 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c @@ -583,6 +583,86 @@ static void test_maps_tearing_from_split(int maps_fd, signal_state(mod_info, TEST_DONE); } +static inline void shrink_vma(const struct vma_modifier_info *mod_info) +{ + assert(mremap(mod_info->addr, page_size * 3, page_size, 0) != MAP_FAILED); +} + +static inline void expand_vma(const struct vma_modifier_info *mod_info) +{ + assert(mremap(mod_info->addr, page_size, page_size * 3, 0) != MAP_FAILED); +} + +static inline void check_shrink_result(struct line_content *mod_last_line, + struct line_content *mod_first_line, + struct line_content *restored_last_line, + struct line_content *restored_first_line) +{ + /* Make sure only the last vma of the first page is changing */ + assert(strcmp(mod_last_line->text, restored_last_line->text) != 0); + assert(strcmp(mod_first_line->text, restored_first_line->text) == 0); +} + +static void test_maps_tearing_from_resize(int maps_fd, + struct vma_modifier_info *mod_info, + struct page_content *page1, + struct page_content *page2, + struct line_content *last_line, + struct line_content *first_line) +{ + struct line_content shrunk_last_line; + struct line_content shrunk_first_line; + struct line_content restored_last_line; + struct line_content restored_first_line; + + wait_for_state(mod_info, SETUP_READY); + + /* re-read the file to avoid using stale data from previous test */ + read_boundary_lines(maps_fd, page1, page2, last_line, first_line); + + mod_info->vma_modify = shrink_vma; + mod_info->vma_restore = expand_vma; + mod_info->vma_mod_check = check_shrink_result; + + capture_mod_pattern(maps_fd, mod_info, page1, page2, last_line, first_line, + &shrunk_last_line, &shrunk_first_line, + &restored_last_line, &restored_first_line); + + /* Now start concurrent modifications for test_duration_sec */ + signal_state(mod_info, TEST_READY); + + struct line_content new_last_line; + struct line_content new_first_line; + struct timespec start_ts, end_ts; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); + do { + read_boundary_lines(maps_fd, page1, page2, &new_last_line, &new_first_line); + + /* Check if we read vmas after shrinking it */ + if (!strcmp(new_last_line.text, shrunk_last_line.text)) { + /* + * The vmas should be consistent with shrunk results, + * however if the vma was concurrently restored, it + * can be reported twice (first as shrunk one, then + * as restored one) because we found it as the next vma + * again. In that case new first line will be the same + * as the last restored line. + */ + assert(!strcmp(new_first_line.text, shrunk_first_line.text) || + !strcmp(new_first_line.text, restored_last_line.text)); + } else { + /* The vmas should be consistent with the original/resored state */ + assert(!strcmp(new_last_line.text, restored_last_line.text) && + !strcmp(new_first_line.text, restored_first_line.text)); + } + clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); + } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); + + /* Signal the modifyer thread to stop and wait until it exits */ + signal_state(mod_info, TEST_DONE); +} + static int test_maps_tearing(void) { struct vma_modifier_info *mod_info; @@ -674,6 +754,9 @@ static int test_maps_tearing(void) test_maps_tearing_from_split(maps_fd, mod_info, &page1, &page2, &last_line, &first_line); + test_maps_tearing_from_resize(maps_fd, mod_info, &page1, &page2, + &last_line, &first_line); + stop_vma_modifier(mod_info); free(page2.data); From patchwork Fri Apr 18 17:49:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057557 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 E7141C369CA for ; Fri, 18 Apr 2025 17:50:14 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E4B806B02AA; Fri, 18 Apr 2025 13:50:11 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id DB1D26B02A9; Fri, 18 Apr 2025 13:50:11 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B8B146B02AA; Fri, 18 Apr 2025 13:50:11 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 866C86B02A7 for ; Fri, 18 Apr 2025 13:50:11 -0400 (EDT) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id D650F1C929C for ; Fri, 18 Apr 2025 17:50:12 +0000 (UTC) X-FDA: 83347903464.16.3BCE83F Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) by imf08.hostedemail.com (Postfix) with ESMTP id 09B6A16000B for ; Fri, 18 Apr 2025 17:50:10 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=1ixFDRbb; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of 30ZACaAYKCEQy0xkthmuumrk.iusrot03-ssq1giq.uxm@flex--surenb.bounces.google.com designates 209.85.216.73 as permitted sender) smtp.mailfrom=30ZACaAYKCEQy0xkthmuumrk.iusrot03-ssq1giq.uxm@flex--surenb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998611; a=rsa-sha256; cv=none; b=ExUjbbS507on+J0YlFom5/OZlTUwlCImzQWOPIcqaFjc5uV1/n1pJ7is/qUHGWMd0HIPnJ /oadKNAFpbNVGbnZaslyRJCo/D73uvsl+uiYUCXr9RhIlIXKwbzfQJh56tCrXD6hIs247D xvGimCt1HugjgyKjb6/ALnHO8PFeM2U= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=1ixFDRbb; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of 30ZACaAYKCEQy0xkthmuumrk.iusrot03-ssq1giq.uxm@flex--surenb.bounces.google.com designates 209.85.216.73 as permitted sender) smtp.mailfrom=30ZACaAYKCEQy0xkthmuumrk.iusrot03-ssq1giq.uxm@flex--surenb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998611; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=9QDrVpMHVQI58rYUIwLQJvrC+l7tIXNhALhARIzYV3A=; b=N8UN8wBFewGTJqRk0f7rx26TUYjs0w5hZ7rrg03ScSvAU7wknB6Werdbn5WA867Y3jddv1 iGP6oNHcmWNnqh2Q7no0Le8zGRZNqtH7nBUXa9qz9V7abVO9e2QWb0uDpgmnRyaJfoEmvE Lll6C4XEeHbhSJdb6lTT4ljp4kBZbGM= Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-30872785c3cso2566588a91.1 for ; Fri, 18 Apr 2025 10:50:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998610; x=1745603410; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=9QDrVpMHVQI58rYUIwLQJvrC+l7tIXNhALhARIzYV3A=; b=1ixFDRbbR1sCFwV6p4RncQS01UuTevHqnd7D+Mp0YDwiDDPquLnHs9JZM3m7/EtJxF +50UykzfnZ7VPmI1XK6tjISF8263dSZnvTCcFg/Xjdi+tQ3BnS3NdD2juTwpy3H5+Wh4 aKZJFof7cuQibQtXmmFZrICnZe0b2opk+iKMksTJfPZqiqkLdRqnc5uqKSW52h5ZrtlB FhAnev8eIiAgC2johFchpH1qxp+S9w0aDtuBnN0BYZNin4UYplvwAhosH/ajEzo7RaVE dgQ7cbKN/7YRWPFu+Na71QEq5BG41dou0wpFPyQVy71wHbzB9ReCXV4QFSXMF54TLxI9 G5eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998610; x=1745603410; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9QDrVpMHVQI58rYUIwLQJvrC+l7tIXNhALhARIzYV3A=; b=Y6JWaOqutBDqm4tLV5SdbNbOAP7W8hVRi3jrsb+AcHjDSXoQ6jtCUojRsSxMcV3ihW NUk7iFT82RmFiqn33DfRHeZ9QmJKCPUULezVhPHKsu+1HY6B1WeI9nS5moh4wt0+46QY mwhtphE0kAGNHRR+hlwHalz1jCGYG985xOx58Tu4MDrAVI4xPIuUotC6aij0xgy3eKQT 3aEkz+upKhfFpUPjeyEQThi7Fj1Wsve8BsDGjI6k7sRusJH8UYNFPI9OXIZLb/23RjCR RuhBE1J1wqbAPUvFSnXPbfx8LoM7u67a2nZddGMnLS7aFBcwexdB3gh8BkoUNhwOfMD1 8RxA== X-Forwarded-Encrypted: i=1; AJvYcCUaKl3RUOMGp1gcp8H9KIguSqG9wLKFSMiI2oezRVa7K9XcW33N429Jfm9ulaXRfzaGlMbRSvgL2Q==@kvack.org X-Gm-Message-State: AOJu0YwLVDrTfZqF5bALTYBEBv5E/7I8HaVycQE5UIyCZDX8NCWDdN/r jlKHYhS3r3Y+SeI4SfNl0NTk9AqUE9myWL/7xWp5Zlyz102paKCOCJXbggb+mlHmpm8D4QhWwFy JPA== X-Google-Smtp-Source: AGHT+IE7iTtCIpLL5pKA5lwf7kKMbjD35Kmet76OppQlPi+RQQiOVcZRsAZLaU2DHrZErhMdfWGzeuof8yo= X-Received: from pjqq6.prod.google.com ([2002:a17:90b:5846:b0:2fc:3022:36b8]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4ed0:b0:2fe:8c22:48b0 with SMTP id 98e67ed59e1d1-3087bb6d159mr5887502a91.15.1744998609934; Fri, 18 Apr 2025 10:50:09 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:54 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-4-surenb@google.com> Subject: [PATCH v3 3/8] selftests/proc: extend /proc/pid/maps tearing test to include vma remapping From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Rspamd-Queue-Id: 09B6A16000B X-Stat-Signature: 8tahsjgar747zx78e4pxfkinwxck1wky X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1744998610-280203 X-HE-Meta: U2FsdGVkX1/JJ4kw9dARTpeUVZOzQV05UZuiccnEOAV6fy8jPLJcJ2y4g2AG6A9lA6cm7opwGLIpzfo2FXCjQRDZLYITZ/KZrF51R+jsv9buuLgcoJIh6YJLsdI9abR4ps5G2z8jgSrADseBCBye6KJS/wFQoEvtWRIIPcRh1AwJYObFg9fr5uhkB4QaXSO+w2J5owIa0yobPGwkEXtiPjAMya7KtPAyRQTEFZ6Lg+ITDk9J/bbDuFnfrbiwwSzHtIEnu8zsgSjEBC+g3ErPm+/ogwO5sNpy6QOAIAlUHo32QJEG4575HzJ8llTn9PGJsKrwsSlbN+LKGydOfyaixUX2Rqdm/eagzbC6S7HAex85CRBWuRg3NUlFeM0cF8/1O4ZDNt8xF5rrcnEsUrAC3BBQX8cMfhKM5+sqNzHx3MaSWmB851KAz/+Hy+VuHB0Ub7EVAVIRueTjd8MjGOk8plx8ii3Ibrubkzz1hE4im5RSxuu7bgiUIWByUOHOPCFoQn5qySuP1KwKIMI59Crv7geGDQ/nyAE0nPgpZDX5BbzghlmBNk7bmX3ozWlbadgDwbA1Zls8/fTD30VuB09gzTWAt24G7W/BwS4Oz1jrzrrmdetR2UkGa8Q0RyslpjiQb7lv2GhhYW6XPUSQlBUrM2820NAdQ72CBO+USn3VVZiv6qpPYvPo+0+4lG84YQ3F97t7jEKjZ2ew98fn/ncboblnXjUytV9diI51pfRGme9+6HXzZOvERoNBtu3pMkU2AePALp/ror8D22QxG/6qFGr5N8l0ZqyL7IB1VB5CK1fMz8PM3tGq98wD+w447pArVWQkae5qhBaKhx+Lm8VnH07mSHzZ01RgiD/vB5ALDPqVRwskWBLDquFVGGrd3QELeUgb2BTiqsSzrYdd4Sobj0aCwhxQ0G3tScXnzBsOiTERXOd1JyiJzLyFto3Yd+/Ay2/0NkXA5z7jY71gf7d v1zASnmx GTnY0r2FWaZA4qFo7+WBE6op/h8QixEKf1ncFm8RPDSZUV1BUTVQVliHFqtMT0TIsyFfW514sOxFsd/Qk7EkpaZNBKAF27lTJ7OaHTbOJ+dEGC4AAimae8KiQ3Gc2TRUzlQTIfBjLUGigTM3tw2OhGG2fThGTpqPG77q5399U8ahsxBYhAfHamFaUAA6bJf8KMyRZoH37PMse7Fg+/55da2zr495hJRKXx7tZhJLpHsIld3CBU+lYydUH7SDX46klO71Nz6U4LecFx/dQNE/K3Y1KBtjzScjCN22RzQmK34ZORChBVLACgaTXJPhcMubeHlaDvnnReGwezJzrkTyyIsgjWyxlcFgmOKV1D8i52yUhkmtUP0RsKIozzmwM9CizevfjH7Zd6C0e4G2O23aYpfaDpufOOSVSlzGotecQ/+SWoLX0R4NvIX3J7E1O3rrQx5InEGerxKoweln6XoxqH+VZJqh1ZB6/lLiMfvuQEShZfvxZvuPUEedmQvz4PYLpF94AlYkJzj92g/A1yRwwfZfgf8OG/icPuWCPdRKKraoHM3U= 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: Test that /proc/pid/maps does not report unexpected holes in the address space when we concurrently remap a part of a vma into the middle of another vma. This remapping results in the destination vma being split into three parts and the part in the middle being patched back from, all done concurrently from under the reader. We should always see either original vma or the split one with no holes. Signed-off-by: Suren Baghdasaryan --- tools/testing/selftests/proc/proc-pid-vm.c | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index 39842e4ec45f..1aef2db7e893 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c @@ -663,6 +663,95 @@ static void test_maps_tearing_from_resize(int maps_fd, signal_state(mod_info, TEST_DONE); } +static inline void remap_vma(const struct vma_modifier_info *mod_info) +{ + /* + * Remap the last page of the next vma into the middle of the vma. + * This splits the current vma and the first and middle parts (the + * parts at lower addresses) become the last vma objserved in the + * first page and the first vma observed in the last page. + */ + assert(mremap(mod_info->next_addr + page_size * 2, page_size, + page_size, MREMAP_FIXED | MREMAP_MAYMOVE | MREMAP_DONTUNMAP, + mod_info->addr + page_size) != MAP_FAILED); +} + +static inline void patch_vma(const struct vma_modifier_info *mod_info) +{ + assert(!mprotect(mod_info->addr + page_size, page_size, + mod_info->prot)); +} + +static inline void check_remap_result(struct line_content *mod_last_line, + struct line_content *mod_first_line, + struct line_content *restored_last_line, + struct line_content *restored_first_line) +{ + /* Make sure vmas at the boundaries are changing */ + assert(strcmp(mod_last_line->text, restored_last_line->text) != 0); + assert(strcmp(mod_first_line->text, restored_first_line->text) != 0); +} + +static void test_maps_tearing_from_remap(int maps_fd, + struct vma_modifier_info *mod_info, + struct page_content *page1, + struct page_content *page2, + struct line_content *last_line, + struct line_content *first_line) +{ + struct line_content remapped_last_line; + struct line_content remapped_first_line; + struct line_content restored_last_line; + struct line_content restored_first_line; + + wait_for_state(mod_info, SETUP_READY); + + /* re-read the file to avoid using stale data from previous test */ + read_boundary_lines(maps_fd, page1, page2, last_line, first_line); + + mod_info->vma_modify = remap_vma; + mod_info->vma_restore = patch_vma; + mod_info->vma_mod_check = check_remap_result; + + capture_mod_pattern(maps_fd, mod_info, page1, page2, last_line, first_line, + &remapped_last_line, &remapped_first_line, + &restored_last_line, &restored_first_line); + + /* Now start concurrent modifications for test_duration_sec */ + signal_state(mod_info, TEST_READY); + + struct line_content new_last_line; + struct line_content new_first_line; + struct timespec start_ts, end_ts; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); + do { + read_boundary_lines(maps_fd, page1, page2, &new_last_line, &new_first_line); + + /* Check if we read vmas after remapping it */ + if (!strcmp(new_last_line.text, remapped_last_line.text)) { + /* + * The vmas should be consistent with remap results, + * however if the vma was concurrently restored, it + * can be reported twice (first as split one, then + * as restored one) because we found it as the next vma + * again. In that case new first line will be the same + * as the last restored line. + */ + assert(!strcmp(new_first_line.text, remapped_first_line.text) || + !strcmp(new_first_line.text, restored_last_line.text)); + } else { + /* The vmas should be consistent with the original/resored state */ + assert(!strcmp(new_last_line.text, restored_last_line.text) && + !strcmp(new_first_line.text, restored_first_line.text)); + } + clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); + } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); + + /* Signal the modifyer thread to stop and wait until it exits */ + signal_state(mod_info, TEST_DONE); +} + static int test_maps_tearing(void) { struct vma_modifier_info *mod_info; @@ -757,6 +846,9 @@ static int test_maps_tearing(void) test_maps_tearing_from_resize(maps_fd, mod_info, &page1, &page2, &last_line, &first_line); + test_maps_tearing_from_remap(maps_fd, mod_info, &page1, &page2, + &last_line, &first_line); + stop_vma_modifier(mod_info); free(page2.data); From patchwork Fri Apr 18 17:49:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057558 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 7CA7CC369CF for ; Fri, 18 Apr 2025 17:50:17 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 220DB6B02A9; Fri, 18 Apr 2025 13:50:14 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1B6226B02AC; Fri, 18 Apr 2025 13:50:14 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id F392C6B02AD; Fri, 18 Apr 2025 13:50:13 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id D25996B02A9 for ; Fri, 18 Apr 2025 13:50:13 -0400 (EDT) Received: from smtpin23.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 103C6C0AE5 for ; Fri, 18 Apr 2025 17:50:15 +0000 (UTC) X-FDA: 83347903590.23.830A76F Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) by imf06.hostedemail.com (Postfix) with ESMTP id 3C8C6180007 for ; Fri, 18 Apr 2025 17:50:13 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=zIcryJl8; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf06.hostedemail.com: domain of 31JACaAYKCEc130nwkpxxpun.lxvurw36-vvt4jlt.x0p@flex--surenb.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=31JACaAYKCEc130nwkpxxpun.lxvurw36-vvt4jlt.x0p@flex--surenb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998613; a=rsa-sha256; cv=none; b=3TkAmooGB7xTExu+twsHDp52Ssfq1wjDG3UahEyhTvgLIstIpjh3jsnAK0dRMAhhLN6Eoe 9bsWeWGDIEx062Ad061UPUuRVhebc+i2jvll5AncI1zetGOwuZITzlC5Hq7Fiw8Nx3hifS lxrJ2XSpSOmlkelE1+ftbo30UJkeYN8= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=zIcryJl8; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf06.hostedemail.com: domain of 31JACaAYKCEc130nwkpxxpun.lxvurw36-vvt4jlt.x0p@flex--surenb.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=31JACaAYKCEc130nwkpxxpun.lxvurw36-vvt4jlt.x0p@flex--surenb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998613; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=HUB6q+v0EpFzFu3PlHq45yNrya7EC7jKKGmhERTYTZQ=; b=2Qz3kT0CxSMYDizGK8seKzD8Fvay6d7gXnyWVP6CYEHkofVQLrMWDhm9d+kA9yZq37YtAU xyrW9XBZOzGUJKs5A6Vl0IgZvwSRfKm8wYJp/wQLlVHuh3QkQd2uF7Aj+KJPhjxicUeav0 O3ZrLL+eVsPGcwu8layy8SJ3G+n8HA0= Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-af5a8c67707so1320037a12.1 for ; Fri, 18 Apr 2025 10:50:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998612; x=1745603412; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=HUB6q+v0EpFzFu3PlHq45yNrya7EC7jKKGmhERTYTZQ=; b=zIcryJl8PS5jrBMTYk7L/V2XauxDTUcXhyCd9cKXMVHdEiNqzsD1CSVcpHOSbuMav8 /l5Qz1c9XUfRDUwJy9ls2CRWvc7OHUFigNwO0YV1v45e/iWtlc5s9/40hjS6DVE0ml3P sOzgUPsS2E+MwBwSdi3om1DWnfzPDJ3JSPdAf95OhZsUPne3J8ezYm7CUqzAjE7mBZp2 bBIdeKCnyLwSo/sLwAoNq4HUWTfANs4w/3+sNRU9jGMyT2sbr5goJ+ngDF/rMAbHkOk+ Fi5GpCTss2dBWx5dyCHBUzhI78wB+iGJIBJfIqkfxqKJxgAErrBWpXbICJFv6wVOn+Ax OxnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998612; x=1745603412; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HUB6q+v0EpFzFu3PlHq45yNrya7EC7jKKGmhERTYTZQ=; b=o538zsvZyill0MGQNTEI7xJP2F5SBq4FJSQJVRvyYjmcLSEV3BUvjey1h2akZRxNFa PdtuebFeIZKhTHc2MfSiRmMsO6RGhFm389hYPQwlTlIgkozU7sy65TTj2EPaFSh/i94o IdzoGmoWn8MXuy0BuA7znoZk0l32ZLg+kn2U9L+Et1HeFbUvg2V3QCLzbcgwtHve+HwQ TBTmSw9qXzqiur+yup+hmfOr2MtUWbtJL58tLN6MdKCbFbODXjIFB4NRnUYv2sx/wSHD wkzcHsXF80dSJ36E8OYNKiSomIMPsJx8h7tRdpSzi/ACYh2WoXyYZ0i/IVpSD1EtobFK pROg== X-Forwarded-Encrypted: i=1; AJvYcCWmwU/BgPp2VycCFw/vOXO0iGlnFVkyuxBA0feB8kIfjuwWcO2qSEoN55gm/zXnp8SVaS9UGRC7yw==@kvack.org X-Gm-Message-State: AOJu0Yy8wUoBH08gAjovZEqPb/1jPucK4ZQLbqFqj2Nnq3HJPyO5fdNT QjZQskbmIz+8/9q4xbNV9LOhGf5LtufHzhdHGf2JSpfi2SpsIQ493KfqoYVeCZaQGPLScUcC4VS CdA== X-Google-Smtp-Source: AGHT+IGyaQr+2pZMSmPsh5wX1RoiROvtwBkd0HseqzqLOxOjXALv+e2mSSAlluxAbqqn3sMiDcQhj5J0Y/Q= X-Received: from pjbqx7.prod.google.com ([2002:a17:90b:3e47:b0:301:2679:9aa]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2809:b0:301:1c29:a1d9 with SMTP id 98e67ed59e1d1-3087bb66b26mr5412483a91.21.1744998612089; Fri, 18 Apr 2025 10:50:12 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:55 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-5-surenb@google.com> Subject: [PATCH v3 4/8] selftests/proc: test PROCMAP_QUERY ioctl while vma is concurrently modified From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Rspamd-Queue-Id: 3C8C6180007 X-Rspam-User: X-Rspamd-Server: rspam07 X-Stat-Signature: daskoxw5mwaf15f8n5kxjtiqik8rig8y X-HE-Tag: 1744998613-522631 X-HE-Meta: U2FsdGVkX1/CbnL5d4tOY3oPDcBgJi5jBDt261vFV56TYyqKTvOl2HSEFQq+NgjSMDwergqfJKSnJx+OIghTwd8/2kbUL3O+89vqURGgIgpThjAhIJcWqbD0NcNVIEFqzq26IBUhLAEnaYPcGjHG6dLcs2doYDpDa4SstqvepoNzre2rPUQkUqTDn+nhJcJ/XD2ufiaJ6NxTZk1S7AZ8bfxdEitmyadGC9Rhdb7Bpm8XPEdqcgLlQNK9yv2TwCoo+80w8aEkgTuoMIMqTaVg8+4tye7Tl6HIiFfKCzBMWV79Uty7mcRVcIidkSnDy2Z+wkAzFkw+xCDf9m7JruZDxJ1kIiwdUoPpoiHIcSgpZuFBN4umjDarMNcwM5JUUqKpiuPi+yoI+kg1ni1qFW56vKzQxZUeK1f0kQ3i9Lld3DGjRfcCgF5FzHKNDAkRODzgglkwU1dZhX6yVfwuLnOGvc2BupiYk1wkd1gkaJsqIsrVU+EW3ERvX2bobh6MMAapSGKSugywF42AA2FH9PqHbIc45Yh44UsWVVFfiKvAcQZylDufH+WZXVEs0Vi7VB9nt41F16PZMmH3Fs2M2Y5Jz821bgqEHvZeAgIn8b93NlVAcIwO42aNreqS3qFHy3H0Av0GFOXBmJUkNy9Ba8YdslwLr0m/ycMsFW6YumKhdLhC0PZrakT6f0WVZG2OzLcZrx+QliFs4pE91JbqPDGJjmcxGcexaYArs4mOF+XYsUuwAB6/mjY3JfKyfzSfG9+h5HxnPExUVuPwR/BYYgxZd2E+nUd3oGKKiz+Gd3q8ieYwA6qcfibfVJizwGek/jdSTBzb3802mC3Rpr/gx03heOblVCAJ5i+2GarC2k/Fn0uCaNBX15xEBeel8zZwsZZt1VlVRCR7Hd77pJSq0+82iR4CEoL5e1gHdteaLubTwuSLaEE1Bi527s7LrUoluKbp91BnuF7UE12WAXxA33i J1Vscps7 0uNijRTj3ZTHdyVfkWTdqzQguddFQU5uBZxT5dRgxNnHqmm3N7fOKbVv0qUFIU9WpJwRBrwfqJAJjP5GyaKFFag+Y+ZGmT00QSOxbQgivBUYl4o9YKlZopwsM6BDPzpbLM2wDIdYDPVZY77YgUDGiMyPHF1CTS2LAz7t3U0vsoiQBFjyqBgjraz3LBpHqdb6+Jq96o2BecTOGtcZt4xEQwCjrpEJE85KqnoSsma52qfUg5TSuQprAqEZwo0MikG1Vr763BfOi17Qn3+U4gm6WCZor3DHRIAnROGAQdxTutrgDixHaxPp0mQs9y3gEBNzciWcplNr7ho+Rcd6/0Drh3Y0HfXfUnSzDyUJnriVY9+cuvp/ZaYxjLZRqZ91WgpCZcujNBxQXA9lNcX0soB6+xzxKV+OYN/JB0d+gQN03jKYxPt2mPe+caqEioH6tbNkqokf28ylPgUZaliK6Nsfa1sg3btluElSYS4ik1sz7tWQp5CWoDc50IRIjhD9ea9YPje7X+5qVYr+zrkdfrw9pEc6oo1ZcwKdXfKH3kw3xZiRxpMFzAFETR6ysuiwx9Ylz2UdwvuSn/AjUfqBcA/DRAkhT+Q== 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: Extend /proc/pid/maps tearing test to verify PROCMAP_QUERY ioctl operation correctness while the vma is being concurrently modified. Signed-off-by: Suren Baghdasaryan --- tools/testing/selftests/proc/proc-pid-vm.c | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index 1aef2db7e893..b582f40851fb 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c @@ -486,6 +486,21 @@ static void capture_mod_pattern(int maps_fd, assert(strcmp(restored_first_line->text, first_line->text) == 0); } +static void query_addr_at(int maps_fd, void *addr, + unsigned long *vma_start, unsigned long *vma_end) +{ + struct procmap_query q; + + memset(&q, 0, sizeof(q)); + q.size = sizeof(q); + /* Find the VMA at the split address */ + q.query_addr = (unsigned long long)addr; + q.query_flags = 0; + assert(!ioctl(maps_fd, PROCMAP_QUERY, &q)); + *vma_start = q.vma_start; + *vma_end = q.vma_end; +} + static inline void split_vma(const struct vma_modifier_info *mod_info) { assert(mmap(mod_info->addr, page_size, mod_info->prot | PROT_EXEC, @@ -546,6 +561,8 @@ static void test_maps_tearing_from_split(int maps_fd, do { bool last_line_changed; bool first_line_changed; + unsigned long vma_start; + unsigned long vma_end; read_boundary_lines(maps_fd, page1, page2, &new_last_line, &new_first_line); @@ -576,6 +593,19 @@ static void test_maps_tearing_from_split(int maps_fd, first_line_changed = strcmp(new_first_line.text, first_line->text) != 0; assert(last_line_changed == first_line_changed); + /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ + query_addr_at(maps_fd, mod_info->addr + page_size, + &vma_start, &vma_end); + /* + * The vma at the split address can be either the same as + * original one (if read before the split) or the same as the + * first line in the second page (if read after the split). + */ + assert((vma_start == last_line->start_addr && + vma_end == last_line->end_addr) || + (vma_start == split_first_line.start_addr && + vma_end == split_first_line.end_addr)); + clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); @@ -637,6 +667,9 @@ static void test_maps_tearing_from_resize(int maps_fd, clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); do { + unsigned long vma_start; + unsigned long vma_end; + read_boundary_lines(maps_fd, page1, page2, &new_last_line, &new_first_line); /* Check if we read vmas after shrinking it */ @@ -656,6 +689,17 @@ static void test_maps_tearing_from_resize(int maps_fd, assert(!strcmp(new_last_line.text, restored_last_line.text) && !strcmp(new_first_line.text, restored_first_line.text)); } + + /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ + query_addr_at(maps_fd, mod_info->addr, &vma_start, &vma_end); + /* + * The vma should stay at the same address and have either the + * original size of 3 pages or 1 page if read after shrinking. + */ + assert(vma_start == last_line->start_addr && + (vma_end - vma_start == page_size * 3 || + vma_end - vma_start == page_size)); + clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); @@ -726,6 +770,9 @@ static void test_maps_tearing_from_remap(int maps_fd, clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); do { + unsigned long vma_start; + unsigned long vma_end; + read_boundary_lines(maps_fd, page1, page2, &new_last_line, &new_first_line); /* Check if we read vmas after remapping it */ @@ -745,6 +792,19 @@ static void test_maps_tearing_from_remap(int maps_fd, assert(!strcmp(new_last_line.text, restored_last_line.text) && !strcmp(new_first_line.text, restored_first_line.text)); } + + /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ + query_addr_at(maps_fd, mod_info->addr + page_size, &vma_start, &vma_end); + /* + * The vma should either stay at the same address and have the + * original size of 3 pages or we should find the remapped vma + * at the remap destination address with size of 1 page. + */ + assert((vma_start == last_line->start_addr && + vma_end - vma_start == page_size * 3) || + (vma_start == last_line->start_addr + page_size && + vma_end - vma_start == page_size)); + clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); From patchwork Fri Apr 18 17:49:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057559 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 41687C369CA for ; Fri, 18 Apr 2025 17:50:20 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id DB9F96B02AD; Fri, 18 Apr 2025 13:50:15 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id D678D6B02AE; Fri, 18 Apr 2025 13:50:15 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B6DFE6B02AF; Fri, 18 Apr 2025 13:50:15 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 8F36B6B02AD for ; Fri, 18 Apr 2025 13:50:15 -0400 (EDT) Received: from smtpin10.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id F1833120AE0 for ; Fri, 18 Apr 2025 17:50:16 +0000 (UTC) X-FDA: 83347903632.10.5023D37 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) by imf25.hostedemail.com (Postfix) with ESMTP id 313D2A0010 for ; Fri, 18 Apr 2025 17:50:15 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=qp58tD6V; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf25.hostedemail.com: domain of 31pACaAYKCEk352pymrzzrwp.nzxwty58-xxv6lnv.z2r@flex--surenb.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=31pACaAYKCEk352pymrzzrwp.nzxwty58-xxv6lnv.z2r@flex--surenb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998615; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=4jqUSvj/NGRZpdVDELGH7hX9O/M0JsmqV6H5P9bViYo=; b=VlX6aePZAil92EpcaTf1G+v0bn7djJBNi9PNTYrEnJyazQZmCUny3c4x/TE3htyaQdDzrW Ecc08zQW0Iw9Pnmqsw1gGdg55D0ZLTM5vmpMHSmnC+OuIUuw4YpbCjfJnPx1PzHvss/PLW y8XPe+aIrsTgabQ87MZLi1LOAZ0kcD4= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998615; a=rsa-sha256; cv=none; b=jKs7JVZegqeJ5TTIjSMmafz+/7c/zDJ+RLGNYQr8nGY/9WWKklR/mdYF5rpzj0SqCKlTcj wa6Xf2R+B6tbjals5K6Ya8vp69GT8D/lKpXN5bpYWc7pYkex6ysKTQT4HDasxxJC7nqhB3 JyqGVcr9t1xsMxO+b++BQrGqSaves4E= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=qp58tD6V; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf25.hostedemail.com: domain of 31pACaAYKCEk352pymrzzrwp.nzxwty58-xxv6lnv.z2r@flex--surenb.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=31pACaAYKCEk352pymrzzrwp.nzxwty58-xxv6lnv.z2r@flex--surenb.bounces.google.com Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-3032ea03448so2090343a91.2 for ; Fri, 18 Apr 2025 10:50:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998614; x=1745603414; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=4jqUSvj/NGRZpdVDELGH7hX9O/M0JsmqV6H5P9bViYo=; b=qp58tD6VdNfvh1Kxxqnhn20YbNp94LvwfvJx9aFxVR8RF2FZDn1qCau7snhF6clqE/ JCIfM0i1Nxh5HW08pC3rG3+oB/FgVB5cxehatZ5aOAynHCUWFoo0Eqn8pw4KtGBkDE+T LZJ8Npuc3LsAlLHU6Sqew3PqBkvA5mtIXSIm05hgU2HtzoM+GMAYCkQ8mM8R8mGxrbBW DA7TFgh66pFP4hXRArFIA77Sdt4fDaZ23eM35jlXm5NxP6fuXBq8IuAz8TT/4wsgHq4e bZyyA4MMFq7/X+ruJBre6xsGwgbMvvUlGeqYYoXxb5jVjxiG2hWIMKXyrHEvgvwos5oC 0boQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998614; x=1745603414; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=4jqUSvj/NGRZpdVDELGH7hX9O/M0JsmqV6H5P9bViYo=; b=Rsh+Xg50VMBalQjKT+mTY98m+7z7bNvRU2OFE9mj+9zYj7zqFuWkt+WjkiKJ8/UssA bK149IK9VUAptNugrn+OPpTEF/3rzExJXS+zoF3Sghmv9NykoET0ySptUkSrkfr1zGr7 vRZSSOckGD8vrM6nWDuAzrx+n0ySGzprsOoOpbqLZCLY98Z15Axulb6rdu/dAlm3IeT3 cuMWaplQHPm1XLiZ7ik3q2eNtFiOKwIgDGhJU8xbDUB1stx+egYQyQJp3eAklXGYsx04 xUBSHhxDstzHQi4PW58h44NdbTjLEukCAHIvSl6kQ08tGEGXfR4tan0gNkQQSyGjElQS FaOA== X-Forwarded-Encrypted: i=1; AJvYcCUBLHUEyQ4qMMF28LsSL8OyKaYkLxZ4lWfXn+A3W1MmAltyV4Hcr8sk4DpXm8FEmGizfHBj653Lww==@kvack.org X-Gm-Message-State: AOJu0YzeLGi6WZFnFozCT5/zg7uoutJF+A07xGqfyAIK/jHfPtsZOv7t lcPHqSZ9f0LBNNRlwDoqr0AwW4Vt1uiqU+LVkZr+WBEBxyepDZqt1Y+wcnbjL7zOR2SECFgQx5V oaQ== X-Google-Smtp-Source: AGHT+IERCla4iFsgpWYpwI6HMOKZWs0UZbPEMYoTuXdvkIt8Z5/Vr0hH5bN0CnC5Fg33kNuXlwhByED7Sls= X-Received: from pjbpd10.prod.google.com ([2002:a17:90b:1dca:b0:2fc:c98:ea47]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3d89:b0:2f4:4500:bb4d with SMTP id 98e67ed59e1d1-3087bb6ba88mr5312595a91.20.1744998614144; Fri, 18 Apr 2025 10:50:14 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:56 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-6-surenb@google.com> Subject: [PATCH v3 5/8] selftests/proc: add verbose more for tests to facilitate debugging From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: 313D2A0010 X-Rspam-User: X-Stat-Signature: wfrmxwqkhu8mctxpcadms67ja4yfp1j3 X-HE-Tag: 1744998615-628045 X-HE-Meta: U2FsdGVkX1/IS3x6DOrERawfHV9JEYtOILn+5qp0/h/aRU1Ia8HT+hBDSKPi2VRXv4zHDyhC60osJtEvFvxq9c56h902er0LD7FCJchNIrOL2Ozi9wYACQ2nH3fcWOrFtljmf4eszIEdOeJT9Q41EfWvU+FmDwN+gi7ehZSIsiN84bJ/Z3XQ1Suy+nbZ0QMLGwYhHdDNCttTf8UAY6F/UqKU92hZOED1+H6HfaKafW8UvRzUS6HgPvVWhJ9Dc3jSo6lnYsIJGNnqsY/fCYsAlcuHlsekS8m/Ay6AdzH4YmACHF1PqtZdkwIL/3QnrYQPzPldj1AMMcwIcp470pmKta/4mJb2wvaxfbRNG4d6bU0p5EtmEjXemJ984Zvrgxod8fc9WzmqVds/XTyFcPQ3Zzk4we0OZVgh/XF7rYPnUsLEZieY9AGUK+XO0KDNp5nD5z6vxjUyQbhv7ZMWNphvQuNSUz+khcwse/VIgKQfUkRPZvkq2lWohQXQWwrgO1EK0NFtgDwD2a5rph1jY16AYwvhdZ73HUBYIrGOyQQltuso8PbHLYfidoS3PLEKajxeIILYqDR/XuQkE258EhdafyP/pUoW0sb7E5tqof32UbE0p9nua2ZQShLPBgnZ1vOeImdBCPs35tz+RAaEyCEEdO49DlaoyMhvIhFJZcOF0pO4ElNZzZgcEHWy0vX2eEGzsGEOFXRIwpZrlzvoCGFwsq0h0O5pO6p/ZOSg2UUJj1SumcZI064ZYgVjDlSvnLT+y90pCpZwOzK/NAIO9AyDg3EcGjtVGTPaVMvw2vmAp0GiJAMveAg9hkK5+tW291MoEYuOcjRuCRS5YcJPT10HJ9zpmnkt3FQAascpdTaWwOCF3s79jId0hc2sYwyXxQKHKNfJHQbYOrxamvnDURqn/lv+8w599h+e+Svp3ztaIUA7pkj9QgBTanu8WkgSdic1P1NcHxG4p6oBK/NvdzF GdSbVYWm E6t31i9S/me0cmrhNWGtswqYXCKBoYizs7JN4at0j3ZCuEsMvhFHuGFmuOMMrao4IwiU/9YUVgUJk316qzcK4tx0F9JQlfQV0cufnaL3NKDpZNKiHDgaaR99I3Lb9EvU8+eeCeMp8qS1ZGtGdjJuxCdZMuI7FASUPyN6eQc9BMm0rjn0OSWPz99ZOCAMxkISgCfngc2z02grto7KR3Xy6mV33xVY+E2GIflGkhElrSpvFBfv0RCqdv5/ep8T7SPacTVP1o3s+5Y3UsC3FtFXA80xvleyKSeMvInBPH1SwQjAUMT8C3xf2X9LOjSisdysNcNh04XL2XI51gleDE7zVVYxccdAQtnsbPIAdMo73MpL/2I+3iKQPXWIMb3/Hvr9oNzMMrM747G3yrHm7KUQuTpsVWz5EO5H51FF0Di3pPUKLjN6SUaDnIsJMVF1bJfyi6uZxf/VHBS5z2jH+ayzvSM0lA54xKWlGRbJgK+36qFD4iOXR7DP+c3AoeCJ0UOVo1rF1EjDTeRawrIQni8LJbo70C4UNcklTQZCjQyFd0tyS9D0= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000002, 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 verbose more to the proc tests to print debugging information. Usage: proc-pid-vm --verbose Signed-off-by: Suren Baghdasaryan --- tools/testing/selftests/proc/proc-pid-vm.c | 154 +++++++++++++++++++-- 1 file changed, 141 insertions(+), 13 deletions(-) diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index b582f40851fb..97017f48cd70 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c @@ -73,6 +73,7 @@ static void make_private_tmp(void) } static unsigned long test_duration_sec = 5UL; +static bool verbose; static int page_size; static pid_t pid = -1; static void ate(void) @@ -452,6 +453,99 @@ static void stop_vma_modifier(struct vma_modifier_info *mod_info) signal_state(mod_info, SETUP_MODIFY_MAPS); } +static void print_first_lines(char *text, int nr) +{ + const char *end = text; + + while (nr && (end = strchr(end, '\n')) != NULL) { + nr--; + end++; + } + + if (end) { + int offs = end - text; + + text[offs] = '\0'; + printf(text); + text[offs] = '\n'; + printf("\n"); + } else { + printf(text); + } +} + +static void print_last_lines(char *text, int nr) +{ + const char *start = text + strlen(text); + + nr++; /* to ignore the last newline */ + while (nr) { + while (start > text && *start != '\n') + start--; + nr--; + start--; + } + printf(start); +} + +static void print_boundaries(const char *title, + struct page_content *page1, + struct page_content *page2) +{ + if (!verbose) + return; + + printf("%s", title); + /* Print 3 boundary lines from each page */ + print_last_lines(page1->data, 3); + printf("-----------------page boundary-----------------\n"); + print_first_lines(page2->data, 3); +} + +static bool print_boundaries_on(bool condition, const char *title, + struct page_content *page1, + struct page_content *page2) +{ + if (verbose && condition) + print_boundaries(title, page1, page2); + + return condition; +} + +static void report_test_start(const char *name) +{ + if (verbose) + printf("==== %s ====\n", name); +} + +static struct timespec print_ts; + +static void start_test_loop(struct timespec *ts) +{ + if (verbose) + print_ts.tv_sec = ts->tv_sec; +} + +static void end_test_iteration(struct timespec *ts) +{ + if (!verbose) + return; + + /* Update every second */ + if (print_ts.tv_sec == ts->tv_sec) + return; + + printf("."); + fflush(stdout); + print_ts.tv_sec = ts->tv_sec; +} + +static void end_test_loop(void) +{ + if (verbose) + printf("\n"); +} + static void capture_mod_pattern(int maps_fd, struct vma_modifier_info *mod_info, struct page_content *page1, @@ -463,18 +557,24 @@ static void capture_mod_pattern(int maps_fd, struct line_content *restored_last_line, struct line_content *restored_first_line) { + print_boundaries("Before modification", page1, page2); + signal_state(mod_info, SETUP_MODIFY_MAPS); wait_for_state(mod_info, SETUP_MAPS_MODIFIED); /* Copy last line of the first page and first line of the last page */ read_boundary_lines(maps_fd, page1, page2, mod_last_line, mod_first_line); + print_boundaries("After modification", page1, page2); + signal_state(mod_info, SETUP_RESTORE_MAPS); wait_for_state(mod_info, SETUP_MAPS_RESTORED); /* Copy last line of the first page and first line of the last page */ read_boundary_lines(maps_fd, page1, page2, restored_last_line, restored_first_line); + print_boundaries("After restore", page1, page2); + mod_info->vma_mod_check(mod_last_line, mod_first_line, restored_last_line, restored_first_line); @@ -546,6 +646,7 @@ static void test_maps_tearing_from_split(int maps_fd, mod_info->vma_restore = merge_vma; mod_info->vma_mod_check = check_split_result; + report_test_start("Tearing from split"); capture_mod_pattern(maps_fd, mod_info, page1, page2, last_line, first_line, &split_last_line, &split_first_line, &restored_last_line, &restored_first_line); @@ -558,6 +659,7 @@ static void test_maps_tearing_from_split(int maps_fd, struct timespec start_ts, end_ts; clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); + start_test_loop(&start_ts); do { bool last_line_changed; bool first_line_changed; @@ -577,12 +679,17 @@ static void test_maps_tearing_from_split(int maps_fd, * In that case new first line will be the same as the * last restored line. */ - assert(!strcmp(new_first_line.text, split_first_line.text) || - !strcmp(new_first_line.text, restored_last_line.text)); + assert(!print_boundaries_on( + strcmp(new_first_line.text, split_first_line.text) && + strcmp(new_first_line.text, restored_last_line.text), + "Split result invalid", page1, page2)); + } else { /* The vmas should be consistent with merge results */ - assert(!strcmp(new_last_line.text, restored_last_line.text) && - !strcmp(new_first_line.text, restored_first_line.text)); + assert(!print_boundaries_on( + strcmp(new_last_line.text, restored_last_line.text) || + strcmp(new_first_line.text, restored_first_line.text), + "Merge result invalid", page1, page2)); } /* * First and last lines should change in unison. If the last @@ -607,7 +714,9 @@ static void test_maps_tearing_from_split(int maps_fd, vma_end == split_first_line.end_addr)); clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); + end_test_iteration(&end_ts); } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); + end_test_loop(); /* Signal the modifyer thread to stop and wait until it exits */ signal_state(mod_info, TEST_DONE); @@ -654,6 +763,7 @@ static void test_maps_tearing_from_resize(int maps_fd, mod_info->vma_restore = expand_vma; mod_info->vma_mod_check = check_shrink_result; + report_test_start("Tearing from resize"); capture_mod_pattern(maps_fd, mod_info, page1, page2, last_line, first_line, &shrunk_last_line, &shrunk_first_line, &restored_last_line, &restored_first_line); @@ -666,6 +776,7 @@ static void test_maps_tearing_from_resize(int maps_fd, struct timespec start_ts, end_ts; clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); + start_test_loop(&start_ts); do { unsigned long vma_start; unsigned long vma_end; @@ -682,12 +793,16 @@ static void test_maps_tearing_from_resize(int maps_fd, * again. In that case new first line will be the same * as the last restored line. */ - assert(!strcmp(new_first_line.text, shrunk_first_line.text) || - !strcmp(new_first_line.text, restored_last_line.text)); + assert(!print_boundaries_on( + strcmp(new_first_line.text, shrunk_first_line.text) && + strcmp(new_first_line.text, restored_last_line.text), + "Shrink result invalid", page1, page2)); } else { /* The vmas should be consistent with the original/resored state */ - assert(!strcmp(new_last_line.text, restored_last_line.text) && - !strcmp(new_first_line.text, restored_first_line.text)); + assert(!print_boundaries_on( + strcmp(new_last_line.text, restored_last_line.text) || + strcmp(new_first_line.text, restored_first_line.text), + "Expand result invalid", page1, page2)); } /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ @@ -701,7 +816,9 @@ static void test_maps_tearing_from_resize(int maps_fd, vma_end - vma_start == page_size)); clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); + end_test_iteration(&end_ts); } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); + end_test_loop(); /* Signal the modifyer thread to stop and wait until it exits */ signal_state(mod_info, TEST_DONE); @@ -757,6 +874,7 @@ static void test_maps_tearing_from_remap(int maps_fd, mod_info->vma_restore = patch_vma; mod_info->vma_mod_check = check_remap_result; + report_test_start("Tearing from remap"); capture_mod_pattern(maps_fd, mod_info, page1, page2, last_line, first_line, &remapped_last_line, &remapped_first_line, &restored_last_line, &restored_first_line); @@ -769,6 +887,7 @@ static void test_maps_tearing_from_remap(int maps_fd, struct timespec start_ts, end_ts; clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts); + start_test_loop(&start_ts); do { unsigned long vma_start; unsigned long vma_end; @@ -785,12 +904,16 @@ static void test_maps_tearing_from_remap(int maps_fd, * again. In that case new first line will be the same * as the last restored line. */ - assert(!strcmp(new_first_line.text, remapped_first_line.text) || - !strcmp(new_first_line.text, restored_last_line.text)); + assert(!print_boundaries_on( + strcmp(new_first_line.text, remapped_first_line.text) && + strcmp(new_first_line.text, restored_last_line.text), + "Remap result invalid", page1, page2)); } else { /* The vmas should be consistent with the original/resored state */ - assert(!strcmp(new_last_line.text, restored_last_line.text) && - !strcmp(new_first_line.text, restored_first_line.text)); + assert(!print_boundaries_on( + strcmp(new_last_line.text, restored_last_line.text) || + strcmp(new_first_line.text, restored_first_line.text), + "Remap restore result invalid", page1, page2)); } /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ @@ -806,7 +929,9 @@ static void test_maps_tearing_from_remap(int maps_fd, vma_end - vma_start == page_size)); clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); + end_test_iteration(&end_ts); } while (end_ts.tv_sec - start_ts.tv_sec < test_duration_sec); + end_test_loop(); /* Signal the modifyer thread to stop and wait until it exits */ signal_state(mod_info, TEST_DONE); @@ -927,6 +1052,7 @@ int usage(void) { fprintf(stderr, "Userland /proc/pid/{s}maps test cases\n"); fprintf(stderr, " -d: Duration for time-consuming tests\n"); + fprintf(stderr, " -v: Verbose mode\n"); fprintf(stderr, " -h: Help screen\n"); exit(-1); } @@ -937,9 +1063,11 @@ int main(int argc, char **argv) int exec_fd; int opt; - while ((opt = getopt(argc, argv, "d:h")) != -1) { + while ((opt = getopt(argc, argv, "d:vh")) != -1) { if (opt == 'd') test_duration_sec = strtoul(optarg, NULL, 0); + else if (opt == 'v') + verbose = true; else if (opt == 'h') usage(); } From patchwork Fri Apr 18 17:49:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057560 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 17BD5C369CF for ; Fri, 18 Apr 2025 17:50:23 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 88FC76B02AF; Fri, 18 Apr 2025 13:50:18 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 83E176B02B0; Fri, 18 Apr 2025 13:50:18 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6B8D3280005; Fri, 18 Apr 2025 13:50:18 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 4993C6B02AF for ; Fri, 18 Apr 2025 13:50:18 -0400 (EDT) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 723B0120AF3 for ; Fri, 18 Apr 2025 17:50:19 +0000 (UTC) X-FDA: 83347903758.15.64646C6 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) by imf05.hostedemail.com (Postfix) with ESMTP id 8FF8A10000E for ; Fri, 18 Apr 2025 17:50:17 +0000 (UTC) Authentication-Results: imf05.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=o1Bcvjdw; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf05.hostedemail.com: domain of 32JACaAYKCEs574r0ot11tyr.p1zyv07A-zzx8npx.14t@flex--surenb.bounces.google.com designates 209.85.214.202 as permitted sender) smtp.mailfrom=32JACaAYKCEs574r0ot11tyr.p1zyv07A-zzx8npx.14t@flex--surenb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998617; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=g/gTsaXuJx1lGF+ktcF8yVCekjdFoDtmHyOs+3ik9i4=; b=JIGlbvVpsfwEQ7OZRguDd7RkZLqCnxawEzN/hadEorFjHLF9yk+/NjlgnIzDX89UMVhE6v 8gFAVxtycAyzZRrPBWDqgDZ76UMLVguVD7iDjB5G3IEKXVDDVVoR3NhJ5OG2nX9SKE44w/ Hc+rcSAWveeiOqhM3K6NFqwJunGgHQ8= ARC-Authentication-Results: i=1; imf05.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=o1Bcvjdw; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf05.hostedemail.com: domain of 32JACaAYKCEs574r0ot11tyr.p1zyv07A-zzx8npx.14t@flex--surenb.bounces.google.com designates 209.85.214.202 as permitted sender) smtp.mailfrom=32JACaAYKCEs574r0ot11tyr.p1zyv07A-zzx8npx.14t@flex--surenb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998617; a=rsa-sha256; cv=none; b=vTiRCiYN40nhbIYpPFKixO40z7luUvjIQuPHV52b1cb3He4La6KmTZvwG9qiwQt1oO8trK OWXOeJiHWE9sznJisTEOZqJYbznSrN8Hzhe2DnWk7MPCjzlnWza7H5iutoCMgx98gtKwF+ qLFtaYqgOfmsZBOhAamKblmO9mV+ti0= Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2262051205aso16016195ad.3 for ; Fri, 18 Apr 2025 10:50:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998616; x=1745603416; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=g/gTsaXuJx1lGF+ktcF8yVCekjdFoDtmHyOs+3ik9i4=; b=o1BcvjdwwkTX1chMDVEj/u2PO51tYusGzAagX8dkE+kgU7yRAhpll4i9XkxZUSl+hb WvtTZhUT3FXZI74PArInbWsZmYwMuuRjWnDbK7TkBV6Y0WDLVTBgjna5HQhlNxUgOx41 wMHwKMHsRxzXvTi/zO5V3SJ/nzPkyHoSPkCdf7QQhlqbkDbfCR8SDCpq0tO15OfuolsW HJ7Gy++81yVg2sFus6qngD3s4Nwfou3V0zU3/uB5MWeibbBF6yAa0lFKdarHgle8/6Hy wDOhunPZi+PT6bAK/DarWBYPACS76Opa49qinmf4613a5DZrQ2DJSVfFVji1i8s5JdmT bG0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998616; x=1745603416; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=g/gTsaXuJx1lGF+ktcF8yVCekjdFoDtmHyOs+3ik9i4=; b=vvBHpqoKtvl/LyErI/5CfGAgpKkHX8F2TXxFMFVOqhPGeWCAwwyTxbaFYcdwU1pJZ9 Xzdr2t419bCo25BpduEzd8P+DndPCgYcus7TL3sOMwJlC7yEGI5g+8VK34Ah4xhyp6MO l/dSCckG7SK4s/X2NYpQDg5dMGN06XHqhiM7mBYzvymQhU3F6NdOTNhDpzsKe2sMz8Ez tDX5q0TZKUlWO2PSMAjg5jbvKKox/F/48Cn3kr6+2T2sTvIEoeVm9btPAAbvSi0vvAdB vpnc1NwKB/f+QZnTA8dr9nsgloLDkks1kKMtJFZkzVYEXVN+OzlN+vsRMQhMHNC9POgN rVLw== X-Forwarded-Encrypted: i=1; AJvYcCU3cB6d+a7h+NNEDQP75uGRsZVr159T7PW2XMxBum3C/IanjtBXlwQQIaV/gUnGcmiGAr/5YVMGmA==@kvack.org X-Gm-Message-State: AOJu0Yy7M8pL7aQp+oslN5++BEKODDY0HuxQceIbbqvAGh7NLJU1eQnR 3E/ICUBDQ/0m69N8uxPBYuOPZb6TSjHFQhy3k/sxB4JCo13Ii6Dlt2ZeH1IrjYu3q3f9SKR/MQ2 OqQ== X-Google-Smtp-Source: AGHT+IGjcICUXwS1wYeFYZR+XrM2Xg014/1EfWbXSEfTLiETYQCBjkJqO1ncD1j5guZx5QFaNlxV4IfN5dY= X-Received: from plld7.prod.google.com ([2002:a17:902:7287:b0:223:8244:94f6]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1744:b0:227:e980:919d with SMTP id d9443c01a7336-22c536207dfmr51660975ad.47.1744998616385; Fri, 18 Apr 2025 10:50:16 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:57 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-7-surenb@google.com> Subject: [PATCH v3 6/8] mm: make vm_area_struct anon_name field RCU-safe From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Stat-Signature: mdfcbq9gufnkhzmzg7z8ont3ajskomun X-Rspamd-Queue-Id: 8FF8A10000E X-Rspam-User: X-Rspamd-Server: rspam05 X-HE-Tag: 1744998617-892644 X-HE-Meta: U2FsdGVkX18scP9/UnRz6qtQ1/c1991spVOSugFZZKoxx61dz7lnOBqkX/gNC7Tw84WQmZeKVMlhpD/Wo1a65u0AhFSwPjAnehptbj10pUhhjrTDDU3dErHEZ7VS3ixQvnY3LJR9+z5Twqt8RHDBVLK+d0TB9G1F/oIE6DmOP/8Vt4luFMsThg8KiSqF2+KbDI6zu/ECfZQ2qHEOfO0RGM+4EZLndUadvP4wRNny4rxzIhq6EJLnD1rRvjfRuxYIXTEijvKr04UxgvMwkwhRjjId2zSqI7epjxfnoUitVHZVB7z9ivqzWAUnixyvyg5V8N8TQRUW+CbOvyV1yueaBLAOC+8jFoZXB1sf4RPfvTur9P16HaajlT2rta0jJp2C3z//yvU05nGPgFOtmVXFr90tM4USnx/aMk5OIdEL8uzqEXug9susmVuLeyw0sVbmj0ohrm/99g8BGp/NEr7DQJO4CWDw3cdiare5lDJWAF4kCXHQ42moP4bwtLyY7fG0cfLb6bcxhsqlj92ygF67lmBMdAsQ1UphBnOTMwXcC0J3VitNi/ZBT18L9+sAMYI9MzOItYZDmltadhhtvniI1/i0pmtpxJUD5u/jiPic6B3iX+wLgINTtGrNyU4OuxV9szwtdlUKuyj/XciSLPKDtZf9s8dfE2JfZHSO85Wg7RuwRGqbXpbAnjHCrXhbjvp9gfoMWd/3/FDWOD0ynmTtjsc1mHexT/gM7W8kunq2I2+P8TYliaJJYN4c3CH/lmOIdu5ODeeC3u4wG2oNDbW3Oe4hoerTQd6Koj9TUHOdiyjv2hckGWWvuDs+cAIkWcdYackEs+bnwFUUvHI0EwmiUkXZ37b4QLeDkNnANOLdrKinaeWLUaWATpwYDW1wWtX7VauAraHURaHO62N4BIC56UPJyZylxwsiX3KqmN6839ElmdxITuxdg+twe/ucOx3LwoD0nrby52z7OqcWRF4 xZpx9Mp8 dtjAcLc816hhBApSFsvyaNgrEMxm5udhSSY2qr9BPxYFAikllxGIEps1Ti2W+5OyAHPX1zfWxMiP/tUWvQDg2upQz2/9BRSfOLjmoAvagmzKRL6n6k0GMaGBiO9MM0m7zMfiR8EzlwcfBWKlv58Vn3wA5atpLZpPPF//mPBAvfnXW7Te+A54Bp+HKtsHOZ/7SlS2bj5i32CNkQdXPwJKkfOd1Lcc45SHeGNWtdUUZbGed6C32ycoiX0qpnjP0e6Y7rflYm3WQqOmVVAYyxvYBpnzHbDzoSGgjhw60149qNJ4KNadxrhhrAp3guI3T/eeffDepaob9FeMad4Uj19qEGkHeOYFsYNqwgp1RP+Wcz6gjHFFrrp9AmfZ5VywF/qQ6T9J4x+vWrRtS8V+eZzUfVG8ZdhscnkWnkQhUdmrcfFk1HPhyAcNOp4FjuSLVLs3+K0y2SGNeWcG0ytS2uoQl0dHAmJK33VFuV4qcZ0kw46RZ8MiEuKh+kQyCPmZWsD0O4XCZmbueXU1XGVSmMDUOLrAQwHQWO1oT8MhdoN0vEKqWWrEWm8vOY7xDyyxL0YDQoxy4rBvWeJ3HsLGraMPkGEFCQQ== 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: For lockless /proc/pid/maps reading we have to ensure all the fields used when generating the output are RCU-safe. The only pointer fields in vm_area_struct which are used to generate that file's output are vm_file and anon_name. vm_file is RCU-safe but anon_name is not. Make anon_name RCU-safe as well. Signed-off-by: Suren Baghdasaryan --- include/linux/mm_inline.h | 10 +++++++++- include/linux/mm_types.h | 3 ++- mm/madvise.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index f9157a0c42a5..9ac2d92d7ede 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -410,7 +410,7 @@ static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma, struct anon_vma_name *anon_name = anon_vma_name(orig_vma); if (anon_name) - new_vma->anon_name = anon_vma_name_reuse(anon_name); + rcu_assign_pointer(new_vma->anon_name, anon_vma_name_reuse(anon_name)); } static inline void free_anon_vma_name(struct vm_area_struct *vma) @@ -432,6 +432,8 @@ static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1, !strcmp(anon_name1->name, anon_name2->name); } +struct anon_vma_name *anon_vma_name_get_rcu(struct vm_area_struct *vma); + #else /* CONFIG_ANON_VMA_NAME */ static inline void anon_vma_name_get(struct anon_vma_name *anon_name) {} static inline void anon_vma_name_put(struct anon_vma_name *anon_name) {} @@ -445,6 +447,12 @@ static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1, return true; } +static inline +struct anon_vma_name *anon_vma_name_get_rcu(struct vm_area_struct *vma) +{ + return NULL; +} + #endif /* CONFIG_ANON_VMA_NAME */ static inline void init_tlb_flush_pending(struct mm_struct *mm) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 56d07edd01f9..15ec288d4a21 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -700,6 +700,7 @@ struct vm_userfaultfd_ctx {}; struct anon_vma_name { struct kref kref; + struct rcu_head rcu; /* The name needs to be at the end because it is dynamically sized. */ char name[]; }; @@ -874,7 +875,7 @@ struct vm_area_struct { * terminated string containing the name given to the vma, or NULL if * unnamed. Serialized by mmap_lock. Use anon_vma_name to access. */ - struct anon_vma_name *anon_name; + struct anon_vma_name __rcu *anon_name; #endif struct vm_userfaultfd_ctx vm_userfaultfd_ctx; } __randomize_layout; diff --git a/mm/madvise.c b/mm/madvise.c index 8433ac9b27e0..ed03a5a2c140 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -101,14 +101,15 @@ void anon_vma_name_free(struct kref *kref) { struct anon_vma_name *anon_name = container_of(kref, struct anon_vma_name, kref); - kfree(anon_name); + kfree_rcu(anon_name, rcu); } struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma) { mmap_assert_locked(vma->vm_mm); - return vma->anon_name; + return rcu_dereference_protected(vma->anon_name, + rwsem_is_locked(&vma->vm_mm->mmap_lock)); } /* mmap_lock should be write-locked */ @@ -118,7 +119,7 @@ static int replace_anon_vma_name(struct vm_area_struct *vma, struct anon_vma_name *orig_name = anon_vma_name(vma); if (!anon_name) { - vma->anon_name = NULL; + rcu_assign_pointer(vma->anon_name, NULL); anon_vma_name_put(orig_name); return 0; } @@ -126,11 +127,32 @@ static int replace_anon_vma_name(struct vm_area_struct *vma, if (anon_vma_name_eq(orig_name, anon_name)) return 0; - vma->anon_name = anon_vma_name_reuse(anon_name); + rcu_assign_pointer(vma->anon_name, anon_vma_name_reuse(anon_name)); anon_vma_name_put(orig_name); return 0; } + +/* + * Returned anon_vma_name is stable due to elevated refcount but not guaranteed + * to be assigned to the original VMA after the call. + */ +struct anon_vma_name *anon_vma_name_get_rcu(struct vm_area_struct *vma) +{ + struct anon_vma_name __rcu *anon_name; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + anon_name = rcu_dereference(vma->anon_name); + if (!anon_name) + return NULL; + + if (unlikely(!kref_get_unless_zero(&anon_name->kref))) + return NULL; + + return anon_name; +} + #else /* CONFIG_ANON_VMA_NAME */ static int replace_anon_vma_name(struct vm_area_struct *vma, struct anon_vma_name *anon_name) From patchwork Fri Apr 18 17:49:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057561 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 EBD61C369CA for ; Fri, 18 Apr 2025 17:50:25 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 5B1226B02B0; Fri, 18 Apr 2025 13:50:20 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 510256B02B1; Fri, 18 Apr 2025 13:50:20 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2C6EF6B02B2; Fri, 18 Apr 2025 13:50:20 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 06EE56B02B0 for ; Fri, 18 Apr 2025 13:50:20 -0400 (EDT) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 6E892BBECF for ; Fri, 18 Apr 2025 17:50:21 +0000 (UTC) X-FDA: 83347903842.16.067A18D Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) by imf06.hostedemail.com (Postfix) with ESMTP id A49BE180009 for ; Fri, 18 Apr 2025 17:50:19 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="Bl5o4/oE"; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf06.hostedemail.com: domain of 32pACaAYKCE0796t2qv33v0t.r310x29C-11zAprz.36v@flex--surenb.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=32pACaAYKCE0796t2qv33v0t.r310x29C-11zAprz.36v@flex--surenb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998619; a=rsa-sha256; cv=none; b=j8rNo7l43hfoWCiKYdQSQMisQ3xmdDHFokXC2uUD9mklwRc7f3uSmHQOaTSKb3+twWDPiQ UVMkfT5ytnZtrgJW4OSNerK4LoZKgIpk9tGc4ZPWCCd2Go2mb1Qd5bEnEvXh6qblMQyNN3 YdU8pqTj9F2cZwhY340JgHBqlhTwp7w= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="Bl5o4/oE"; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf06.hostedemail.com: domain of 32pACaAYKCE0796t2qv33v0t.r310x29C-11zAprz.36v@flex--surenb.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=32pACaAYKCE0796t2qv33v0t.r310x29C-11zAprz.36v@flex--surenb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998619; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=/zYtkrY7HUMXj6I83iq2T2dcIR3++4RWvz/bo+0QsbU=; b=t1pcmhuv2yAWEK6V4OenDMfZhCOikDOpnVoJqWda5kei9hkL7BltcrkWyJ2aNZ/XgwbNJr 55+Jf3qXUt52a1fLsRJDN1da14q+ks4o9fN3bqbSPKcfj3xEtIPsQeT3Nxa43P14MRdO/0 Y/Y0DYPaIBsZB5IUQhsKZyAdKNKLWv4= Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b078af4b07dso1206864a12.3 for ; Fri, 18 Apr 2025 10:50:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998618; x=1745603418; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=/zYtkrY7HUMXj6I83iq2T2dcIR3++4RWvz/bo+0QsbU=; b=Bl5o4/oEGuivrMB5oHBtGXj4klSXUDgoTNG10YlIUhEEfCbtDCKLXx/Hk+X7Dpf1rq UoQPE9mJY+gyxuoLv3XpWG1UzD1bRqLkasGghDm7hnhFkGAsWHkTRra4pBD0Ulm9Kyu4 Vt29QaCPmG34l6QWm3qlTPrWxnB6mt4636k4agHWz46DDj2aKkmcianKAuLhHAf0LM7+ Zh4vHquL5hkAdwuedEd+HaTF1IFxZENW4wmSy6gMhA096llUGOXQ3l/LXcWEmyQz0Zgm VGbsJxv2WwOq8QZ+joteN3TJXOxVcdsIEE2xeSEUpwc4+QJaWmxEkBNXZY/6pdu1zlWU sGjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998618; x=1745603418; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/zYtkrY7HUMXj6I83iq2T2dcIR3++4RWvz/bo+0QsbU=; b=hRnrlAz8PIBI9pp2npsI1l51D2bOtPN1h48UiMqsqjkwrs9CjNR1Bh+OvxUeZnpBU6 MK3K30bshoaQe840zNiUEjVGtoeQm/Ou6rvdS5OPcNaFu3KO6TMKYU8MVTx39qWSYImZ U81hIuWrNIXAOflI1vBHemmsqFSFLsjI99/nuChhgvlaV0w3/SpkbZcKikici/bOu6oN OMUhBoE9gDSkVBAT9iabnqMIVmxEX+kdhNwD83kIksXy+Dod7n2YjKNcnhuJrE5Xp3gV 3l3koeNWzzaERXdvyk1s+e+zwbau+XJU8JvzxnCC51PQBGJSw5/KIrpzf1u9Rkx7SyOS O10A== X-Forwarded-Encrypted: i=1; AJvYcCUYGupwMon2/uiZ+4S9WDbxuhzWMAMkTuq9R3bIt6OpumT9HRwSCwguPn9+xwhBMM26/DTvcDmTLQ==@kvack.org X-Gm-Message-State: AOJu0Yy2p58I2N+Lkz6y+t1Q1g3WUjpHhR+VqCOuy1jNu/UJ8KMB9maj 85Ywxw15TuTT840etJmvDAfjO3HgNawTzKnfhuOWjT0PN+QhLhkg+OfTXK3GpW7fs7p0hWpji49 8Rw== X-Google-Smtp-Source: AGHT+IFtA4TMsuStPYu7aoBjj//DZ8se4BNHvSXu+W66hYuPWTAds876LFCU1b60VeWLvlCjpqZ1/KyDDUw= X-Received: from pjbpa2.prod.google.com ([2002:a17:90b:2642:b0:2ef:7af4:5e8e]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:528a:b0:2ff:7ad4:77b1 with SMTP id 98e67ed59e1d1-3087bb3973fmr6045262a91.2.1744998618622; Fri, 18 Apr 2025 10:50:18 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:58 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-8-surenb@google.com> Subject: [PATCH v3 7/8] mm/maps: read proc/pid/maps under RCU From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Rspam-User: X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: A49BE180009 X-Stat-Signature: x6ycbp9zmcom737st4qg5nye8wu5djg9 X-HE-Tag: 1744998619-338423 X-HE-Meta: U2FsdGVkX1/d9A4RBrDDOiWqlbsE3vhpdHqnAEhwFOtGvQNKzlC4Hyu8ul8+VZ86A4UQDBl0xAaxEdKsdrUvwuKx6B+T+qxVLVtUs56RxjT+sW/45o23edf4zULfNmim4SK6xWFrZVhacTQT5vUeh95fr9rv+ztqJX2SVaQ5xOsYAOUlUWFMI+lSnbTmTcR6D9VlwjlgqyirO8R013cEj10+mX17ZYoRU7eFB0lihoYlx3QdXsnod1NUUGYQKUGFjvDZlg7omt8rhowLul5ExZb23poVq3+/Fnw/0TxyIHpfBa6hwhj/82KqIrTXVLHXc0Yo5fgloG/FkMEtHK2zh4aDtTM/A+Xz47tpJLquWRU2aCUakodR8h1DYpLuN6hmCcYiK3MZaCSTg25v4tZhzRiqBxb8UX7kqDTt6ESKsJoPP6t68GOmNIdA4S5Yb/A02IR7LdWiCa4t7IqdeNJh8mYb8nSmKqtQei/XaxUyVtI40I/pt0OsbkCxuobeKTs5yFeLi1k6nxPuzOA3KoUYniXYuZc8XnB5kLRasZYIEB59hKa9LzeED4+gDRRiJljTGl3CSjnJNFud9iu6DzQgKCVMngQwiGVQHCKqS8mXL9P9AoVWOHHExGgjAKkbVQ2fW48zy42NR6cfABd+IXi0ZttYGr2ReVZ/uBy5hExq75EOla+fxfgZvjnrh0FzxopShYZZXqXIW0zsYW7ce2r4X+mc88hQCM4dyLJqd+Jes8nQqUW7+Wn2M+z+BfXxgL/4lT6DQrw3LmJBgXowwMD4fv4oMqRYWrC0sLCxclOlcJAGBfFp07wORUrwTApSbE+JGSxgnL/+dh6MKbg7MGRsTXrlS7TxjcZ93ChLXX3gGMkZq/sYqjVUhpkxvPM8lTzp9Pw2n7B0wjvqvUVTPMXBZ0YL4g3BwiXCKHiJHOtaoA0ACSDYiA46ybZNFuIZAvKZ0dL9KbiFaAtaVbSmLJ/ XY0wCbX2 XHzCsInC/HjsDj+knTw8IgzBchoVscHSs/7Gilch41SV3sd1Kf0pvRmQUZv9NDmnVvXNOZllYVFGgiso2Q7WoSxsJlN79psTu9iEef5v2iGAam7i6We9XIV8RvC7S28YltY9G4q/oh90zkg9aY7lnXr1garOzng+YTITIT0y7HAuecwVXoGPbTp9ln4+47PZd4T4td3olIfK2L/xp+8Se8hb0tZBKOhhXkjr6yUSts3EXMgDTtUIQf/X90LJjjV2tZeAgA/gtrBH0Oo5ZQR7IVy3GhBMAIaD0enozpUSvgg9Ke55SvUWWBkg+NldGWjHb2BZ9BdG45VP4li5qdpDlI/Yx5p9LODqeejZvXfZzPhPvU2JcIIazIf8yUNQKFBcJWo62CFOETOate5IqwQrlebQSF6MFOG90Pz8QeL5R5Ju4VqW7PwWdFvxLuEno+debiZXUTKJFUP/wPtpQUSs6byUH5rnw2m3L3RKpD7icoDA1Mhd7h6AEewb4DniIeqFwGe18L5MHzQsp/9H+aX5RIa1o954khf2qTzhimYThmV80uZM= 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: With maple_tree supporting vma tree traversal under RCU and vma and its important members being RCU-safe, /proc/pid/maps can be read under RCU and without the need to read-lock mmap_lock. However vma content can change from under us, therefore we make a copy of the vma and we pin pointer fields used when generating the output (currently only vm_file and anon_name). Afterwards we check for concurrent address space modifications, wait for them to end and retry. While we take the mmap_lock for reading during such contention, we do that momentarily only to record new mm_wr_seq counter. This change is designed to reduce mmap_lock contention and prevent a process reading /proc/pid/maps files (often a low priority task, such as monitoring/data collection services) from blocking address space updates. Note that this change has a userspace visible disadvantage: it allows for sub-page data tearing as opposed to the previous mechanism where data tearing could happen only between pages of generated output data. Since current userspace considers data tearing between pages to be acceptable, we assume is will be able to handle sub-page data tearing as well. Signed-off-by: Suren Baghdasaryan --- fs/proc/internal.h | 6 ++ fs/proc/task_mmu.c | 170 ++++++++++++++++++++++++++++++++++---- include/linux/mm_inline.h | 18 ++++ 3 files changed, 177 insertions(+), 17 deletions(-) diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 96122e91c645..6e1169c1f4df 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -379,6 +379,12 @@ struct proc_maps_private { struct task_struct *task; struct mm_struct *mm; struct vma_iterator iter; + bool mmap_locked; + loff_t last_pos; +#ifdef CONFIG_PER_VMA_LOCK + unsigned int mm_wr_seq; + struct vm_area_struct vma_copy; +#endif #ifdef CONFIG_NUMA struct mempolicy *task_mempolicy; #endif diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index b9e4fbbdf6e6..f9d50a61167c 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -127,13 +127,130 @@ static void release_task_mempolicy(struct proc_maps_private *priv) } #endif -static struct vm_area_struct *proc_get_vma(struct proc_maps_private *priv, - loff_t *ppos) +#ifdef CONFIG_PER_VMA_LOCK + +static const struct seq_operations proc_pid_maps_op; + +/* + * Take VMA snapshot and pin vm_file and anon_name as they are used by + * show_map_vma. + */ +static int get_vma_snapshot(struct proc_maps_private *priv, struct vm_area_struct *vma) +{ + struct vm_area_struct *copy = &priv->vma_copy; + int ret = -EAGAIN; + + memcpy(copy, vma, sizeof(*vma)); + if (copy->vm_file && !get_file_rcu(©->vm_file)) + goto out; + + if (!anon_vma_name_get_if_valid(copy)) + goto put_file; + + if (!mmap_lock_speculate_retry(priv->mm, priv->mm_wr_seq)) + return 0; + + /* Address space got modified, vma might be stale. Re-lock and retry. */ + rcu_read_unlock(); + ret = mmap_read_lock_killable(priv->mm); + if (!ret) { + /* mmap_lock_speculate_try_begin() succeeds when holding mmap_read_lock */ + mmap_lock_speculate_try_begin(priv->mm, &priv->mm_wr_seq); + mmap_read_unlock(priv->mm); + ret = -EAGAIN; + } + + rcu_read_lock(); + + anon_vma_name_put_if_valid(copy); +put_file: + if (copy->vm_file) + fput(copy->vm_file); +out: + return ret; +} + +static void put_vma_snapshot(struct proc_maps_private *priv) +{ + struct vm_area_struct *vma = &priv->vma_copy; + + anon_vma_name_put_if_valid(vma); + if (vma->vm_file) + fput(vma->vm_file); +} + +static inline bool drop_mmap_lock(struct seq_file *m, struct proc_maps_private *priv) +{ + /* + * smaps and numa_maps perform page table walk, therefore require + * mmap_lock but maps can be read under RCU. + */ + if (m->op != &proc_pid_maps_op) + return false; + + /* mmap_lock_speculate_try_begin() succeeds when holding mmap_read_lock */ + mmap_lock_speculate_try_begin(priv->mm, &priv->mm_wr_seq); + mmap_read_unlock(priv->mm); + rcu_read_lock(); + memset(&priv->vma_copy, 0, sizeof(priv->vma_copy)); + + return true; +} + +static struct vm_area_struct *get_stable_vma(struct vm_area_struct *vma, + struct proc_maps_private *priv, + loff_t last_pos) +{ + int ret; + + put_vma_snapshot(priv); + while ((ret = get_vma_snapshot(priv, vma)) == -EAGAIN) { + /* lookup the vma at the last position again */ + vma_iter_init(&priv->iter, priv->mm, last_pos); + vma = vma_next(&priv->iter); + } + + return ret ? ERR_PTR(ret) : &priv->vma_copy; +} + +#else /* CONFIG_PER_VMA_LOCK */ + +/* Without per-vma locks VMA access is not RCU-safe */ +static inline bool drop_mmap_lock(struct seq_file *m, + struct proc_maps_private *priv) +{ + return false; +} + +static struct vm_area_struct *get_stable_vma(struct vm_area_struct *vma, + struct proc_maps_private *priv, + loff_t last_pos) +{ + return vma; +} + +#endif /* CONFIG_PER_VMA_LOCK */ + +static struct vm_area_struct *proc_get_vma(struct seq_file *m, loff_t *ppos) { + struct proc_maps_private *priv = m->private; struct vm_area_struct *vma = vma_next(&priv->iter); + if (vma && !priv->mmap_locked) + vma = get_stable_vma(vma, priv, *ppos); + + if (IS_ERR(vma)) + return vma; + if (vma) { - *ppos = vma->vm_start; + /* Store previous position to be able to restart if needed */ + priv->last_pos = *ppos; + /* + * Track the end of the reported vma to ensure position changes + * even if previous vma was merged with the next vma and we + * found the extended vma with the same vm_start. + */ + *ppos = vma->vm_end; } else { *ppos = -2UL; vma = get_gate_vma(priv->mm); @@ -148,6 +265,7 @@ static void *m_start(struct seq_file *m, loff_t *ppos) unsigned long last_addr = *ppos; struct mm_struct *mm; + priv->mmap_locked = true; /* See m_next(). Zero at the start or after lseek. */ if (last_addr == -1UL) return NULL; @@ -170,12 +288,18 @@ static void *m_start(struct seq_file *m, loff_t *ppos) return ERR_PTR(-EINTR); } + /* Drop mmap_lock if possible */ + if (drop_mmap_lock(m, priv)) + priv->mmap_locked = false; + + if (last_addr > 0) + *ppos = last_addr = priv->last_pos; vma_iter_init(&priv->iter, mm, last_addr); hold_task_mempolicy(priv); if (last_addr == -2UL) return get_gate_vma(mm); - return proc_get_vma(priv, ppos); + return proc_get_vma(m, ppos); } static void *m_next(struct seq_file *m, void *v, loff_t *ppos) @@ -184,7 +308,7 @@ static void *m_next(struct seq_file *m, void *v, loff_t *ppos) *ppos = -1UL; return NULL; } - return proc_get_vma(m->private, ppos); + return proc_get_vma(m, ppos); } static void m_stop(struct seq_file *m, void *v) @@ -196,7 +320,10 @@ static void m_stop(struct seq_file *m, void *v) return; release_task_mempolicy(priv); - mmap_read_unlock(mm); + if (priv->mmap_locked) + mmap_read_unlock(mm); + else + rcu_read_unlock(); mmput(mm); put_task_struct(priv->task); priv->task = NULL; @@ -243,14 +370,20 @@ static int do_maps_open(struct inode *inode, struct file *file, static void get_vma_name(struct vm_area_struct *vma, const struct path **path, const char **name, - const char **name_fmt) + const char **name_fmt, bool mmap_locked) { - struct anon_vma_name *anon_name = vma->vm_mm ? anon_vma_name(vma) : NULL; + struct anon_vma_name *anon_name; *name = NULL; *path = NULL; *name_fmt = NULL; + if (vma->vm_mm) + anon_name = mmap_locked ? anon_vma_name(vma) : + anon_vma_name_get_rcu(vma); + else + anon_name = NULL; + /* * Print the dentry name for named mappings, and a * special [heap] marker for the heap: @@ -266,39 +399,41 @@ static void get_vma_name(struct vm_area_struct *vma, } else { *path = file_user_path(vma->vm_file); } - return; + goto out; } if (vma->vm_ops && vma->vm_ops->name) { *name = vma->vm_ops->name(vma); if (*name) - return; + goto out; } *name = arch_vma_name(vma); if (*name) - return; + goto out; if (!vma->vm_mm) { *name = "[vdso]"; - return; + goto out; } if (vma_is_initial_heap(vma)) { *name = "[heap]"; - return; + goto out; } if (vma_is_initial_stack(vma)) { *name = "[stack]"; - return; + goto out; } if (anon_name) { *name_fmt = "[anon:%s]"; *name = anon_name->name; - return; } +out: + if (anon_name && !mmap_locked) + anon_vma_name_put(anon_name); } static void show_vma_header_prefix(struct seq_file *m, @@ -324,6 +459,7 @@ static void show_vma_header_prefix(struct seq_file *m, static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) { + struct proc_maps_private *priv = m->private; const struct path *path; const char *name_fmt, *name; vm_flags_t flags = vma->vm_flags; @@ -344,7 +480,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) end = vma->vm_end; show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino); - get_vma_name(vma, &path, &name, &name_fmt); + get_vma_name(vma, &path, &name, &name_fmt, priv->mmap_locked); if (path) { seq_pad(m, ' '); seq_path(m, path, "\n"); @@ -549,7 +685,7 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) const char *name_fmt; size_t name_sz = 0; - get_vma_name(vma, &path, &name, &name_fmt); + get_vma_name(vma, &path, &name, &name_fmt, true); if (path || name_fmt || name) { name_buf = kmalloc(name_buf_sz, GFP_KERNEL); diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 9ac2d92d7ede..436512f1e759 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -434,6 +434,21 @@ static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1, struct anon_vma_name *anon_vma_name_get_rcu(struct vm_area_struct *vma); +/* + * Takes a reference if anon_vma is valid and stable (has references). + * Fails only if anon_vma is valid but we failed to get a reference. + */ +static inline bool anon_vma_name_get_if_valid(struct vm_area_struct *vma) +{ + return !vma->anon_name || anon_vma_name_get_rcu(vma); +} + +static inline void anon_vma_name_put_if_valid(struct vm_area_struct *vma) +{ + if (vma->anon_name) + anon_vma_name_put(vma->anon_name); +} + #else /* CONFIG_ANON_VMA_NAME */ static inline void anon_vma_name_get(struct anon_vma_name *anon_name) {} static inline void anon_vma_name_put(struct anon_vma_name *anon_name) {} @@ -453,6 +468,9 @@ struct anon_vma_name *anon_vma_name_get_rcu(struct vm_area_struct *vma) return NULL; } +static inline bool anon_vma_name_get_if_valid(struct vm_area_struct *vma) { return true; } +static inline void anon_vma_name_put_if_valid(struct vm_area_struct *vma) {} + #endif /* CONFIG_ANON_VMA_NAME */ static inline void init_tlb_flush_pending(struct mm_struct *mm) From patchwork Fri Apr 18 17:49:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suren Baghdasaryan X-Patchwork-Id: 14057562 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 1387AC369CA for ; Fri, 18 Apr 2025 17:50:29 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 20B646B02B1; Fri, 18 Apr 2025 13:50:23 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1B9716B02B3; Fri, 18 Apr 2025 13:50:23 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id F2DE56B02B4; Fri, 18 Apr 2025 13:50:22 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id D32FC6B02B1 for ; Fri, 18 Apr 2025 13:50:22 -0400 (EDT) Received: from smtpin25.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 3BC0E160AB8 for ; Fri, 18 Apr 2025 17:50:24 +0000 (UTC) X-FDA: 83347903968.25.2B9F23D Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) by imf14.hostedemail.com (Postfix) with ESMTP id D8804100008 for ; Fri, 18 Apr 2025 17:50:21 +0000 (UTC) Authentication-Results: imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=0qWUbmrs; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf14.hostedemail.com: domain of 33JACaAYKCE89B8v4sx55x2v.t532z4BE-331Crt1.58x@flex--surenb.bounces.google.com designates 209.85.214.202 as permitted sender) smtp.mailfrom=33JACaAYKCE89B8v4sx55x2v.t532z4BE-331Crt1.58x@flex--surenb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744998621; a=rsa-sha256; cv=none; b=lEBRwBVwFlBsT2OJ+FB2DcRvagD6frI/Hpf4wkAIPCjK9rdoAegfo8EWjzsoxQ1Bga67lt EHnGiQUVkgsBczpQxhoYx93Ryku8kiOxPW3WUebWTwN2pzGgSCgJNStpzyfkhTOKxTXl8f pTDwNuzyDD6nJoKld0rcvSvYYXLGWiU= ARC-Authentication-Results: i=1; imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=0qWUbmrs; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf14.hostedemail.com: domain of 33JACaAYKCE89B8v4sx55x2v.t532z4BE-331Crt1.58x@flex--surenb.bounces.google.com designates 209.85.214.202 as permitted sender) smtp.mailfrom=33JACaAYKCE89B8v4sx55x2v.t532z4BE-331Crt1.58x@flex--surenb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744998621; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=GDNsq3YX7eW5e3apKRRmkWWvDDDuWE0xbjvQjwBgCsE=; b=qkKQcVJTe51sp5hbWYx8GBBcWQ+Hivuj2YIC5E3VJnOESuyuBdRlGbV1C4KlgvxfTE5crL OcAdUg+r3BvdMqphE0jXbz1TKydXNpcBvMI0aX9LoI4Qo8wnXMHmp5QrFheGVgc63Rv9aH QXbLCdkIAZpQQG7sgJU9q6U8PxGLV+E= Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-22c35bafdbdso30245925ad.1 for ; Fri, 18 Apr 2025 10:50:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744998621; x=1745603421; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=GDNsq3YX7eW5e3apKRRmkWWvDDDuWE0xbjvQjwBgCsE=; b=0qWUbmrszho6lf/6bsKu4TFOmR4Ou6Zc0iXRlDKGhJcJhuigOFH3cIzub2bFO6rD+e xx6Y3JdJ4XqeFeGClmPaZXjbqXeGPEo3nyWj0Be4YBCRA+1naQ8RdI7vYI+mbAwKRxxm 8fhLU6RmFSuFyihLd5o3qbaO939RCUOeMGMyMVDMKBfixGnY2Q/8iLFj6W7CcsJVtECz iBHjyjplqnKgVZdKLhChEodQVORe7Oj1bYatyE0hGZBbUZMMOyPqzQ+cpMGIaaeITYgU 3q58WfF5BC4RO3j8nkgaY8LoCUIa2tCJ2wvcEIOQmd8mB+wBUPPtdTYBcH2JHwn5iEU/ 0caw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744998621; x=1745603421; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=GDNsq3YX7eW5e3apKRRmkWWvDDDuWE0xbjvQjwBgCsE=; b=LmGLEpOjyEug94UJE5avVW6TD05fTB7r2xfakQJpN+pWzlnpFAmgL0kmZEmHZkkS/y ScqURSRnHKB+hfyx7OJoLsVYH3FwuK1NflIERDX07ZOj0IyTT1y1VxnHSt9bnyawoPG1 m3VyPH5GkT+O+RS1w72GxteC0yodtQ7Kc4fDqGcKddWRzi1mOldUye3ybiKQunmnR7mo y8U8j4DItZhahndVSh3VKVKl5RhE15qZediiRgjiv913EpKjGq1wi3xGfOcGna0He5Nk FQ57+hWRB8Ust85U5R4tbnsx8JMOY7CvYCRTW0ZpAk7/JpKwdH/1OtqyvU6sA4Lk9/WG Cmvg== X-Forwarded-Encrypted: i=1; AJvYcCULa+Rz9miqu2XTqf6IwPxqJgIw5K+jbrHebOxZm+V1+xQeC8rCY0Su1KmQmW76nzY8BVx9HMQpKw==@kvack.org X-Gm-Message-State: AOJu0YwFDOOhZ5q2s6dMKPL+Rhp9eNEhys8PNQJS+fmSZMGgrOclkAKA W2Ngh3o2WyYhfXjyZvL5gbTQzrrleBjVXmoRMKZDKgvrTGRuKyFs4tGgCWwuOxepcGcf1aHk28j SgQ== X-Google-Smtp-Source: AGHT+IH4SzFcgriEZeEyINeEOYHsKsBduZvh1a8UF65TGxe4ng4DHNhTgv3meBOCFXGKpW1iswhVW2S93bM= X-Received: from plrd9.prod.google.com ([2002:a17:902:aa89:b0:223:225b:3d83]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:19cc:b0:224:24d5:f20a with SMTP id d9443c01a7336-22c53620caamr57870345ad.48.1744998620802; Fri, 18 Apr 2025 10:50:20 -0700 (PDT) Date: Fri, 18 Apr 2025 10:49:59 -0700 In-Reply-To: <20250418174959.1431962-1-surenb@google.com> Mime-Version: 1.0 References: <20250418174959.1431962-1-surenb@google.com> X-Mailer: git-send-email 2.49.0.805.g082f7c87e0-goog Message-ID: <20250418174959.1431962-9-surenb@google.com> Subject: [PATCH v3 8/8] mm/maps: execute PROCMAP_QUERY ioctl under RCU From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, david@redhat.com, vbabka@suse.cz, peterx@redhat.com, jannh@google.com, hannes@cmpxchg.org, mhocko@kernel.org, paulmck@kernel.org, shuah@kernel.org, adobriyan@gmail.com, brauner@kernel.org, josef@toxicpanda.com, yebin10@huawei.com, linux@weissschuh.net, willy@infradead.org, osalvador@suse.de, andrii@kernel.org, ryan.roberts@arm.com, christophe.leroy@csgroup.eu, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, surenb@google.com X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: D8804100008 X-Stat-Signature: j4yryccr6bfwwn6b4wqqabfiynah4bnk X-Rspam-User: X-HE-Tag: 1744998621-25102 X-HE-Meta: U2FsdGVkX1+s1SNeQqKuSK3hhhvpdBEzNa4XGv4qWFZ4zF30xmOlUOTfzZB2YE9E7c4s3Sxbv+CfnFSJh4VXlgfeDhH4pK5XD7/NpLzPr6OCPQOSYMpLmv8DouXfbT/8bsp7D94RLGFX5j86fwVrm+wy8O/kxcIihdyvNqJFxI1jJrio2dMc1fu21g8NNfg5txnoF5Bm1E7GmAzrpkfZNoxF+SXDK0O/JP6C7naNS9gpmB3e/IBbW1NF1p8YMSQoTj/9jhpWmmBPBLgEq5gtjYynArfu0WvhNqS5ALB2q+6JnsGe9MkjGJY23DdniqoEctCX65JsbnEahPBkPKwGsI7NHnbbPjB2rBfRlMEyY/tFUGAi/xY0Um0RHrjweCSJFd3bxjQDfPk2qg9xrX7dbTcDuNUbd2VGQxigHuD+OLz134C4dhY+9so2pp5ha6Q5vKV6VQR3HmKKoxDHQYoitSfROu8FyyX+W8+r45n3vWQxvyaKynyXh6OdRlcO9S7Ey3eMbaCF5vFoTckR99nRhdf8RMkBELcH7zgerEe5SvaY5FDSJlCXfrqkVL/MIhDRrQhyOE8qdke5fOxVQ56tVJsj/4vvCKIkEBIrNe2LWt7RwQVIP9cpI6xvDWZu264QiJ97+IYnT3n76cvNRyh1VHhORe/dpkNtq9OOoF288QbWpdF1zqKRygmmdrsEjPDGBlF6T6vhOwTIJEhEzXq1ZK6QPeSee/smpWXY5Vn8YZjvZsU+eao5xsNrJ3yTBnYd6OQt1kpeN+f00sQjj2oUDMCnekOg+2arR+MYOtV97OtTUiILYa8fR2ChqzKWYrP6I90SnafjDaTE/Lvtv81fh/XuO52YDXuBk4APBjieHy9cVQZI/eSNYATb7J8025jJLJdNHGm2sGsgSrCgcHxgNBROm/5lqcUON4Xbt1xwDkxVp9P+kDkO20Hx3KSl1Z/Vo1fq8twcvfIXcY/LFXy oN1wT4FD LdJHCqXMPaU5oBk8zjtEdaOuMQpcK8XW9BsYhCQTfjOnyL4PI9rS/zkKRuAWhF6SNY/QAbN/AxQlTwDiXH2PA4WXcuNpZUg5Qytnr/WpNM/cQrUCZTZI5W0/4251Y7r3OFMryaWjSBjEZIc8oQHn6axEzx8QrXB+BazL/vGEFgMPiwNMe7uhF5tF5QS/EQXwp4WFT6nLMDpoRhGtO2COPLdG1DccPvj3YmXmLhgU6w7N/JvUpQ3tqVcADwWH9WYqcMd/pQc/E7nYHh3zp6ZsMMKrtsGFNrjqH8CljQQHiOBuVLtNosuisJAe0pwOmrWYfAfSo3LsBggzMu5AG010sJr0epvz+nFname2Y0vt5BvtZ0iTcCgQ1MPUKhlGnOrjAR5vKsy1iOyDfsdu5VFCNkWfysrHd/geVzKetHRsO0+1t3M1yIeEULKdC3QFdQWVePzso+cuRHZ86MCgU117YoQdTpvPG1Wbod77wsguPfnExUbsxRpM4Z9qyJBUCLYNQrLcGopCZqNVDd1HAzDguJgdGLXaXaP2bR7ieGYP1kJKlbzN5pPIGuYab+tSV2PpvuGUvfX3EyGkJdBY+4tbs68uLbQ== 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: Utilize speculative vma lookup to find and snapshot a vma without taking mmap_lock during PROCMAP_QUERY ioctl execution. Concurrent address space modifications are detected and the lookup is retried. While we take the mmap_lock for reading during such contention, we do that momentarily only to record new mm_wr_seq counter. This change is designed to reduce mmap_lock contention and prevent PROCMAP_QUERY ioctl calls (often a low priority task, such as monitoring/data collection services) from blocking address space updates. Signed-off-by: Suren Baghdasaryan --- fs/proc/task_mmu.c | 63 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index f9d50a61167c..28b975ddff26 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -525,9 +525,53 @@ static int pid_maps_open(struct inode *inode, struct file *file) PROCMAP_QUERY_VMA_FLAGS \ ) -static int query_vma_setup(struct mm_struct *mm) +#ifdef CONFIG_PER_VMA_LOCK + +static int query_vma_setup(struct proc_maps_private *priv) { - return mmap_read_lock_killable(mm); + if (!mmap_lock_speculate_try_begin(priv->mm, &priv->mm_wr_seq)) { + int ret = mmap_read_lock_killable(priv->mm); + + if (ret) + return ret; + + /* mmap_lock_speculate_try_begin() succeeds when holding mmap_read_lock */ + mmap_lock_speculate_try_begin(priv->mm, &priv->mm_wr_seq); + mmap_read_unlock(priv->mm); + } + + memset(&priv->vma_copy, 0, sizeof(priv->vma_copy)); + rcu_read_lock(); + + return 0; +} + +static void query_vma_teardown(struct mm_struct *mm, struct vm_area_struct *vma) +{ + rcu_read_unlock(); +} + +static struct vm_area_struct *query_vma_find_by_addr(struct proc_maps_private *priv, + unsigned long addr) +{ + struct vm_area_struct *vma; + + vma_iter_init(&priv->iter, priv->mm, addr); + vma = vma_next(&priv->iter); + if (!vma) + return NULL; + + vma = get_stable_vma(vma, priv, addr); + + /* The only possible error is EINTR, just pretend we found nothing */ + return IS_ERR(vma) ? NULL : vma; +} + +#else /* CONFIG_PER_VMA_LOCK */ + +static int query_vma_setup(struct proc_maps_private *priv) +{ + return mmap_read_lock_killable(priv->mm); } static void query_vma_teardown(struct mm_struct *mm, struct vm_area_struct *vma) @@ -535,18 +579,21 @@ static void query_vma_teardown(struct mm_struct *mm, struct vm_area_struct *vma) mmap_read_unlock(mm); } -static struct vm_area_struct *query_vma_find_by_addr(struct mm_struct *mm, unsigned long addr) +static struct vm_area_struct *query_vma_find_by_addr(struct proc_maps_private *priv, + unsigned long addr) { - return find_vma(mm, addr); + return find_vma(priv->mm, addr); } -static struct vm_area_struct *query_matching_vma(struct mm_struct *mm, +#endif /* CONFIG_PER_VMA_LOCK */ + +static struct vm_area_struct *query_matching_vma(struct proc_maps_private *priv, unsigned long addr, u32 flags) { struct vm_area_struct *vma; next_vma: - vma = query_vma_find_by_addr(mm, addr); + vma = query_vma_find_by_addr(priv, addr); if (!vma) goto no_vma; @@ -622,13 +669,13 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) if (!mm || !mmget_not_zero(mm)) return -ESRCH; - err = query_vma_setup(mm); + err = query_vma_setup(priv); if (err) { mmput(mm); return err; } - vma = query_matching_vma(mm, karg.query_addr, karg.query_flags); + vma = query_matching_vma(priv, karg.query_addr, karg.query_flags); if (IS_ERR(vma)) { err = PTR_ERR(vma); vma = NULL;