Print this page
OS-881 To workaround OS-580 add support to only invalidate mappings from a single process
        
*** 19,28 ****
--- 19,29 ----
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
   * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
+  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
   */
  
  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  /*        All Rights Reserved   */
  
*** 430,441 ****
                          } else {
                                  hat_setmod_only(pp);
                                  page_io_unlock(pp);
                                  page_unlock(pp);
                          }
!                 } else if (flags & B_INVAL) {
                          /*
                           * XXX - Failed writes with B_INVAL set are
                           * not handled appropriately.
                           */
                          page_io_unlock(pp);
                          /*LINTED: constant in conditional context*/
--- 431,449 ----
                          } else {
                                  hat_setmod_only(pp);
                                  page_io_unlock(pp);
                                  page_unlock(pp);
                          }
!                 } else if ((flags & (B_INVAL | B_INVALCURONLY)) == B_INVAL) {
                          /*
+                          * If B_INVALCURONLY is set, then we handle that case
+                          * in the next conditional if hat_page_is_mapped()
+                          * indicates that there are no additional mappings
+                          * to the page.
+                          */
+ 
+                         /*
                           * XXX - Failed writes with B_INVAL set are
                           * not handled appropriately.
                           */
                          page_io_unlock(pp);
                          /*LINTED: constant in conditional context*/
*** 571,582 ****
              tnf_ulong,  pages_freed,            dfree,
              tnf_ulong,  pages_reclaimed,        pgrec);
  }
  
  /*
!  * Flags are composed of {B_ASYNC, B_INVAL, B_FREE, B_DONTNEED, B_DELWRI,
!  * B_TRUNC, B_FORCE}.  B_DELWRI indicates that this page is part of a kluster
   * operation and is only to be considered if it doesn't involve any
   * waiting here.  B_TRUNC indicates that the file is being truncated
   * and so no i/o needs to be done. B_FORCE indicates that the page
   * must be destroyed so don't try wrting it out.
   *
--- 579,591 ----
              tnf_ulong,  pages_freed,            dfree,
              tnf_ulong,  pages_reclaimed,        pgrec);
  }
  
  /*
!  * Flags are composed of {B_ASYNC, B_INVAL, B_INVALCURONLY, B_FREE,
!  * B_DONTNEED, B_DELWRI, B_TRUNC, B_FORCE}.
!  * B_DELWRI indicates that this page is part of a kluster
   * operation and is only to be considered if it doesn't involve any
   * waiting here.  B_TRUNC indicates that the file is being truncated
   * and so no i/o needs to be done. B_FORCE indicates that the page
   * must be destroyed so don't try wrting it out.
   *
*** 626,642 ****
  
          /*
           * If we want to free or invalidate the page then
           * we need to unload it so that anyone who wants
           * it will have to take a minor fault to get it.
           * Otherwise, we're just writing the page back so we
           * need to sync up the hardwre and software mod bit to
           * detect any future modifications.  We clear the
           * software mod bit when we put the page on the dirty
           * list.
           */
!         if (flags & (B_INVAL | B_FREE)) {
                  (void) hat_pageunload(pp, HAT_FORCE_PGUNLOAD);
          } else {
                  (void) hat_pagesync(pp, HAT_SYNC_ZERORM);
          }
  
--- 635,655 ----
  
          /*
           * If we want to free or invalidate the page then
           * we need to unload it so that anyone who wants
           * it will have to take a minor fault to get it.
+          * If we are only invalidating the page for the
+          * current process, then pass in a different flag.
           * Otherwise, we're just writing the page back so we
           * need to sync up the hardwre and software mod bit to
           * detect any future modifications.  We clear the
           * software mod bit when we put the page on the dirty
           * list.
           */
!         if (flags & B_INVALCURONLY) {
!                 (void) hat_pageunload(pp, HAT_CURPROC_PGUNLOAD);
!         } else if (flags & (B_INVAL | B_FREE)) {
                  (void) hat_pageunload(pp, HAT_FORCE_PGUNLOAD);
          } else {
                  (void) hat_pagesync(pp, HAT_SYNC_ZERORM);
          }
  
*** 644,654 ****
                  /*
                   * Don't need to add it to the
                   * list after all.
                   */
                  page_io_unlock(pp);
!                 if (flags & B_INVAL) {
                          /*LINTED: constant in conditional context*/
                          VN_DISPOSE(pp, B_INVAL, 0, kcred);
                  } else if (flags & B_FREE) {
                          /*LINTED: constant in conditional context*/
                          VN_DISPOSE(pp, B_FREE, (flags & B_DONTNEED), kcred);
--- 657,667 ----
                  /*
                   * Don't need to add it to the
                   * list after all.
                   */
                  page_io_unlock(pp);
!                 if ((flags & (B_INVAL | B_INVALCURONLY)) == B_INVAL) {
                          /*LINTED: constant in conditional context*/
                          VN_DISPOSE(pp, B_INVAL, 0, kcred);
                  } else if (flags & B_FREE) {
                          /*LINTED: constant in conditional context*/
                          VN_DISPOSE(pp, B_FREE, (flags & B_DONTNEED), kcred);
*** 656,665 ****
--- 669,681 ----
                          /*
                           * This is advisory path for the callers
                           * of VOP_PUTPAGE() who prefer freeing the
                           * page _only_ if no one else is accessing it.
                           * E.g. segmap_release()
+                          * We also take this path for B_INVALCURONLY and
+                          * let page_release call VN_DISPOSE if no one else is
+                          * using the page.
                           *
                           * The above hat_ismod() check is useless because:
                           * (1) we may not be holding SE_EXCL lock;
                           * (2) we've not unloaded _all_ translations
                           *
*** 680,690 ****
           * If we're going to free the page when we're done
           * then we can let others try to use it starting now.
           * We'll detect the fact that they used it when the
           * i/o is done and avoid freeing the page.
           */
!         if (flags & B_FREE)
                  page_downgrade(pp);
  
  
          TRACE_1(TR_FAC_VM, TR_PVN_GETDIRTY, "pvn_getdirty:pp %p", pp);
  
--- 696,706 ----
           * If we're going to free the page when we're done
           * then we can let others try to use it starting now.
           * We'll detect the fact that they used it when the
           * i/o is done and avoid freeing the page.
           */
!         if (flags & (B_FREE | B_INVALCURONLY))
                  page_downgrade(pp);
  
  
          TRACE_1(TR_FAC_VM, TR_PVN_GETDIRTY, "pvn_getdirty:pp %p", pp);