LCOV - code coverage report
Current view: top level - kernel/sched - stats.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 29 36 80.6 %
Date: 2014-02-18 Functions: 5 6 83.3 %
Branches: 13 14 92.9 %

           Branch data     Line data    Source code
       1                 :            : 
       2                 :            : #include <linux/slab.h>
       3                 :            : #include <linux/fs.h>
       4                 :            : #include <linux/seq_file.h>
       5                 :            : #include <linux/proc_fs.h>
       6                 :            : 
       7                 :            : #include "sched.h"
       8                 :            : 
       9                 :            : /*
      10                 :            :  * bump this up when changing the output format or the meaning of an existing
      11                 :            :  * format, so that tools can adapt (or abort)
      12                 :            :  */
      13                 :            : #define SCHEDSTAT_VERSION 15
      14                 :            : 
      15                 :          0 : static int show_schedstat(struct seq_file *seq, void *v)
      16                 :            : {
      17                 :            :         int cpu;
      18                 :            :         int mask_len = DIV_ROUND_UP(NR_CPUS, 32) * 9;
      19                 :            :         char *mask_str = kmalloc(mask_len, GFP_KERNEL);
      20                 :            : 
      21         [ +  - ]:          3 :         if (mask_str == NULL)
      22                 :            :                 return -ENOMEM;
      23                 :            : 
      24         [ +  + ]:          3 :         if (v == (void *)1) {
      25                 :          1 :                 seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION);
      26                 :          1 :                 seq_printf(seq, "timestamp %lu\n", jiffies);
      27                 :            :         } else {
      28                 :            :                 struct rq *rq;
      29                 :            : #ifdef CONFIG_SMP
      30                 :            :                 struct sched_domain *sd;
      31                 :            :                 int dcount = 0;
      32                 :            : #endif
      33                 :          2 :                 cpu = (unsigned long)(v - 2);
      34                 :          2 :                 rq = cpu_rq(cpu);
      35                 :            : 
      36                 :            :                 /* runqueue-specific stats */
      37                 :          2 :                 seq_printf(seq,
      38                 :            :                     "cpu%d %u 0 %u %u %u %u %llu %llu %lu",
      39                 :            :                     cpu, rq->yld_count,
      40                 :            :                     rq->sched_count, rq->sched_goidle,
      41                 :            :                     rq->ttwu_count, rq->ttwu_local,
      42                 :            :                     rq->rq_cpu_time,
      43                 :            :                     rq->rq_sched_info.run_delay, rq->rq_sched_info.pcount);
      44                 :            : 
      45                 :          2 :                 seq_printf(seq, "\n");
      46                 :            : 
      47                 :            : #ifdef CONFIG_SMP
      48                 :            :                 /* domain-specific stats */
      49                 :            :                 rcu_read_lock();
      50         [ +  + ]:          7 :                 for_each_domain(cpu, sd) {
      51                 :            :                         enum cpu_idle_type itype;
      52                 :            : 
      53                 :            :                         cpumask_scnprintf(mask_str, mask_len,
      54                 :            :                                           sched_domain_span(sd));
      55                 :          2 :                         seq_printf(seq, "domain%d %s", dcount++, mask_str);
      56         [ +  + ]:          8 :                         for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES;
      57                 :          6 :                                         itype++) {
      58                 :          6 :                                 seq_printf(seq, " %u %u %u %u %u %u %u %u",
      59                 :            :                                     sd->lb_count[itype],
      60                 :            :                                     sd->lb_balanced[itype],
      61                 :            :                                     sd->lb_failed[itype],
      62                 :            :                                     sd->lb_imbalance[itype],
      63                 :            :                                     sd->lb_gained[itype],
      64                 :            :                                     sd->lb_hot_gained[itype],
      65                 :            :                                     sd->lb_nobusyq[itype],
      66                 :            :                                     sd->lb_nobusyg[itype]);
      67                 :            :                         }
      68                 :          2 :                         seq_printf(seq,
      69                 :            :                                    " %u %u %u %u %u %u %u %u %u %u %u %u\n",
      70                 :            :                             sd->alb_count, sd->alb_failed, sd->alb_pushed,
      71                 :            :                             sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed,
      72                 :            :                             sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed,
      73                 :            :                             sd->ttwu_wake_remote, sd->ttwu_move_affine,
      74                 :            :                             sd->ttwu_move_balance);
      75                 :            :                 }
      76                 :            :                 rcu_read_unlock();
      77                 :            : #endif
      78                 :            :         }
      79                 :          3 :         kfree(mask_str);
      80                 :          3 :         return 0;
      81                 :            : }
      82                 :            : 
      83                 :            : /*
      84                 :            :  * This itererator needs some explanation.
      85                 :            :  * It returns 1 for the header position.
      86                 :            :  * This means 2 is cpu 0.
      87                 :            :  * In a hotplugged system some cpus, including cpu 0, may be missing so we have
      88                 :            :  * to use cpumask_* to iterate over the cpus.
      89                 :            :  */
      90                 :          0 : static void *schedstat_start(struct seq_file *file, loff_t *offset)
      91                 :            : {
      92                 :          5 :         unsigned long n = *offset;
      93                 :            : 
      94         [ +  + ]:          5 :         if (n == 0)
      95                 :            :                 return (void *) 1;
      96                 :            : 
      97                 :          4 :         n--;
      98                 :            : 
      99         [ +  + ]:          4 :         if (n > 0)
     100                 :          3 :                 n = cpumask_next(n - 1, cpu_online_mask);
     101                 :            :         else
     102                 :          1 :                 n = cpumask_first(cpu_online_mask);
     103                 :            : 
     104                 :          4 :         *offset = n + 1;
     105                 :            : 
     106         [ +  + ]:          4 :         if (n < nr_cpu_ids)
     107                 :          2 :                 return (void *)(unsigned long)(n + 2);
     108                 :            :         return NULL;
     109                 :            : }
     110                 :            : 
     111                 :          0 : static void *schedstat_next(struct seq_file *file, void *data, loff_t *offset)
     112                 :            : {
     113                 :          3 :         (*offset)++;
     114                 :          3 :         return schedstat_start(file, offset);
     115                 :            : }
     116                 :            : 
     117                 :          0 : static void schedstat_stop(struct seq_file *file, void *data)
     118                 :            : {
     119                 :          2 : }
     120                 :            : 
     121                 :            : static const struct seq_operations schedstat_sops = {
     122                 :            :         .start = schedstat_start,
     123                 :            :         .next  = schedstat_next,
     124                 :            :         .stop  = schedstat_stop,
     125                 :            :         .show  = show_schedstat,
     126                 :            : };
     127                 :            : 
     128                 :          0 : static int schedstat_open(struct inode *inode, struct file *file)
     129                 :            : {
     130                 :          1 :         return seq_open(file, &schedstat_sops);
     131                 :            : }
     132                 :            : 
     133                 :            : static const struct file_operations proc_schedstat_operations = {
     134                 :            :         .open    = schedstat_open,
     135                 :            :         .read    = seq_read,
     136                 :            :         .llseek  = seq_lseek,
     137                 :            :         .release = seq_release,
     138                 :            : };
     139                 :            : 
     140                 :          0 : static int __init proc_schedstat_init(void)
     141                 :            : {
     142                 :            :         proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
     143                 :          0 :         return 0;
     144                 :            : }
     145                 :            : module_init(proc_schedstat_init);

Generated by: LCOV version 1.9