From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from shelob.surriel.com (shelob.surriel.com [96.67.55.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0AC9F19C556 for ; Fri, 17 Jul 2026 17:00:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.67.55.147 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784307644; cv=none; b=tD934ClmTfwOJwRHQI+EYsFMo6TT+7eVziH3ICCW2RzBaq7R4SImN9L+EO4n1xBmf/WC/UtSmvmCUns6MZJIJXakUHHbT9iWZiE8g1+Pekb6gh8/ZpeEA6baJKHMnvz4RYk7Y6gAfk84dg8HSAMRUoR+t45yvIp96Sa22ATnZbw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784307644; c=relaxed/simple; bh=QIv5dWCUZuKVGPPpNSqHUEZ0HX0QA8NDXPijqKc0u1k=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=TcKtMmwk5IF0dBaCnL7biMt0yt9g9Sd19ZQ1RxkN9t01lNtnlbblZJiLsJ52NaItAvhgqE821Ua4Q7n3uOd3o47AQOnLSUiqO0nlF4TB1O+UVwavzMst+lIu9s8Bxw8zszsCUenBJ7coJnWvvjSmfeZQ5eCRrE7Yba3iw03X1/g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=surriel.com; spf=pass smtp.mailfrom=surriel.com; dkim=pass (2048-bit key) header.d=surriel.com header.i=@surriel.com header.b=J2fN1h2p; arc=none smtp.client-ip=96.67.55.147 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=surriel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=surriel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=surriel.com header.i=@surriel.com header.b="J2fN1h2p" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=surriel.com ; s=mail; h=Content-Transfer-Encoding:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Sender:Reply-To:Content-Type:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=WTV6N+XuYLQWmH3zDQ41ixHZSwmvPvsN1UZvS35Zb+k=; b=J2fN1h2pzqesSntyVLo7mK6urB LFylNWiNvN1EHSLKPlKiD/0/jEUxNHI5VrUEJBXwpzG37KuJNRv21FahpPBKDkemBzIbfuxDfH+88 WBG4mBW6iAUOzx1ur8A6XQD8mbUTR7SYSpJmvbqUug3zDHbiwDRkM+sePgr/rq4Tp8CPeQs3MMiuz Ta679GAXyBCifxnFJwkpj+ZblqU6Yx7zyA6qdNoXc5LvOnYdScBr4200wCeP7+LoqXWzbfPdDmUhs R9bRrXUpWdNBBRCMsNQo3mf7dBuiwHDqQyaOPjhb7ddqSGTQ5XKjn5H7Ue25J1Q8F3elRmO7GaQLZ dwDy5Z9Q==; Received: from fangorn.home.surriel.com ([10.0.13.7]) by shelob.surriel.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.97.1) (envelope-from ) id 1wklvS-000000001w4-01Ib; Fri, 17 Jul 2026 13:00:38 -0400 From: Rik van Riel To: linux-kernel@vger.kernel.org, Andrew Morton Cc: kernel-team@meta.com, Rik van Riel , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , linux-mm@kvack.org Subject: [PATCH v3 0/6] mm: access remote process memory under the per-VMA lock Date: Fri, 17 Jul 2026 13:00:30 -0400 Message-ID: <20260717170036.743149-1-riel@surriel.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit __access_remote_vm() holds mmap_read_lock() for the whole transfer. On large machines with large multi-threaded applications, the mmap_lock is often contended due to mixed accesses from readers and writers, like mmap and munmap. When a lock holder gets stuck, system monitoring software can get stuck behind that, resulting in a failure to log that the system is in trouble. Take the per-VMA lock in __access_remote_vm() when the access falls entirely within a single VMA. Fall back to the mmap lock when the access crosses a VMA boundary, or when the page cannot be reached under the per-VMA lock: a dropped fault, a userfaultfd VMA, a hard error, or memory with no struct page that has to go through vma->vm_ops->access(). The bulk of the work is a new gup helper. __access_remote_vm() needs a single page from a VMA it has already looked up and locked, faulting it in when necessary, under either lock. get_user_pages_remote() does not fit: it hard codes the mmap lock and re-derives the VMA. get_user_page_vma() walks the page tables, faults a missing page in, and returns it with a reference and the caller's lock still held. The per-VMA path also closes a pre-existing gap. A COWed page in a VM_IO/VM_PFNMAP VMA has a struct page, but the old code routed it to ->access(), where generic_access_phys() ioremaps the PFN and ioremap of RAM is rejected, so the read came up short. get_user_page_vma() now returns that page normally. Raw PFNs with no struct page still reach ->access() under the mmap lock, as before. The series is arranged as: 1-2: untag the remote address in the VMA lookup without the mmap lock, on x86 and riscv. 3: rename get_user_page_vma_remote() to get_user_page_lookup_vma(). 4: add get_user_page_vma(). 5: switch __access_remote_vm() to the per-VMA lock. 6: add selftest coverage. Changes since v2 [1]. The per-VMA fast path is reworked to build on the GUP lookup+fault path instead of a custom walker, per David Hildenbrand's and Lorenzo Stoakes' review, and now faults pages in rather than only reading resident ones. - Drop the folio_walk_start(FW_VMA_LOCKED) walk. Add get_user_page_vma() in mm/gup.c (patch 4): a trimmed __get_user_pages() that walks with follow_page_mask(), faults in with faultin_page(), and returns the page with the caller's lock held. Safe under the per-VMA lock because page tables are RCU-freed, so interrupts need not be disabled. (David) - Fault pages in on the fast path. v2 fell back to the mmap lock for any not-present page; now it falls back only on -EAGAIN. (David) - Turn the v2 READ_ONCE/WRITE_ONCE untag_mask change into an untagged_addr_remote_unlocked() helper (patch 1), and add the riscv pointer-masking equivalent (patch 2), which v2 did not cover. - Read COWed pages in VM_IO/VM_PFNMAP VMAs; raw PFNs still fall back to ->access() under the mmap lock. - Add the get_user_page_lookup_vma() rename (patch 3) and selftest coverage for the struct-page and raw-PFN paths (patch 6). [1] https://lore.kernel.org/all/20260625015053.2445008-1-riel@surriel.com/ Rik van Riel (6): x86/mm: add untagged_addr_remote_unlocked() riscv/mm: add untagged_addr_remote_unlocked() mm: rename get_user_page_vma_remote() to get_user_page_lookup_vma() mm/gup: add get_user_page_vma() to fault in a page under a held lock mm: use per-VMA lock in __access_remote_vm() for single-VMA accesses selftests/mm: cover /proc/pid/mem access to VM_PFNMAP memory arch/arm64/kernel/mte.c | 2 +- arch/riscv/include/asm/mmu_context.h | 4 +- arch/riscv/include/asm/uaccess.h | 10 +- arch/riscv/kernel/process.c | 12 +- arch/x86/include/asm/mmu_context.h | 6 +- arch/x86/include/asm/uaccess_64.h | 14 ++- arch/x86/kernel/process_64.c | 4 +- arch/x86/kernel/uprobes.c | 2 +- include/linux/mm.h | 2 +- include/linux/uaccess.h | 7 ++ mm/gup.c | 156 ++++++++++++++++++++++---- mm/internal.h | 7 +- mm/memory.c | 171 ++++++++++++++++++++------- mm/rmap.c | 2 +- tools/testing/selftests/mm/pfnmap.c | 66 +++++++++++ 15 files changed, 375 insertions(+), 90 deletions(-) base-commit: 0f26556c5eeea62cc934fa8938b148aa5844a6b6 -- 2.47.0