xref: /openbmc/linux/fs/proc/stat.c (revision 82ced6fd)
1 #include <linux/cpumask.h>
2 #include <linux/fs.h>
3 #include <linux/gfp.h>
4 #include <linux/init.h>
5 #include <linux/interrupt.h>
6 #include <linux/kernel_stat.h>
7 #include <linux/proc_fs.h>
8 #include <linux/sched.h>
9 #include <linux/seq_file.h>
10 #include <linux/slab.h>
11 #include <linux/time.h>
12 #include <linux/irqnr.h>
13 #include <asm/cputime.h>
14 
15 #ifndef arch_irq_stat_cpu
16 #define arch_irq_stat_cpu(cpu) 0
17 #endif
18 #ifndef arch_irq_stat
19 #define arch_irq_stat() 0
20 #endif
21 #ifndef arch_idle_time
22 #define arch_idle_time(cpu) 0
23 #endif
24 
25 static int show_stat(struct seq_file *p, void *v)
26 {
27 	int i, j;
28 	unsigned long jif;
29 	cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
30 	cputime64_t guest;
31 	u64 sum = 0;
32 	struct timespec boottime;
33 	unsigned int per_irq_sum;
34 
35 	user = nice = system = idle = iowait =
36 		irq = softirq = steal = cputime64_zero;
37 	guest = cputime64_zero;
38 	getboottime(&boottime);
39 	jif = boottime.tv_sec;
40 
41 	for_each_possible_cpu(i) {
42 		user = cputime64_add(user, kstat_cpu(i).cpustat.user);
43 		nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
44 		system = cputime64_add(system, kstat_cpu(i).cpustat.system);
45 		idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
46 		idle = cputime64_add(idle, arch_idle_time(i));
47 		iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
48 		irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
49 		softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
50 		steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
51 		guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
52 		for_each_irq_nr(j) {
53 			sum += kstat_irqs_cpu(j, i);
54 		}
55 		sum += arch_irq_stat_cpu(i);
56 	}
57 	sum += arch_irq_stat();
58 
59 	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
60 		(unsigned long long)cputime64_to_clock_t(user),
61 		(unsigned long long)cputime64_to_clock_t(nice),
62 		(unsigned long long)cputime64_to_clock_t(system),
63 		(unsigned long long)cputime64_to_clock_t(idle),
64 		(unsigned long long)cputime64_to_clock_t(iowait),
65 		(unsigned long long)cputime64_to_clock_t(irq),
66 		(unsigned long long)cputime64_to_clock_t(softirq),
67 		(unsigned long long)cputime64_to_clock_t(steal),
68 		(unsigned long long)cputime64_to_clock_t(guest));
69 	for_each_online_cpu(i) {
70 
71 		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
72 		user = kstat_cpu(i).cpustat.user;
73 		nice = kstat_cpu(i).cpustat.nice;
74 		system = kstat_cpu(i).cpustat.system;
75 		idle = kstat_cpu(i).cpustat.idle;
76 		idle = cputime64_add(idle, arch_idle_time(i));
77 		iowait = kstat_cpu(i).cpustat.iowait;
78 		irq = kstat_cpu(i).cpustat.irq;
79 		softirq = kstat_cpu(i).cpustat.softirq;
80 		steal = kstat_cpu(i).cpustat.steal;
81 		guest = kstat_cpu(i).cpustat.guest;
82 		seq_printf(p,
83 			"cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
84 			i,
85 			(unsigned long long)cputime64_to_clock_t(user),
86 			(unsigned long long)cputime64_to_clock_t(nice),
87 			(unsigned long long)cputime64_to_clock_t(system),
88 			(unsigned long long)cputime64_to_clock_t(idle),
89 			(unsigned long long)cputime64_to_clock_t(iowait),
90 			(unsigned long long)cputime64_to_clock_t(irq),
91 			(unsigned long long)cputime64_to_clock_t(softirq),
92 			(unsigned long long)cputime64_to_clock_t(steal),
93 			(unsigned long long)cputime64_to_clock_t(guest));
94 	}
95 	seq_printf(p, "intr %llu", (unsigned long long)sum);
96 
97 	/* sum again ? it could be updated? */
98 	for_each_irq_nr(j) {
99 		per_irq_sum = 0;
100 		for_each_possible_cpu(i)
101 			per_irq_sum += kstat_irqs_cpu(j, i);
102 
103 		seq_printf(p, " %u", per_irq_sum);
104 	}
105 
106 	seq_printf(p,
107 		"\nctxt %llu\n"
108 		"btime %lu\n"
109 		"processes %lu\n"
110 		"procs_running %lu\n"
111 		"procs_blocked %lu\n",
112 		nr_context_switches(),
113 		(unsigned long)jif,
114 		total_forks,
115 		nr_running(),
116 		nr_iowait());
117 
118 	return 0;
119 }
120 
121 static int stat_open(struct inode *inode, struct file *file)
122 {
123 	unsigned size = 4096 * (1 + num_possible_cpus() / 32);
124 	char *buf;
125 	struct seq_file *m;
126 	int res;
127 
128 	/* don't ask for more than the kmalloc() max size, currently 128 KB */
129 	if (size > 128 * 1024)
130 		size = 128 * 1024;
131 	buf = kmalloc(size, GFP_KERNEL);
132 	if (!buf)
133 		return -ENOMEM;
134 
135 	res = single_open(file, show_stat, NULL);
136 	if (!res) {
137 		m = file->private_data;
138 		m->buf = buf;
139 		m->size = size;
140 	} else
141 		kfree(buf);
142 	return res;
143 }
144 
145 static const struct file_operations proc_stat_operations = {
146 	.open		= stat_open,
147 	.read		= seq_read,
148 	.llseek		= seq_lseek,
149 	.release	= single_release,
150 };
151 
152 static int __init proc_stat_init(void)
153 {
154 	proc_create("stat", 0, NULL, &proc_stat_operations);
155 	return 0;
156 }
157 module_init(proc_stat_init);
158