Fri May 15 22:27:04 2020 UTC ()
PR kern/55268: tmpfs is slow

uao_get(): in the PGO_LOCKED case, we're okay to allocate a new page as long
as the caller holds a write lock.  PGO_NOBUSY doesn't put a stop to that.


(ad)
diff -r1.139 -r1.140 src/sys/uvm/uvm_aobj.c

cvs diff -r1.139 -r1.140 src/sys/uvm/uvm_aobj.c (expand / switch to unified diff)

--- src/sys/uvm/uvm_aobj.c 2020/03/22 18:32:42 1.139
+++ src/sys/uvm/uvm_aobj.c 2020/05/15 22:27:04 1.140
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uvm_aobj.c,v 1.139 2020/03/22 18:32:42 ad Exp $ */ 1/* $NetBSD: uvm_aobj.c,v 1.140 2020/05/15 22:27:04 ad Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and 4 * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
5 * Washington University. 5 * Washington University.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * from: Id: uvm_aobj.c,v 1.1.2.5 1998/02/06 05:14:38 chs Exp 28 * from: Id: uvm_aobj.c,v 1.1.2.5 1998/02/06 05:14:38 chs Exp
29 */ 29 */
30 30
31/* 31/*
32 * uvm_aobj.c: anonymous memory uvm_object pager 32 * uvm_aobj.c: anonymous memory uvm_object pager
33 * 33 *
34 * author: Chuck Silvers <chuq@chuq.com> 34 * author: Chuck Silvers <chuq@chuq.com>
35 * started: Jan-1998 35 * started: Jan-1998
36 * 36 *
37 * - design mostly from Chuck Cranor 37 * - design mostly from Chuck Cranor
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.139 2020/03/22 18:32:42 ad Exp $"); 41__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.140 2020/05/15 22:27:04 ad Exp $");
42 42
43#ifdef _KERNEL_OPT 43#ifdef _KERNEL_OPT
44#include "opt_uvmhist.h" 44#include "opt_uvmhist.h"
45#endif 45#endif
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/systm.h> 48#include <sys/systm.h>
49#include <sys/kernel.h> 49#include <sys/kernel.h>
50#include <sys/kmem.h> 50#include <sys/kmem.h>
51#include <sys/pool.h> 51#include <sys/pool.h>
52#include <sys/atomic.h> 52#include <sys/atomic.h>
53 53
54#include <uvm/uvm.h> 54#include <uvm/uvm.h>
@@ -817,58 +817,61 @@ uao_get(struct uvm_object *uobj, voff_t  @@ -817,58 +817,61 @@ uao_get(struct uvm_object *uobj, voff_t
817 (access_type & VM_PROT_WRITE) == 0)); 817 (access_type & VM_PROT_WRITE) == 0));
818 818
819 /* 819 /*
820 * get number of pages 820 * get number of pages
821 */ 821 */
822 822
823 maxpages = *npagesp; 823 maxpages = *npagesp;
824 824
825 /* 825 /*
826 * step 1: handled the case where fault data structures are locked. 826 * step 1: handled the case where fault data structures are locked.
827 */ 827 */
828 828
829 if (flags & PGO_LOCKED) { 829 if (flags & PGO_LOCKED) {
 830 krw_t lktype = rw_lock_op(uobj->vmobjlock);
830 831
831 /* 832 /*
832 * step 1a: get pages that are already resident. only do 833 * step 1a: get pages that are already resident. only do
833 * this if the data structures are locked (i.e. the first 834 * this if the data structures are locked (i.e. the first
834 * time through). 835 * time through).
835 */ 836 */
836 837
837 done = true; /* be optimistic */ 838 done = true; /* be optimistic */
838 gotpages = 0; /* # of pages we got so far */ 839 gotpages = 0; /* # of pages we got so far */
839 for (lcv = 0, current_offset = offset ; lcv < maxpages ; 840 for (lcv = 0, current_offset = offset ; lcv < maxpages ;
840 lcv++, current_offset += PAGE_SIZE) { 841 lcv++, current_offset += PAGE_SIZE) {
841 /* do we care about this page? if not, skip it */ 842 /* do we care about this page? if not, skip it */
842 if (pps[lcv] == PGO_DONTCARE) 843 if (pps[lcv] == PGO_DONTCARE)
843 continue; 844 continue;
844 ptmp = uvm_pagelookup(uobj, current_offset); 845 ptmp = uvm_pagelookup(uobj, current_offset);
845 846
846 /* 847 /*
847 * if page is new, attempt to allocate the page, 848 * if page is new, attempt to allocate the page,
848 * zero-fill'd. we can only do this if busying 849 * zero-fill'd. we can only do this if the caller
849 * pages, as otherwise the object is read locked. 850 * holds a write lock.
850 */ 851 */
851 852
852 if ((flags & PGO_NOBUSY) == 0 && ptmp == NULL && 853 if (ptmp == NULL && lktype == RW_WRITER &&
853 uao_find_swslot(uobj, 854 uao_find_swslot(uobj,
854 current_offset >> PAGE_SHIFT) == 0) { 855 current_offset >> PAGE_SHIFT) == 0) {
855 ptmp = uao_pagealloc(uobj, current_offset, 856 ptmp = uao_pagealloc(uobj, current_offset,
856 UVM_FLAG_COLORMATCH|UVM_PGA_ZERO); 857 UVM_FLAG_COLORMATCH|UVM_PGA_ZERO);
857 if (ptmp) { 858 if (ptmp) {
858 /* new page */ 859 /* new page */
859 ptmp->flags &= ~(PG_FAKE); 860 ptmp->flags &= ~(PG_FAKE);
860 uvm_pagemarkdirty(ptmp, 861 uvm_pagemarkdirty(ptmp,
861 UVM_PAGE_STATUS_UNKNOWN); 862 UVM_PAGE_STATUS_UNKNOWN);
 863 if ((flags & PGO_NOBUSY) != 0)
 864 ptmp->flags &= ~PG_BUSY;
862 goto gotpage; 865 goto gotpage;
863 } 866 }
864 } 867 }
865 868
866 /* 869 /*
867 * to be useful must get a non-busy page 870 * to be useful must get a non-busy page
868 */ 871 */
869 872
870 if (ptmp == NULL || (ptmp->flags & PG_BUSY) != 0) { 873 if (ptmp == NULL || (ptmp->flags & PG_BUSY) != 0) {
871 if (lcv == centeridx || 874 if (lcv == centeridx ||
872 (flags & PGO_ALLPAGES) != 0) 875 (flags & PGO_ALLPAGES) != 0)
873 /* need to do a wait or I/O! */ 876 /* need to do a wait or I/O! */
874 done = false; 877 done = false;