Print this page
12701 segspt_minfree needs right-sizing
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Patrick Mooney <pmooney@pfmooney.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/vm/seg_spt.c
          +++ new/usr/src/uts/common/vm/seg_spt.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  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) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2018 Joyent, Inc.
       23 + * Copyright 2019 Joyent, Inc.
  24   24   * Copyright (c) 2016 by Delphix. All rights reserved.
  25   25   */
  26   26  
  27   27  #include <sys/param.h>
  28   28  #include <sys/user.h>
  29   29  #include <sys/mman.h>
  30   30  #include <sys/kmem.h>
  31   31  #include <sys/sysmacros.h>
  32   32  #include <sys/cmn_err.h>
  33   33  #include <sys/systm.h>
↓ open down ↓ 19 lines elided ↑ open up ↑
  53   53  #include <sys/zone.h>
  54   54  
  55   55  #define SEGSPTADDR      (caddr_t)0x0
  56   56  
  57   57  /*
  58   58   * # pages used for spt
  59   59   */
  60   60  size_t  spt_used;
  61   61  
  62   62  /*
  63      - * segspt_minfree is the memory left for system after ISM
  64      - * locked its pages; it is set up to 5% of availrmem in
  65      - * sptcreate when ISM is created.  ISM should not use more
  66      - * than ~90% of availrmem; if it does, then the performance
  67      - * of the system may decrease. Machines with large memories may
  68      - * be able to use up more memory for ISM so we set the default
  69      - * segspt_minfree to 5% (which gives ISM max 95% of availrmem.
  70      - * If somebody wants even more memory for ISM (risking hanging
  71      - * the system) they can patch the segspt_minfree to smaller number.
       63 + * See spt_setminfree().
  72   64   */
  73   65  pgcnt_t segspt_minfree = 0;
       66 +size_t segspt_minfree_clamp = (1UL << 30); /* 1GB in bytes */
  74   67  
  75   68  static int segspt_create(struct seg **segpp, void *argsp);
  76   69  static int segspt_unmap(struct seg *seg, caddr_t raddr, size_t ssize);
  77   70  static void segspt_free(struct seg *seg);
  78   71  static void segspt_free_pages(struct seg *seg, caddr_t addr, size_t len);
  79   72  static lgrp_mem_policy_info_t *segspt_getpolicy(struct seg *seg, caddr_t addr);
  80   73  
  81   74  /* ARGSUSED */
  82   75  __NORETURN static int
  83   76  segspt_badop_dup(struct seg *seg __unused, struct seg *newseg __unused)
↓ open down ↓ 225 lines elided ↑ open up ↑
 309  302          segspt_shmcapable,
 310  303          seg_inherit_notsup
 311  304  };
 312  305  
 313  306  static void segspt_purge(struct seg *seg);
 314  307  static int segspt_reclaim(void *, caddr_t, size_t, struct page **,
 315  308                  enum seg_rw, int);
 316  309  static int spt_anon_getpages(struct seg *seg, caddr_t addr, size_t len,
 317  310                  page_t **ppa);
 318  311  
      312 +/*
      313 + * This value corresponds to headroom in availrmem that ISM can never allocate
      314 + * (but others can).  The original intent here was to prevent ISM from locking
      315 + * all of the remaining availrmem into memory, making forward progress
      316 + * difficult. It's not clear how much this matters on modern systems.
      317 + *
      318 + * The traditional default value of 5% of total memory is used, except on
      319 + * systems where that quickly gets ridiculous: in that case we clamp at a rather
      320 + * arbitrary value of 1GB.
      321 + *
      322 + * Note that since this is called lazily on the first sptcreate(), in theory,
      323 + * this could represent a very small value if the system is heavily loaded
      324 + * already. In practice, the first ISM user is pretty likely to come along
      325 + * earlier during the system's operation.
      326 + *
      327 + * This never gets re-figured.
      328 + */
      329 +static void
      330 +spt_setminfree(void)
      331 +{
      332 +        segspt_minfree = availrmem / 20;
 319  333  
      334 +        if (segspt_minfree_clamp != 0 &&
      335 +            segspt_minfree > (segspt_minfree_clamp / PAGESIZE))
      336 +                segspt_minfree = segspt_minfree_clamp / PAGESIZE;
      337 +}
 320  338  
 321      -/*ARGSUSED*/
 322  339  int
 323  340  sptcreate(size_t size, struct seg **sptseg, struct anon_map *amp,
 324  341      uint_t prot, uint_t flags, uint_t share_szc)
 325  342  {
 326  343          int     err;
 327  344          struct  as      *newas;
 328  345          struct  segspt_crargs sptcargs;
 329  346  
 330  347  #ifdef DEBUG
 331  348          TNF_PROBE_1(sptcreate, "spt", /* CSTYLED */,
 332  349                          tnf_ulong, size, size );
 333  350  #endif
 334      -        if (segspt_minfree == 0)        /* leave min 5% of availrmem for */
 335      -                segspt_minfree = availrmem/20;  /* for the system */
      351 +        if (segspt_minfree == 0)
      352 +                spt_setminfree();
 336  353  
 337  354          if (!hat_supported(HAT_SHARED_PT, (void *)0))
 338  355                  return (EINVAL);
 339  356  
 340  357          /*
 341  358           * get a new as for this shared memory segment
 342  359           */
 343  360          newas = as_alloc();
 344  361          newas->a_proc = NULL;
 345  362          sptcargs.amp = amp;
↓ open down ↓ 2895 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX