From owner-svn-src-all@freebsd.org Sun Dec 15 02:00:33 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9C1551DE0C3; Sun, 15 Dec 2019 02:00:33 +0000 (UTC) (envelope-from jeff@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) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47b70K3k8gz40sp; Sun, 15 Dec 2019 02:00:33 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7B1A55F5A; Sun, 15 Dec 2019 02:00:33 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xBF20XNs046766; Sun, 15 Dec 2019 02:00:33 GMT (envelope-from jeff@FreeBSD.org) Received: (from jeff@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xBF20Xd8046764; Sun, 15 Dec 2019 02:00:33 GMT (envelope-from jeff@FreeBSD.org) Message-Id: <201912150200.xBF20Xd8046764@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jeff set sender to jeff@FreeBSD.org using -f From: Jeff Roberson Date: Sun, 15 Dec 2019 02:00:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355763 - in head/sys: kern vm X-SVN-Group: head X-SVN-Commit-Author: jeff X-SVN-Commit-Paths: in head/sys: kern vm X-SVN-Commit-Revision: 355763 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Dec 2019 02:00:33 -0000 Author: jeff Date: Sun Dec 15 02:00:32 2019 New Revision: 355763 URL: https://svnweb.freebsd.org/changeset/base/355763 Log: Handle pagein clustering in vm_page_grab_valid() so that it can be used by exec_map_first_page(). This will also enable pagein clustering for other interested consumers (tmpfs, md, etc). Discussed with: alc Approved by: kib Differential Revision: https://reviews.freebsd.org/D22731 Modified: head/sys/kern/kern_exec.c head/sys/vm/vm_page.c Modified: head/sys/kern/kern_exec.c ============================================================================== --- head/sys/kern/kern_exec.c Sun Dec 15 01:56:56 2019 (r355762) +++ head/sys/kern/kern_exec.c Sun Dec 15 02:00:32 2019 (r355763) @@ -974,9 +974,9 @@ exec_fail: int exec_map_first_page(struct image_params *imgp) { - int rv, i, after, initial_pagein; - vm_page_t ma[VM_INITIAL_PAGEIN]; vm_object_t object; + vm_page_t m; + int error; if (imgp->firstpage != NULL) exec_unmap_first_page(imgp); @@ -988,68 +988,14 @@ exec_map_first_page(struct image_params *imgp) #if VM_NRESERVLEVEL > 0 vm_object_color(object, 0); #endif -retry: - ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | - VM_ALLOC_WIRED); - if (!vm_page_all_valid(ma[0])) { - if (vm_page_busy_acquire(ma[0], VM_ALLOC_WAITFAIL) == 0) { - vm_page_unwire_noq(ma[0]); - goto retry; - } - if (vm_page_all_valid(ma[0])) { - vm_page_xunbusy(ma[0]); - goto out; - } - if (!vm_pager_has_page(object, 0, NULL, &after)) { - if (vm_page_unwire_noq(ma[0])) - vm_page_free(ma[0]); - else - vm_page_xunbusy(ma[0]); - VM_OBJECT_WUNLOCK(object); - return (EIO); - } - initial_pagein = min(after, VM_INITIAL_PAGEIN); - KASSERT(initial_pagein <= object->size, - ("%s: initial_pagein %d object->size %ju", - __func__, initial_pagein, (uintmax_t )object->size)); - for (i = 1; i < initial_pagein; i++) { - if ((ma[i] = vm_page_next(ma[i - 1])) != NULL) { - if (ma[i]->valid) - break; - if (!vm_page_tryxbusy(ma[i])) - break; - } else { - ma[i] = vm_page_alloc(object, i, - VM_ALLOC_NORMAL); - if (ma[i] == NULL) - break; - } - } - initial_pagein = i; - rv = vm_pager_get_pages(object, ma, initial_pagein, NULL, NULL); - if (rv != VM_PAGER_OK) { - if (vm_page_unwire_noq(ma[0])) - vm_page_free(ma[0]); - else - vm_page_xunbusy(ma[0]); - for (i = 1; i < initial_pagein; i++) { - if (!vm_page_wired(ma[i])) - vm_page_free(ma[i]); - else - vm_page_xunbusy(ma[i]); - } - VM_OBJECT_WUNLOCK(object); - return (EIO); - } - vm_page_xunbusy(ma[0]); - for (i = 1; i < initial_pagein; i++) - vm_page_readahead_finish(ma[i]); - } - -out: + error = vm_page_grab_valid(&m, object, 0, + VM_ALLOC_COUNT(VM_INITIAL_PAGEIN) | + VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | VM_ALLOC_WIRED); VM_OBJECT_WUNLOCK(object); - imgp->firstpage = sf_buf_alloc(ma[0], 0); + if (error != VM_PAGER_OK) + return (EIO); + imgp->firstpage = sf_buf_alloc(m, 0); imgp->image_header = (char *)sf_buf_kva(imgp->firstpage); return (0); Modified: head/sys/vm/vm_page.c ============================================================================== --- head/sys/vm/vm_page.c Sun Dec 15 01:56:56 2019 (r355762) +++ head/sys/vm/vm_page.c Sun Dec 15 02:00:32 2019 (r355763) @@ -4333,15 +4333,18 @@ out: /* * Grab a page and make it valid, paging in if necessary. Pages missing from - * their pager are zero filled and validated. + * their pager are zero filled and validated. If a VM_ALLOC_COUNT is supplied + * and the page is not valid as many as VM_INITIAL_PAGEIN pages can be brought + * in simultaneously. Additional pages will be left on a paging queue but + * will neither be wired nor busy regardless of allocflags. */ int vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, int allocflags) { vm_page_t m; + vm_page_t ma[VM_INITIAL_PAGEIN]; bool sleep, xbusy; - int pflags; - int rv; + int after, i, pflags, rv; KASSERT((allocflags & VM_ALLOC_SBUSY) == 0 || (allocflags & VM_ALLOC_IGN_SBUSY) != 0, @@ -4400,15 +4403,40 @@ retrylookup: vm_page_assert_xbusied(m); MPASS(xbusy); - if (vm_pager_has_page(object, pindex, NULL, NULL)) { - rv = vm_pager_get_pages(object, &m, 1, NULL, NULL); + if (vm_pager_has_page(object, pindex, NULL, &after)) { + after = MIN(after, VM_INITIAL_PAGEIN); + after = MIN(after, allocflags >> VM_ALLOC_COUNT_SHIFT); + after = MAX(after, 1); + ma[0] = m; + for (i = 1; i < after; i++) { + if ((ma[i] = vm_page_next(ma[i - 1])) != NULL) { + if (ma[i]->valid || !vm_page_tryxbusy(ma[i])) + break; + } else { + ma[i] = vm_page_alloc(object, m->pindex + i, + VM_ALLOC_NORMAL); + if (ma[i] == NULL) + break; + } + } + after = i; + rv = vm_pager_get_pages(object, ma, after, NULL, NULL); + /* Pager may have replaced a page. */ + m = ma[0]; if (rv != VM_PAGER_OK) { - if (allocflags & VM_ALLOC_WIRED) + if ((allocflags & VM_ALLOC_WIRED) != 0) vm_page_unwire_noq(m); - vm_page_free(m); + for (i = 0; i < after; i++) { + if (!vm_page_wired(ma[i])) + vm_page_free(ma[i]); + else + vm_page_xunbusy(ma[i]); + } *mp = NULL; return (rv); } + for (i = 1; i < after; i++) + vm_page_readahead_finish(ma[i]); MPASS(vm_page_all_valid(m)); } else { vm_page_zero_invalid(m, TRUE);