| @@ -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; |