Print this page
OS-881 To workaround OS-580 add support to only invalidate mappings from a single process

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/vm/vm_pvn.c
          +++ new/usr/src/uts/common/vm/vm_pvn.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
       24 + * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  24   25   */
  25   26  
  26   27  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  27   28  /*        All Rights Reserved   */
  28   29  
  29   30  /*
  30   31   * University Copyright- Copyright (c) 1982, 1986, 1988
  31   32   * The Regents of the University of California
  32   33   * All Rights Reserved
  33   34   *
↓ open down ↓ 391 lines elided ↑ open up ↑
 425  426                           */
 426  427                          if ((flags & (B_INVAL|B_FORCE)) == (B_INVAL|B_FORCE)) {
 427  428                                  page_io_unlock(pp);
 428  429                                  /*LINTED: constant in conditional context*/
 429  430                                  VN_DISPOSE(pp, B_INVAL, 0, kcred);
 430  431                          } else {
 431  432                                  hat_setmod_only(pp);
 432  433                                  page_io_unlock(pp);
 433  434                                  page_unlock(pp);
 434  435                          }
 435      -                } else if (flags & B_INVAL) {
      436 +                } else if ((flags & (B_INVAL | B_INVALCURONLY)) == B_INVAL) {
 436  437                          /*
      438 +                         * If B_INVALCURONLY is set, then we handle that case
      439 +                         * in the next conditional if hat_page_is_mapped()
      440 +                         * indicates that there are no additional mappings
      441 +                         * to the page.
      442 +                         */
      443 +
      444 +                        /*
 437  445                           * XXX - Failed writes with B_INVAL set are
 438  446                           * not handled appropriately.
 439  447                           */
 440  448                          page_io_unlock(pp);
 441  449                          /*LINTED: constant in conditional context*/
 442  450                          VN_DISPOSE(pp, B_INVAL, 0, kcred);
 443  451                  } else if (flags & B_FREE ||!hat_page_is_mapped(pp)) {
 444  452                          /*
 445  453                           * Update statistics for pages being paged out
 446  454                           */
↓ open down ↓ 119 lines elided ↑ open up ↑
 566  574  
 567  575          /* Kernel probe */
 568  576          TNF_PROBE_4(pageout, "vm pageio io", /* CSTYLED */,
 569  577              tnf_opaque, vnode,                  vp,
 570  578              tnf_ulong,  pages_pageout,          pgpgout,
 571  579              tnf_ulong,  pages_freed,            dfree,
 572  580              tnf_ulong,  pages_reclaimed,        pgrec);
 573  581  }
 574  582  
 575  583  /*
 576      - * Flags are composed of {B_ASYNC, B_INVAL, B_FREE, B_DONTNEED, B_DELWRI,
 577      - * B_TRUNC, B_FORCE}.  B_DELWRI indicates that this page is part of a kluster
      584 + * Flags are composed of {B_ASYNC, B_INVAL, B_INVALCURONLY, B_FREE,
      585 + * B_DONTNEED, B_DELWRI, B_TRUNC, B_FORCE}.
      586 + * B_DELWRI indicates that this page is part of a kluster
 578  587   * operation and is only to be considered if it doesn't involve any
 579  588   * waiting here.  B_TRUNC indicates that the file is being truncated
 580  589   * and so no i/o needs to be done. B_FORCE indicates that the page
 581  590   * must be destroyed so don't try wrting it out.
 582  591   *
 583  592   * The caller must ensure that the page is locked.  Returns 1, if
 584  593   * the page should be written back (the "iolock" is held in this
 585  594   * case), or 0 if the page has been dealt with or has been
 586  595   * unlocked.
 587  596   */
↓ open down ↓ 33 lines elided ↑ open up ↑
 621  630                          return (0);
 622  631                  }
 623  632          } else {
 624  633                  page_io_lock(pp);
 625  634          }
 626  635  
 627  636          /*
 628  637           * If we want to free or invalidate the page then
 629  638           * we need to unload it so that anyone who wants
 630  639           * it will have to take a minor fault to get it.
      640 +         * If we are only invalidating the page for the
      641 +         * current process, then pass in a different flag.
 631  642           * Otherwise, we're just writing the page back so we
 632  643           * need to sync up the hardwre and software mod bit to
 633  644           * detect any future modifications.  We clear the
 634  645           * software mod bit when we put the page on the dirty
 635  646           * list.
 636  647           */
 637      -        if (flags & (B_INVAL | B_FREE)) {
      648 +        if (flags & B_INVALCURONLY) {
      649 +                (void) hat_pageunload(pp, HAT_CURPROC_PGUNLOAD);
      650 +        } else if (flags & (B_INVAL | B_FREE)) {
 638  651                  (void) hat_pageunload(pp, HAT_FORCE_PGUNLOAD);
 639  652          } else {
 640  653                  (void) hat_pagesync(pp, HAT_SYNC_ZERORM);
 641  654          }
 642  655  
 643  656          if (!hat_ismod(pp) || (flags & B_TRUNC)) {
 644  657                  /*
 645  658                   * Don't need to add it to the
 646  659                   * list after all.
 647  660                   */
 648  661                  page_io_unlock(pp);
 649      -                if (flags & B_INVAL) {
      662 +                if ((flags & (B_INVAL | B_INVALCURONLY)) == B_INVAL) {
 650  663                          /*LINTED: constant in conditional context*/
 651  664                          VN_DISPOSE(pp, B_INVAL, 0, kcred);
 652  665                  } else if (flags & B_FREE) {
 653  666                          /*LINTED: constant in conditional context*/
 654  667                          VN_DISPOSE(pp, B_FREE, (flags & B_DONTNEED), kcred);
 655  668                  } else {
 656  669                          /*
 657  670                           * This is advisory path for the callers
 658  671                           * of VOP_PUTPAGE() who prefer freeing the
 659  672                           * page _only_ if no one else is accessing it.
 660  673                           * E.g. segmap_release()
      674 +                         * We also take this path for B_INVALCURONLY and
      675 +                         * let page_release call VN_DISPOSE if no one else is
      676 +                         * using the page.
 661  677                           *
 662  678                           * The above hat_ismod() check is useless because:
 663  679                           * (1) we may not be holding SE_EXCL lock;
 664  680                           * (2) we've not unloaded _all_ translations
 665  681                           *
 666  682                           * Let page_release() do the heavy-lifting.
 667  683                           */
 668  684                          (void) page_release(pp, 1);
 669  685                  }
 670  686                  return (0);
↓ open down ↓ 4 lines elided ↑ open up ↑
 675  691           * and add page to the dirty list.
 676  692           */
 677  693          hat_clrrefmod(pp);
 678  694  
 679  695          /*
 680  696           * If we're going to free the page when we're done
 681  697           * then we can let others try to use it starting now.
 682  698           * We'll detect the fact that they used it when the
 683  699           * i/o is done and avoid freeing the page.
 684  700           */
 685      -        if (flags & B_FREE)
      701 +        if (flags & (B_FREE | B_INVALCURONLY))
 686  702                  page_downgrade(pp);
 687  703  
 688  704  
 689  705          TRACE_1(TR_FAC_VM, TR_PVN_GETDIRTY, "pvn_getdirty:pp %p", pp);
 690  706  
 691  707          return (1);
 692  708  }
 693  709  
 694  710  
 695  711  /*ARGSUSED*/
↓ open down ↓ 524 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX