From patchwork Mon Nov 7 18:47:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pasha Tatashin X-Patchwork-Id: 13035114 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 A6951C433FE for ; Mon, 7 Nov 2022 18:47:21 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 44D6E6B0071; Mon, 7 Nov 2022 13:47:21 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 3FDB26B0072; Mon, 7 Nov 2022 13:47:21 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2C5DC8E0001; Mon, 7 Nov 2022 13:47:21 -0500 (EST) 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 1E4556B0071 for ; Mon, 7 Nov 2022 13:47:21 -0500 (EST) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id DB3C24082D for ; Mon, 7 Nov 2022 18:47:20 +0000 (UTC) X-FDA: 80107529040.27.0870D07 Received: from mail-qt1-f174.google.com (mail-qt1-f174.google.com [209.85.160.174]) by imf26.hostedemail.com (Postfix) with ESMTP id 53385140008 for ; Mon, 7 Nov 2022 18:47:20 +0000 (UTC) Received: by mail-qt1-f174.google.com with SMTP id hh9so7379344qtb.13 for ; Mon, 07 Nov 2022 10:47:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=Lj2j2IowLRClh2CPK+1bgXAKaDYVWiVJ2biJrtBrjjs=; b=fAsxNpKqKfjlLu6qyaCUUsQ6rgzXrse5vGKTil+8bXk5cFvSQ6jD5lq6WuyaLZDydJ TrFSoxBtyaN6K68JJsrqntKcnCbm9BsA7xgOMU90mwKvLKC2oyLQ4p0Mi7teerV7EMWZ ZHsI0H6iaqFs63tPj46T4LVKPCzLMfx0GotpVLIO9u2f0jEGNMEpQ05AYjUEn37cWMnJ v8ptvlt23NbMCLTphQQi0fpn7DbbfscEsUxz0lEKrrW7q+6yi6ETrYqdEffF83R4Rid1 0qXLNdkQwo5ommzLS/5z0LfIKIjShEyNG9AV77dtGO4kW2exnkQNIHwC+E5Hx9vTFJ/9 /8FA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Lj2j2IowLRClh2CPK+1bgXAKaDYVWiVJ2biJrtBrjjs=; b=GSyVuYhT0OeS8zi1GLse5zltdGo+btDw6mKB06aNw3BFerd05ENqhd7xPSoIICWkUa YQmMuE5JK/v1DOvDjPg5l/6cJwqhZRRMyBXvSjr6KgA8I/S2mY1D3ts0zaINfsoNl6xd Nac1m8ZQZe/8iSQIm2wecxRsT9su2qO/rspCea9olF+XKaGFdqJseIMQskLVBzQ2UKpm 4z/uKjxAClMfQm9vabOjb4yl2i5AlukZJYMEnGjp6MDCQuMYBdkOQF/GYZbTdKglG+br PpnVcJ+2MSowETGiuc9GHJx1OdUww76zxJQnX9DlqLijknG7woT/hyJEV7p42GhK5p6u qAfA== X-Gm-Message-State: ACrzQf1Grbn+DDf2HSk5qMjbOoh80MgSXDo+QqRCpQi6NzIoY1kKFXKc 5CYuwk8DllYHTfBCf4vXyyKrbw== X-Google-Smtp-Source: AMsMyM7oIXCqWPDxi3Itwk4RPx2dR7Dbzk5iWTr+mBkmB1MCZBfwAw0s/XVQc8Gc17pUawEm8yzI1w== X-Received: by 2002:ac8:71c7:0:b0:3a5:4cb1:7baa with SMTP id i7-20020ac871c7000000b003a54cb17baamr21357905qtp.303.1667846839395; Mon, 07 Nov 2022 10:47:19 -0800 (PST) Received: from soleen.c.googlers.com.com (193.132.150.34.bc.googleusercontent.com. [34.150.132.193]) by smtp.gmail.com with ESMTPSA id t17-20020a05622a149100b0039ee562799csm6638167qtx.59.2022.11.07.10.47.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Nov 2022 10:47:18 -0800 (PST) From: Pasha Tatashin To: corbet@lwn.net, akpm@linux-foundation.org, hughd@google.com, hannes@cmpxchg.org, david@redhat.com, vincent.whitchurch@axis.com, seanjc@google.com, rppt@kernel.org, shy828301@gmail.com, pasha.tatashin@soleen.com, paul.gortmaker@windriver.com, peterx@redhat.com, vbabka@suse.cz, Liam.Howlett@Oracle.com, ccross@google.com, willy@infradead.org, arnd@arndb.de, cgel.zte@gmail.com, yuzhao@google.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, bagasdotme@gmail.com, kirill@shutemov.name Subject: [PATCH v2] mm: anonymous shared memory naming Date: Mon, 7 Nov 2022 18:47:15 +0000 Message-Id: <20221107184715.3950621-1-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog MIME-Version: 1.0 ARC-Authentication-Results: i=1; imf26.hostedemail.com; dkim=pass header.d=soleen.com header.s=google header.b=fAsxNpKq; spf=pass (imf26.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.160.174 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=none ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1667846840; a=rsa-sha256; cv=none; b=Oo6ZVxozEbAI8PIWpyj11bd9J7+t7V+j896HCz6vYSzjLwMY7269nCgU66zx469Lvf9qo1 Ako2jHuobtbk+UJcGfJ1qfWaZoS/+5oIIdFOGCa88e2e38t3+H6kSs/AE2A4iSvM3IlPgi eUdVl0W9YpMrPKf13RcXVDjpqNNYNVg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1667846840; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references:dkim-signature; bh=Lj2j2IowLRClh2CPK+1bgXAKaDYVWiVJ2biJrtBrjjs=; b=xjL6ec2mJ9poPoNJFGUMkfhAXdIwIPQv2xDd+7vewTz2Ryc9fB7VyBt/iX0SyP/FR1pwF4 LXK3ucSFd1cf/J8oI+L7drqALUY5e/8NCYHg6j1o8ho9OO6EGeVXrNDFrVNBjqm67Gzg6f fizvOGH298UcNfCmUUztbB5I/0oeEhQ= X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 53385140008 Authentication-Results: imf26.hostedemail.com; dkim=pass header.d=soleen.com header.s=google header.b=fAsxNpKq; spf=pass (imf26.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.160.174 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=none X-Stat-Signature: g78j9bogprw1it6zugxpzofcqec7ftxc X-Rspam-User: X-HE-Tag: 1667846840-552103 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: Since: commit 9a10064f5625 ("mm: add a field to store names for private anonymous memory"), name for private anonymous memory, but not shared anonymous, can be set. However, naming shared anonymous memory just as useful for tracking purposes. Extend the functionality to be able to set names for shared anon. Sample output: /* Create shared anonymous segmenet */ anon_shmem = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); /* Name the segment: "MY-NAME" */ rv = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, anon_shmem, SIZE, "MY-NAME"); cat /proc//maps (and smaps): 7fc8e2b4c000-7fc8f2b4c000 rw-s 00000000 00:01 1024 [anon_shmem:MY-NAME] Signed-off-by: Pasha Tatashin Acked-by: David Hildenbrand --- Documentation/filesystems/proc.rst | 8 +++++--- fs/proc/task_mmu.c | 14 ++++++++++---- include/linux/mm.h | 2 ++ include/linux/mm_types.h | 27 +++++++++++++-------------- mm/madvise.c | 7 ++----- mm/shmem.c | 20 ++++++++++++++++++-- 6 files changed, 50 insertions(+), 28 deletions(-) Changes since v1: https://lore.kernel.org/lkml/20221105025342.3130038-1-pasha.tatashin@soleen.com - removed "path" for user named anon shared memory - fixed a warning found by kernel test robot - fixed a warning reported by Bagas Sanjaya - simplified and improved the commit log diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst index 898c99eae8e4..b8f175ae4853 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -426,14 +426,16 @@ with the memory region, as the case would be with BSS (uninitialized data). The "pathname" shows the name associated file for this mapping. If the mapping is not associated with a file: - ============= ==================================== + =================== =========================================== [heap] the heap of the program [stack] the stack of the main process [vdso] the "virtual dynamic shared object", the kernel system call handler - [anon:] an anonymous mapping that has been + [anon:] a private anonymous mapping that has been named by userspace - ============= ==================================== + [anon_shmem:] an anonymous shared memory mapping that has + been named by userspace + =================== =========================================== or if empty, the mapping is anonymous. diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 8a74cdcc9af0..d22687d2e81e 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -277,6 +277,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) struct mm_struct *mm = vma->vm_mm; struct file *file = vma->vm_file; vm_flags_t flags = vma->vm_flags; + struct anon_vma_name *anon_name; unsigned long ino = 0; unsigned long long pgoff = 0; unsigned long start, end; @@ -293,6 +294,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) start = vma->vm_start; end = vma->vm_end; show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino); + anon_name = anon_vma_name(vma); /* * Print the dentry name for named mappings, and a @@ -300,7 +302,14 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) */ if (file) { seq_pad(m, ' '); - seq_file_path(m, file, "\n"); + /* + * If user named this anon shared memory via + * prctl(PR_SET_VMA ..., use the provided name. + */ + if (anon_name) + seq_printf(m, "[anon_shmem:%s]", anon_name->name); + else + seq_file_path(m, file, "\n"); goto done; } @@ -312,8 +321,6 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) name = arch_vma_name(vma); if (!name) { - struct anon_vma_name *anon_name; - if (!mm) { name = "[vdso]"; goto done; @@ -330,7 +337,6 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) goto done; } - anon_name = anon_vma_name(vma); if (anon_name) { seq_pad(m, ' '); seq_printf(m, "[anon:%s]", anon_name->name); diff --git a/include/linux/mm.h b/include/linux/mm.h index 8bbcccbc5565..06b6fb3277ab 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -699,8 +699,10 @@ static inline unsigned long vma_iter_addr(struct vma_iterator *vmi) * paths in userfault. */ bool vma_is_shmem(struct vm_area_struct *vma); +bool vma_is_anon_shmem(struct vm_area_struct *vma); #else static inline bool vma_is_shmem(struct vm_area_struct *vma) { return false; } +static inline bool vma_is_anon_shmem(struct vm_area_struct *vma) { return false; } #endif int vma_is_stack_for_current(struct vm_area_struct *vma); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 500e536796ca..08d8b973fb60 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -461,21 +461,11 @@ struct vm_area_struct { * For areas with an address space and backing store, * linkage into the address_space->i_mmap interval tree. * - * For private anonymous mappings, a pointer to a null terminated string - * containing the name given to the vma, or NULL if unnamed. */ - - union { - struct { - struct rb_node rb; - unsigned long rb_subtree_last; - } shared; - /* - * Serialized by mmap_sem. Never use directly because it is - * valid only when vm_file is NULL. Use anon_vma_name instead. - */ - struct anon_vma_name *anon_name; - }; + struct { + struct rb_node rb; + unsigned long rb_subtree_last; + } shared; /* * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma @@ -485,6 +475,7 @@ struct vm_area_struct { */ struct list_head anon_vma_chain; /* Serialized by mmap_lock & * page_table_lock */ + struct anon_vma *anon_vma; /* Serialized by page_table_lock */ /* Function pointers to deal with this struct. */ @@ -496,6 +487,14 @@ struct vm_area_struct { struct file * vm_file; /* File we map to (can be NULL). */ void * vm_private_data; /* was vm_pte (shared mem) */ +#ifdef CONFIG_ANON_VMA_NAME + /* + * For private and shared anonymous mappings, a pointer to a null + * terminated string containing the name given to the vma, or NULL if + * unnamed. Serialized by mmap_sem. Use anon_vma_name to access. + */ + struct anon_vma_name *anon_name; +#endif #ifdef CONFIG_SWAP atomic_long_t swap_readahead_info; #endif diff --git a/mm/madvise.c b/mm/madvise.c index c7105ec6d08c..255d5b485432 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -95,9 +95,6 @@ struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma) { mmap_assert_locked(vma->vm_mm); - if (vma->vm_file) - return NULL; - return vma->anon_name; } @@ -183,7 +180,7 @@ static int madvise_update_vma(struct vm_area_struct *vma, * vm_flags is protected by the mmap_lock held in write mode. */ vma->vm_flags = new_flags; - if (!vma->vm_file) { + if (!vma->vm_file || vma_is_anon_shmem(vma)) { error = replace_anon_vma_name(vma, anon_name); if (error) return error; @@ -1273,7 +1270,7 @@ static int madvise_vma_anon_name(struct vm_area_struct *vma, int error; /* Only anonymous mappings can be named */ - if (vma->vm_file) + if (vma->vm_file && !vma_is_anon_shmem(vma)) return -EBADF; error = madvise_update_vma(vma, prev, start, end, vma->vm_flags, diff --git a/mm/shmem.c b/mm/shmem.c index c1d8b8a1aa3b..a6482cadda79 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -237,11 +237,17 @@ static const struct inode_operations shmem_inode_operations; static const struct inode_operations shmem_dir_inode_operations; static const struct inode_operations shmem_special_inode_operations; static const struct vm_operations_struct shmem_vm_ops; +static const struct vm_operations_struct shmem_anon_vm_ops; static struct file_system_type shmem_fs_type; +bool vma_is_anon_shmem(struct vm_area_struct *vma) +{ + return vma->vm_ops == &shmem_anon_vm_ops; +} + bool vma_is_shmem(struct vm_area_struct *vma) { - return vma->vm_ops == &shmem_vm_ops; + return vma_is_anon_shmem(vma) || vma->vm_ops == &shmem_vm_ops; } static LIST_HEAD(shmem_swaplist); @@ -3995,6 +4001,15 @@ static const struct vm_operations_struct shmem_vm_ops = { #endif }; +static const struct vm_operations_struct shmem_anon_vm_ops = { + .fault = shmem_fault, + .map_pages = filemap_map_pages, +#ifdef CONFIG_NUMA + .set_policy = shmem_set_policy, + .get_policy = shmem_get_policy, +#endif +}; + int shmem_init_fs_context(struct fs_context *fc) { struct shmem_options *ctx; @@ -4170,6 +4185,7 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend) EXPORT_SYMBOL_GPL(shmem_truncate_range); #define shmem_vm_ops generic_file_vm_ops +#define shmem_anon_vm_ops generic_file_vm_ops #define shmem_file_operations ramfs_file_operations #define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev) #define shmem_acct_size(flags, size) 0 @@ -4275,7 +4291,7 @@ int shmem_zero_setup(struct vm_area_struct *vma) if (vma->vm_file) fput(vma->vm_file); vma->vm_file = file; - vma->vm_ops = &shmem_vm_ops; + vma->vm_ops = &shmem_anon_vm_ops; return 0; }