]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/vm/vnode_pager.c
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / bsd / vm / vnode_pager.c
index 0a9075c05ff87faba7bab90b59f3d222d32dda54..b4d6d6fc64792c56b69765c15d97f036718b1aeb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -65,7 +65,6 @@
 #include <vm/vm_map.h>
 #include <vm/vm_kern.h>
 #include <kern/zalloc.h>
-#include <kern/kalloc.h>
 #include <libkern/libkern.h>
 
 #include <vm/vnode_pager.h>
@@ -83,7 +82,7 @@
 #include <vfs/vfs_disk_conditioner.h>
 
 void
-vnode_pager_throttle()
+vnode_pager_throttle(void)
 {
        struct uthread *ut;
 
@@ -122,7 +121,7 @@ vnode_pager_issue_reprioritize_io(struct vnode *devvp, uint64_t blkno, uint32_t
 
        set_tier.extents = &extent;
        set_tier.extentsCount = 1;
-       set_tier.tier = priority;
+       set_tier.tier = (uint8_t)priority;
 
        error = VNOP_IOCTL(devvp, DKIOCSETTIER, (caddr_t)&set_tier, 0, vfs_context_kernel());
        return;
@@ -312,6 +311,26 @@ vnode_pageout(struct vnode *vp,
 
        isize = (int)size;
 
+       /*
+        * This call is non-blocking and does not ever fail but it can
+        * only be made when there is other explicit synchronization
+        * with reclaiming of the vnode which, in this path, is provided
+        * by the paging in progress counter.
+        *
+        * In addition, this may also be entered via explicit ubc_msync
+        * calls or vm_swapfile_io where the existing iocount provides
+        * the necessary synchronization. Ideally we would not take an
+        * additional iocount here in the cases where an explcit iocount
+        * has already been taken but this call doesn't cause a deadlock
+        * as other forms of vnode_get* might if this thread has already
+        * taken an iocount.
+        */
+       error = vnode_getalways_from_pager(vp);
+       if (error != 0) {
+               /* This can't happen */
+               panic("vnode_getalways returned %d for vp %p", error, vp);
+       }
+
        if (isize <= 0) {
                result    = PAGER_ERROR;
                error_ret = EINVAL;
@@ -549,6 +568,8 @@ vnode_pageout(struct vnode *vp,
                pg_index += num_of_pages;
        }
 out:
+       vnode_put_from_pager(vp);
+
        if (errorp) {
                *errorp = error_ret;
        }
@@ -586,6 +607,25 @@ vnode_pagein(
                ignore_valid_page_check = 1;
        }
 
+       /*
+        * This call is non-blocking and does not ever fail but it can
+        * only be made when there is other explicit synchronization
+        * with reclaiming of the vnode which, in this path, is provided
+        * by the paging in progress counter.
+        *
+        * In addition, this may also be entered via vm_swapfile_io
+        * where the existing iocount provides the necessary synchronization.
+        * Ideally we would not take an additional iocount here in the cases
+        * where an explcit iocount has already been taken but this call
+        * doesn't cause a deadlock as other forms of vnode_get* might if
+        * this thread has already taken an iocount.
+        */
+       error = vnode_getalways_from_pager(vp);
+       if (error != 0) {
+               /* This can't happen */
+               panic("vnode_getalways returned %d for vp %p", error, vp);
+       }
+
        if (UBCINFOEXISTS(vp) == 0) {
                result = PAGER_ERROR;
                error  = PAGER_ERROR;
@@ -770,6 +810,8 @@ vnode_pagein(
                }
        }
 out:
+       vnode_put_from_pager(vp);
+
        if (errorp) {
                *errorp = result;
        }