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