Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/uvm PR kern/55658



details:   https://anonhg.NetBSD.org/src/rev/60de40210b57
branches:  trunk
changeset: 977187:60de40210b57
user:      rin <rin%NetBSD.org@localhost>
date:      Sun Oct 18 08:52:15 2020 +0000

description:
PR kern/55658

Revert rev 1.122:
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/uvm/uvm_bio.c#rev1.122

If this commit is applied to NFS client, changes to files in client
side are sometimes invisible in server side, which results in file
corruption.

Demonstrated by test code provided by Anthony Mallet:
https://mail-index.netbsd.org/current-users/2020/10/17/msg039708.html

Whether the test case above passes or not depends on architectures
and size of NFS I/O specified by -r and -w options of mount_nfs(8)
(the default size is 32KB for x86 and 8KB for other archs).

Whereas it fails on amd64 and i386 with the default size, it passes
on other archs (aarch64, arm, alpha, m68k, and powerpc at least) with
their default. On most ports, it fails with some I/O sizes.

However, the condition for failure is still unclear; whereas it fails
with 2KB I/O size on amiga (m68k, 8KB page), it passes with same I/O
size on alpha (8KB page). It may depends on some VM parameters or
details in pmap implementation, or some race conditions are involved.

Great thanks to Anthony Mallet for providing the test code, and sorry
everyone for breakage.

diffstat:

 sys/uvm/uvm_bio.c |  12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diffs (43 lines):

diff -r 412b9ec287ce -r 60de40210b57 sys/uvm/uvm_bio.c
--- a/sys/uvm/uvm_bio.c Sun Oct 18 08:47:54 2020 +0000
+++ b/sys/uvm/uvm_bio.c Sun Oct 18 08:52:15 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_bio.c,v 1.122 2020/10/05 04:48:23 rin Exp $        */
+/*     $NetBSD: uvm_bio.c,v 1.123 2020/10/18 08:52:15 rin Exp $        */
 
 /*
  * Copyright (c) 1998 Chuck Silvers.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_bio.c,v 1.122 2020/10/05 04:48:23 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_bio.c,v 1.123 2020/10/18 08:52:15 rin Exp $");
 
 #include "opt_uvmhist.h"
 #include "opt_ubc.h"
@@ -235,7 +235,9 @@
 ubc_fault_page(const struct uvm_faultinfo *ufi, const struct ubc_map *umap,
     struct vm_page *pg, vm_prot_t prot, vm_prot_t access_type, vaddr_t va)
 {
+       vm_prot_t mask;
        int error;
+       bool rdonly;
 
        KASSERT(rw_write_held(pg->uobject->vmobjlock));
 
@@ -278,11 +280,11 @@
            pg->offset < umap->writeoff ||
            pg->offset + PAGE_SIZE > umap->writeoff + umap->writelen);
 
-       KASSERT((access_type & VM_PROT_WRITE) == 0 ||
-           uvm_pagegetdirty(pg) != UVM_PAGE_STATUS_CLEAN);
+       rdonly = uvm_pagereadonly_p(pg);
+       mask = rdonly ? ~VM_PROT_WRITE : VM_PROT_ALL;
 
        error = pmap_enter(ufi->orig_map->pmap, va, VM_PAGE_TO_PHYS(pg),
-           prot, PMAP_CANFAIL | access_type);
+           prot & mask, PMAP_CANFAIL | (access_type & mask));
 
        uvm_pagelock(pg);
        uvm_pageactivate(pg);



Home | Main Index | Thread Index | Old Index