From nobody Wed Aug 27 17:08:33 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4cBrb535qzz65KND; Wed, 27 Aug 2025 17:08:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cBrb52Bpsz3h96; Wed, 27 Aug 2025 17:08:33 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1756314513; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WrO1yMei5y9WZIZuqZiBZVWrd6Ydy9p3CloESALXtek=; b=bxqaTNxwK2NNtJRSdOdW2QzKvWqp1s+aoaLLWKF8wDRcFlmWSFNmE6hPP+TGDyPsGJ8Tes wZH8Lrv+m11inZ7Bx5NKjwzvxpQOsPC0GYnXHOpKGgOkGfE2dWkulF24/683lMhuIoFIoh 7lFzdQGlLPKRzd5QadxYbiGCa4GGjulFcPQh3rRNUWfuEs2ePcowoePjia3u9w3YyRKttQ NsEnjOsK0IPCk0slJHqGJ/qrIyzDfqu6BlO7WV6Ww9udBH2BkU4AU7fIv5P2vznhdEiN53 hwSjzwEFjWt05S+1duUsvYxWbIqXV0DT2xFssDv6zfBq48CWSdxIwjA2snx9ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1756314513; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WrO1yMei5y9WZIZuqZiBZVWrd6Ydy9p3CloESALXtek=; b=Um33XeRoVG4262HWzbYKsffmpu26KJaJSIUYRfXw0l7VdZnhvBLF+XP5q1cJUymvOsvfJP DOv+pqsushow03XE2hpCbLLNgL9tyi0OWm1OaA6elY9vv9GGTzyerZ2zQudBOH1B/2LEOn bv6773+6bj35+W9jzAffjjmJHIau42FWH6s2mULAeOl8pRdDCOEyz2mnDQ7s+MIyFsi7Vv luk/WfuD+UJEZkfe2iSVlCUofyXsMYVb+1AIfTVr9DRAiw25Oy+978c2eUdMSutWJxIh12 apUoeh6YbJniVnjPfmNNc/vbjaV+WIvHhjSGC8ByRpfCskPWW9i6prGB9YZnrg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1756314513; a=rsa-sha256; cv=none; b=JcOaBzRbjmSeeZeovMBf8NYATWu1lvB9kzCbyGW1ZJstgS7v+l6DOnnq+gWhZScefvXnvF ZSJNBip5chjO3aWHbUh5oWXBmTMl2wV65E0QcR6NTRMWlxdVnGR+Gv0cyndPQIyxb5cENl DGikdHna82nU7LuccfN70L6SWSUhXHFAVUgewCXmYxcY/TmS2fazjaVvte9R+cSmg+1TDs DmG0ZxVdSXkYOvA9hKD/kzog75lo3SQWDa4Q9DTMQTX9qH7+lpNSaTdjphwqqAt/x7/S64 M3WV41Lj/r4+uhukzBuqD/f2iz7AyBxGy51kvcsltk7hPI9R4twn6Yyq8WIqhA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4cBrb51hqczWpF; Wed, 27 Aug 2025 17:08:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 57RH8Xob078811; Wed, 27 Aug 2025 17:08:33 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 57RH8XT8078808; Wed, 27 Aug 2025 17:08:33 GMT (envelope-from git) Date: Wed, 27 Aug 2025 17:08:33 GMT Message-Id: <202508271708.57RH8XT8078808@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 041efb55ec8b - main - vm_fault: improve interface for vm_fault_quick_hold_pages() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 041efb55ec8ba4e379fd1d0a75bd0f637e3d9676 Auto-Submitted: auto-generated The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=041efb55ec8ba4e379fd1d0a75bd0f637e3d9676 commit 041efb55ec8ba4e379fd1d0a75bd0f637e3d9676 Author: Konstantin Belousov AuthorDate: 2025-08-26 15:03:10 +0000 Commit: Konstantin Belousov CommitDate: 2025-08-27 17:04:20 +0000 vm_fault: improve interface for vm_fault_quick_hold_pages() Provide (transitional) vm_fault_quick_hold_pages_e() function that returns distinguishable errors in different failure situation. Also it does not panic() on too short array case, but return an error, allowing sometimes lessen the burden of the check from the caller. vm_fault_quick_hold_pages() becomes a wrapper, that should be eliminated eventually. Reviewed by: imp, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D52165 --- sys/vm/vm_extern.h | 2 ++ sys/vm/vm_fault.c | 81 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 93ec6014c27d..053a0fdde6c2 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -93,6 +93,8 @@ int vm_fault_disable_pagefaults(void); void vm_fault_enable_pagefaults(int save); int vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, vm_prot_t prot, vm_page_t *ma, int max_count); +int vm_fault_quick_hold_pages_e(vm_map_t map, vm_offset_t addr, vm_size_t len, + vm_prot_t prot, vm_page_t *ma, int max_count, int *ppages_count); int vm_fault_trap(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, int fault_flags, int *signo, int *ucode); int vm_forkproc(struct thread *, struct proc *, struct thread *, diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 3e57e8d4f1d0..c9f84f951427 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1995,32 +1995,43 @@ vm_fault_prefault(const struct faultstate *fs, vm_offset_t addra, } /* - * Hold each of the physical pages that are mapped by the specified range of - * virtual addresses, ["addr", "addr" + "len"), if those mappings are valid - * and allow the specified types of access, "prot". If all of the implied - * pages are successfully held, then the number of held pages is returned - * together with pointers to those pages in the array "ma". However, if any - * of the pages cannot be held, -1 is returned. + * Hold each of the physical pages that are mapped by the specified + * range of virtual addresses, ["addr", "addr" + "len"), if those + * mappings are valid and allow the specified types of access, "prot". + * If all of the implied pages are successfully held, then the number + * of held pages is assigned to *ppages_count, together with pointers + * to those pages in the array "ma". The returned value is zero. + * + * However, if any of the pages cannot be held, an error is returned, + * and no pages are held. + * Error values: + * ENOMEM - the range is not valid + * EINVAL - the provided vm_page array is too small to hold all pages + * EAGAIN - a page was not mapped, and the thread is in nofaulting mode + * EFAULT - a page with requested permissions cannot be mapped + * (more detailed result from vm_fault() is lost) */ int -vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, - vm_prot_t prot, vm_page_t *ma, int max_count) +vm_fault_quick_hold_pages_e(vm_map_t map, vm_offset_t addr, vm_size_t len, + vm_prot_t prot, vm_page_t *ma, int max_count, int *ppages_count) { vm_offset_t end, va; vm_page_t *mp; - int count; + int count, error; boolean_t pmap_failed; - if (len == 0) + if (len == 0) { + *ppages_count = 0; return (0); + } end = round_page(addr + len); addr = trunc_page(addr); if (!vm_map_range_valid(map, addr, end)) - return (-1); + return (ENOMEM); if (atop(end - addr) > max_count) - panic("vm_fault_quick_hold_pages: count > max_count"); + return (EINVAL); count = atop(end - addr); /* @@ -2062,19 +2073,49 @@ vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, * the proper behaviour explicitly. */ if ((prot & VM_PROT_QUICK_NOFAULT) != 0 && - (curthread->td_pflags & TDP_NOFAULTING) != 0) - goto error; - for (mp = ma, va = addr; va < end; mp++, va += PAGE_SIZE) + (curthread->td_pflags & TDP_NOFAULTING) != 0) { + error = EAGAIN; + goto fail; + } + for (mp = ma, va = addr; va < end; mp++, va += PAGE_SIZE) { if (*mp == NULL && vm_fault(map, va, prot, - VM_FAULT_NORMAL, mp) != KERN_SUCCESS) - goto error; + VM_FAULT_NORMAL, mp) != KERN_SUCCESS) { + error = EFAULT; + goto fail; + } + } } - return (count); -error: + *ppages_count = count; + return (0); +fail: for (mp = ma; mp < ma + count; mp++) if (*mp != NULL) vm_page_unwire(*mp, PQ_INACTIVE); - return (-1); + return (error); +} + + /* + * Hold each of the physical pages that are mapped by the specified range of + * virtual addresses, ["addr", "addr" + "len"), if those mappings are valid + * and allow the specified types of access, "prot". If all of the implied + * pages are successfully held, then the number of held pages is returned + * together with pointers to those pages in the array "ma". However, if any + * of the pages cannot be held, -1 is returned. + */ +int +vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, + vm_prot_t prot, vm_page_t *ma, int max_count) +{ + int error, pages_count; + + error = vm_fault_quick_hold_pages_e(map, addr, len, prot, ma, + max_count, &pages_count); + if (error != 0) { + if (error == EINVAL) + panic("vm_fault_quick_hold_pages: count > max_count"); + return (-1); + } + return (pages_count); } /*