The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/delayacct.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* delayacct.c - per-task delay accounting
    2  *
    3  * Copyright (C) Shailabh Nagar, IBM Corp. 2006
    4  *
    5  * This program is free software;  you can redistribute it and/or modify
    6  * it under the terms of the GNU General Public License as published by
    7  * the Free Software Foundation; either version 2 of the License, or
    8  * (at your option) any later version.
    9  *
   10  * This program is distributed in the hope that it would be useful, but
   11  * WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
   13  * the GNU General Public License for more details.
   14  */
   15 
   16 #include <linux/sched.h>
   17 #include <linux/slab.h>
   18 #include <linux/taskstats.h>
   19 #include <linux/time.h>
   20 #include <linux/sysctl.h>
   21 #include <linux/delayacct.h>
   22 #include <linux/module.h>
   23 
   24 int delayacct_on __read_mostly = 1;     /* Delay accounting turned on/off */
   25 EXPORT_SYMBOL_GPL(delayacct_on);
   26 struct kmem_cache *delayacct_cache;
   27 
   28 static int __init delayacct_setup_disable(char *str)
   29 {
   30         delayacct_on = 0;
   31         return 1;
   32 }
   33 __setup("nodelayacct", delayacct_setup_disable);
   34 
   35 void delayacct_init(void)
   36 {
   37         delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC);
   38         delayacct_tsk_init(&init_task);
   39 }
   40 
   41 void __delayacct_tsk_init(struct task_struct *tsk)
   42 {
   43         tsk->delays = kmem_cache_zalloc(delayacct_cache, GFP_KERNEL);
   44         if (tsk->delays)
   45                 spin_lock_init(&tsk->delays->lock);
   46 }
   47 
   48 /*
   49  * Start accounting for a delay statistic using
   50  * its starting timestamp (@start)
   51  */
   52 
   53 static inline void delayacct_start(struct timespec *start)
   54 {
   55         do_posix_clock_monotonic_gettime(start);
   56 }
   57 
   58 /*
   59  * Finish delay accounting for a statistic using
   60  * its timestamps (@start, @end), accumalator (@total) and @count
   61  */
   62 
   63 static void delayacct_end(struct timespec *start, struct timespec *end,
   64                                 u64 *total, u32 *count)
   65 {
   66         struct timespec ts;
   67         s64 ns;
   68         unsigned long flags;
   69 
   70         do_posix_clock_monotonic_gettime(end);
   71         ts = timespec_sub(*end, *start);
   72         ns = timespec_to_ns(&ts);
   73         if (ns < 0)
   74                 return;
   75 
   76         spin_lock_irqsave(&current->delays->lock, flags);
   77         *total += ns;
   78         (*count)++;
   79         spin_unlock_irqrestore(&current->delays->lock, flags);
   80 }
   81 
   82 void __delayacct_blkio_start(void)
   83 {
   84         delayacct_start(&current->delays->blkio_start);
   85 }
   86 
   87 void __delayacct_blkio_end(void)
   88 {
   89         if (current->delays->flags & DELAYACCT_PF_SWAPIN)
   90                 /* Swapin block I/O */
   91                 delayacct_end(&current->delays->blkio_start,
   92                         &current->delays->blkio_end,
   93                         &current->delays->swapin_delay,
   94                         &current->delays->swapin_count);
   95         else    /* Other block I/O */
   96                 delayacct_end(&current->delays->blkio_start,
   97                         &current->delays->blkio_end,
   98                         &current->delays->blkio_delay,
   99                         &current->delays->blkio_count);
  100 }
  101 
  102 int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
  103 {
  104         s64 tmp;
  105         unsigned long t1;
  106         unsigned long long t2, t3;
  107         unsigned long flags;
  108         struct timespec ts;
  109 
  110         /* Though tsk->delays accessed later, early exit avoids
  111          * unnecessary returning of other data
  112          */
  113         if (!tsk->delays)
  114                 goto done;
  115 
  116         tmp = (s64)d->cpu_run_real_total;
  117         cputime_to_timespec(tsk->utime + tsk->stime, &ts);
  118         tmp += timespec_to_ns(&ts);
  119         d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
  120 
  121         tmp = (s64)d->cpu_scaled_run_real_total;
  122         cputime_to_timespec(tsk->utimescaled + tsk->stimescaled, &ts);
  123         tmp += timespec_to_ns(&ts);
  124         d->cpu_scaled_run_real_total =
  125                 (tmp < (s64)d->cpu_scaled_run_real_total) ? 0 : tmp;
  126 
  127         /*
  128          * No locking available for sched_info (and too expensive to add one)
  129          * Mitigate by taking snapshot of values
  130          */
  131         t1 = tsk->sched_info.pcount;
  132         t2 = tsk->sched_info.run_delay;
  133         t3 = tsk->se.sum_exec_runtime;
  134 
  135         d->cpu_count += t1;
  136 
  137         tmp = (s64)d->cpu_delay_total + t2;
  138         d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp;
  139 
  140         tmp = (s64)d->cpu_run_virtual_total + t3;
  141         d->cpu_run_virtual_total =
  142                 (tmp < (s64)d->cpu_run_virtual_total) ? 0 : tmp;
  143 
  144         /* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */
  145 
  146         spin_lock_irqsave(&tsk->delays->lock, flags);
  147         tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
  148         d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp;
  149         tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
  150         d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp;
  151         tmp = d->freepages_delay_total + tsk->delays->freepages_delay;
  152         d->freepages_delay_total = (tmp < d->freepages_delay_total) ? 0 : tmp;
  153         d->blkio_count += tsk->delays->blkio_count;
  154         d->swapin_count += tsk->delays->swapin_count;
  155         d->freepages_count += tsk->delays->freepages_count;
  156         spin_unlock_irqrestore(&tsk->delays->lock, flags);
  157 
  158 done:
  159         return 0;
  160 }
  161 
  162 __u64 __delayacct_blkio_ticks(struct task_struct *tsk)
  163 {
  164         __u64 ret;
  165         unsigned long flags;
  166 
  167         spin_lock_irqsave(&tsk->delays->lock, flags);
  168         ret = nsec_to_clock_t(tsk->delays->blkio_delay +
  169                                 tsk->delays->swapin_delay);
  170         spin_unlock_irqrestore(&tsk->delays->lock, flags);
  171         return ret;
  172 }
  173 
  174 void __delayacct_freepages_start(void)
  175 {
  176         delayacct_start(&current->delays->freepages_start);
  177 }
  178 
  179 void __delayacct_freepages_end(void)
  180 {
  181         delayacct_end(&current->delays->freepages_start,
  182                         &current->delays->freepages_end,
  183                         &current->delays->freepages_delay,
  184                         &current->delays->freepages_count);
  185 }
  186 

Cache object: d6406400f294752cdacbc4c43b5edf71


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.