Print this page
    
OS-3088 need a lighterweight page invalidation mechanism for zone memcap
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/syscall/rusagesys.c
          +++ new/usr/src/uts/common/syscall/rusagesys.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ 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 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + * Copyright 2014 Joyent, Inc.  All rights reserved.
  24   25   */
  25   26  
  26   27  /*
  27   28   * Implement fast getrusage call
  28   29   */
  29   30  
  30   31  #include <sys/types.h>
  31   32  #include <sys/systm.h>
  32   33  #include <sys/time.h>
  33   34  #include <sys/errno.h>
  34   35  #include <sys/resource.h>
  35   36  #include <sys/vm_usage.h>
  36   37  
  37   38  static int
  38   39  getrusage(void *user_rusage)
  39   40  {
  40   41          struct rusage r;
  41   42          kthread_t *t = curthread;
  42   43          proc_t *p = ttoproc(t);
  43   44          hrtime_t snsecs, unsecs;
  44   45          klwp_t *lwp;
  45   46  
  46   47          bzero(&r, sizeof (struct rusage));
  47   48  
  48   49          mutex_enter(&p->p_lock);
  49   50  
  50   51          if (p->p_defunct > 0) {
  51   52                  r.ru_majflt     = p->p_ru.majflt;
  52   53                  r.ru_minflt     = p->p_ru.minflt;
  53   54                  r.ru_nswap      = p->p_ru.nswap;
  54   55                  r.ru_inblock    = p->p_ru.inblock;
  55   56                  r.ru_oublock    = p->p_ru.oublock;
  56   57                  r.ru_msgsnd     = p->p_ru.msgsnd;
  57   58                  r.ru_msgrcv     = p->p_ru.msgrcv;
  58   59                  r.ru_nsignals   = p->p_ru.nsignals;
  59   60                  r.ru_nvcsw      = p->p_ru.nvcsw;
  60   61                  r.ru_nivcsw     = p->p_ru.nivcsw;
  61   62          }
  62   63  
  63   64          unsecs = mstate_aggr_state(p, LMS_USER);
  64   65          snsecs = mstate_aggr_state(p, LMS_SYSTEM);
  65   66  
  66   67          do {
  67   68                  if (t->t_proc_flag & TP_LWPEXIT)
  68   69                          continue;
  69   70  
  70   71                  lwp = ttolwp(t);
  71   72  
  72   73                  r.ru_majflt     += lwp->lwp_ru.majflt;
  73   74                  r.ru_minflt     += lwp->lwp_ru.minflt;
  74   75                  r.ru_nswap      += lwp->lwp_ru.nswap;
  75   76                  r.ru_inblock    += lwp->lwp_ru.inblock;
  76   77                  r.ru_oublock    += lwp->lwp_ru.oublock;
  77   78                  r.ru_msgsnd     += lwp->lwp_ru.msgsnd;
  78   79                  r.ru_msgrcv     += lwp->lwp_ru.msgrcv;
  79   80                  r.ru_nsignals   += lwp->lwp_ru.nsignals;
  80   81                  r.ru_nvcsw      += lwp->lwp_ru.nvcsw;
  81   82                  r.ru_nivcsw     += lwp->lwp_ru.nivcsw;
  82   83  
  83   84          } while ((t = t->t_forw) != curthread);
  84   85  
  85   86          mutex_exit(&p->p_lock);
  86   87  
  87   88          hrt2tv(unsecs, &r.ru_utime);
  88   89          hrt2tv(snsecs, &r.ru_stime);
  89   90  
  90   91  #ifdef _SYSCALL32_IMPL
  91   92          if (get_udatamodel() == DATAMODEL_ILP32) {
  92   93                  struct rusage32 r32;
  93   94  
  94   95                  bzero(&r32, sizeof (struct rusage32));
  95   96  
  96   97                  r32.ru_utime.tv_sec  = r.ru_utime.tv_sec;
  97   98                  r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
  98   99                  r32.ru_stime.tv_sec  = r.ru_stime.tv_sec;
  99  100                  r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
 100  101  
 101  102                  r32.ru_majflt   = (int32_t)r.ru_majflt;
 102  103                  r32.ru_minflt   = (int32_t)r.ru_minflt;
 103  104                  r32.ru_nswap    = (int32_t)r.ru_nswap;
 104  105                  r32.ru_inblock  = (int32_t)r.ru_inblock;
 105  106                  r32.ru_oublock  = (int32_t)r.ru_oublock;
 106  107                  r32.ru_msgsnd   = (int32_t)r.ru_msgsnd;
 107  108                  r32.ru_msgrcv   = (int32_t)r.ru_msgrcv;
 108  109                  r32.ru_nsignals = (int32_t)r.ru_nsignals;
 109  110                  r32.ru_nvcsw    = (int32_t)r.ru_nvcsw;
 110  111                  r32.ru_nivcsw   = (int32_t)r.ru_nivcsw;
 111  112                  if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
 112  113                          return (set_errno(EFAULT));
 113  114          } else
 114  115  #endif /* _SYSCALL32_IMPL */
 115  116  
 116  117                  if (copyout(&r, user_rusage, sizeof (r)) != 0)
 117  118                          return (set_errno(EFAULT));
 118  119  
 119  120          return (0);
 120  121  }
 121  122  
 122  123  static int
 123  124  getrusage_chld(void *user_rusage)
 124  125  {
 125  126          struct rusage r;
 126  127          kthread_t *t = curthread;
 127  128          proc_t *p = ttoproc(t);
 128  129          hrtime_t snsecs, unsecs;
 129  130  
 130  131          bzero(&r, sizeof (struct rusage));
 131  132  
 132  133          mutex_enter(&p->p_lock);
 133  134  
 134  135          unsecs = p->p_cacct[LMS_USER];
 135  136          snsecs = p->p_cacct[LMS_SYSTEM] + p->p_cacct[LMS_TRAP];
 136  137  
 137  138          r.ru_majflt     = p->p_cru.majflt;
 138  139          r.ru_minflt     = p->p_cru.minflt;
 139  140          r.ru_nswap      = p->p_cru.nswap;
 140  141          r.ru_inblock    = p->p_cru.inblock;
 141  142          r.ru_oublock    = p->p_cru.oublock;
 142  143          r.ru_msgsnd     = p->p_cru.msgsnd;
 143  144          r.ru_msgrcv     = p->p_cru.msgrcv;
 144  145          r.ru_nsignals   = p->p_cru.nsignals;
 145  146          r.ru_nvcsw      = p->p_cru.nvcsw;
 146  147          r.ru_nivcsw     = p->p_cru.nivcsw;
 147  148  
 148  149          mutex_exit(&p->p_lock);
 149  150  
 150  151          hrt2tv(unsecs, &r.ru_utime);
 151  152          hrt2tv(snsecs, &r.ru_stime);
 152  153  #ifdef _SYSCALL32_IMPL
 153  154          if (get_udatamodel() == DATAMODEL_ILP32) {
 154  155                  struct rusage32 r32;
 155  156  
 156  157                  bzero(&r32, sizeof (struct rusage32));
 157  158  
 158  159                  r32.ru_utime.tv_sec  = r.ru_utime.tv_sec;
 159  160                  r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
 160  161                  r32.ru_stime.tv_sec  = r.ru_stime.tv_sec;
 161  162                  r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
 162  163  
 163  164                  r32.ru_majflt   = (int32_t)r.ru_majflt;
 164  165                  r32.ru_minflt   = (int32_t)r.ru_minflt;
 165  166                  r32.ru_nswap    = (int32_t)r.ru_nswap;
 166  167                  r32.ru_inblock  = (int32_t)r.ru_inblock;
 167  168                  r32.ru_oublock  = (int32_t)r.ru_oublock;
 168  169                  r32.ru_msgsnd   = (int32_t)r.ru_msgsnd;
 169  170                  r32.ru_msgrcv   = (int32_t)r.ru_msgrcv;
 170  171                  r32.ru_nsignals = (int32_t)r.ru_nsignals;
 171  172                  r32.ru_nvcsw    = (int32_t)r.ru_nvcsw;
 172  173                  r32.ru_nivcsw   = (int32_t)r.ru_nivcsw;
 173  174                  if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
 174  175                          return (set_errno(EFAULT));
 175  176          } else
 176  177  #endif /* _SYSCALL32_IMPL */
 177  178  
 178  179                  if (copyout(&r, user_rusage, sizeof (r)) != 0)
 179  180                          return (set_errno(EFAULT));
 180  181  
 181  182          return (0);
 182  183  }
 183  184  
 184  185  static int
 185  186  getrusage_lwp(void *user_rusage)
 186  187  {
 187  188          struct rusage r;
 188  189          kthread_t *t = curthread;
 189  190          klwp_t *lwp;
 190  191          hrtime_t snsecs, unsecs;
 191  192          struct mstate *ms;
 192  193  
 193  194          bzero(&r, sizeof (struct rusage));
 194  195  
 195  196          lwp = ttolwp(t);
 196  197          ms = &lwp->lwp_mstate;
 197  198          unsecs = ms->ms_acct[LMS_USER];
 198  199          snsecs = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
 199  200          scalehrtime(&unsecs);
 200  201          scalehrtime(&snsecs);
 201  202          r.ru_majflt     = lwp->lwp_ru.majflt;
 202  203          r.ru_minflt     = lwp->lwp_ru.minflt;
 203  204          r.ru_nswap      = lwp->lwp_ru.nswap;
 204  205          r.ru_inblock    = lwp->lwp_ru.inblock;
 205  206          r.ru_oublock    = lwp->lwp_ru.oublock;
 206  207          r.ru_msgsnd     = lwp->lwp_ru.msgsnd;
 207  208          r.ru_msgrcv     = lwp->lwp_ru.msgrcv;
 208  209          r.ru_nsignals   = lwp->lwp_ru.nsignals;
 209  210          r.ru_nvcsw      = lwp->lwp_ru.nvcsw;
 210  211          r.ru_nivcsw     = lwp->lwp_ru.nivcsw;
 211  212  
 212  213          hrt2tv(unsecs, &r.ru_utime);
 213  214          hrt2tv(snsecs, &r.ru_stime);
 214  215  #ifdef _SYSCALL32_IMPL
 215  216          if (get_udatamodel() == DATAMODEL_ILP32) {
 216  217                  struct rusage32 r32;
 217  218  
 218  219                  bzero(&r32, sizeof (struct rusage32));
 219  220  
 220  221                  r32.ru_utime.tv_sec  = r.ru_utime.tv_sec;
 221  222                  r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
 222  223                  r32.ru_stime.tv_sec  = r.ru_stime.tv_sec;
 223  224                  r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
 224  225  
 225  226                  r32.ru_majflt   = (int32_t)r.ru_majflt;
 226  227                  r32.ru_minflt   = (int32_t)r.ru_minflt;
 227  228                  r32.ru_nswap    = (int32_t)r.ru_nswap;
 228  229                  r32.ru_inblock  = (int32_t)r.ru_inblock;
 229  230                  r32.ru_oublock  = (int32_t)r.ru_oublock;
 230  231                  r32.ru_msgsnd   = (int32_t)r.ru_msgsnd;
 231  232                  r32.ru_msgrcv   = (int32_t)r.ru_msgrcv;
 232  233                  r32.ru_nsignals = (int32_t)r.ru_nsignals;
 233  234                  r32.ru_nvcsw    = (int32_t)r.ru_nvcsw;
 234  235                  r32.ru_nivcsw   = (int32_t)r.ru_nivcsw;
 235  236                  if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
 236  237                          return (set_errno(EFAULT));
 237  238          } else
 238  239  #endif /* _SYSCALL32_IMPL */
 239  240  
 240  241                  if (copyout(&r, user_rusage, sizeof (r)) != 0)
 241  242                          return (set_errno(EFAULT));
 242  243  
 243  244          return (0);
 244  245  }
 245  246  
 246  247  int
 247  248  rusagesys(int code, void *arg1, void *arg2, void *arg3, void *arg4)
 248  249  {
 249  250          switch (code) {
  
    | 
      ↓ open down ↓ | 
    216 lines elided | 
    
      ↑ open up ↑ | 
  
 250  251  
 251  252          case _RUSAGESYS_GETRUSAGE:
 252  253                  return (getrusage(arg1));
 253  254          case _RUSAGESYS_GETRUSAGE_CHLD:
 254  255                  return (getrusage_chld(arg1));
 255  256          case _RUSAGESYS_GETRUSAGE_LWP:
 256  257                  return (getrusage_lwp(arg1));
 257  258          case _RUSAGESYS_GETVMUSAGE:
 258  259                  return (vm_getusage((uint_t)(uintptr_t)arg1, (time_t)arg2,
 259  260                      (vmusage_t *)arg3, (size_t *)arg4, 0));
      261 +        case _RUSAGESYS_INVALMAP:
      262 +                /*
      263 +                 * SPARC sfmmu hat does not support HAT_CURPROC_PGUNLOAD
      264 +                 * handling so callers on SPARC should get simple sync
      265 +                 * handling with invalidation to all processes.
      266 +                 */
      267 +#if defined(__sparc)
      268 +                return (memcntl((caddr_t)arg2, (size_t)arg3, MC_SYNC,
      269 +                    (caddr_t)(MS_ASYNC | MS_INVALIDATE), 0, 0));
      270 +#else
      271 +                return (vm_map_inval((pid_t)(uintptr_t)arg1, (caddr_t)arg2,
      272 +                    (size_t)arg3));
      273 +#endif
 260  274          default:
 261  275                  return (set_errno(EINVAL));
 262  276          }
 263  277  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX