| .. | .. |
|---|
| 23 | 23 | |
|---|
| 24 | 24 | #ifdef arch_idle_time |
|---|
| 25 | 25 | |
|---|
| 26 | | -static u64 get_idle_time(int cpu) |
|---|
| 26 | +u64 get_idle_time(struct kernel_cpustat *kcs, int cpu) |
|---|
| 27 | 27 | { |
|---|
| 28 | 28 | u64 idle; |
|---|
| 29 | 29 | |
|---|
| 30 | | - idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; |
|---|
| 30 | + idle = kcs->cpustat[CPUTIME_IDLE]; |
|---|
| 31 | 31 | if (cpu_online(cpu) && !nr_iowait_cpu(cpu)) |
|---|
| 32 | 32 | idle += arch_idle_time(cpu); |
|---|
| 33 | 33 | return idle; |
|---|
| 34 | 34 | } |
|---|
| 35 | 35 | |
|---|
| 36 | | -static u64 get_iowait_time(int cpu) |
|---|
| 36 | +static u64 get_iowait_time(struct kernel_cpustat *kcs, int cpu) |
|---|
| 37 | 37 | { |
|---|
| 38 | 38 | u64 iowait; |
|---|
| 39 | 39 | |
|---|
| 40 | | - iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; |
|---|
| 40 | + iowait = kcs->cpustat[CPUTIME_IOWAIT]; |
|---|
| 41 | 41 | if (cpu_online(cpu) && nr_iowait_cpu(cpu)) |
|---|
| 42 | 42 | iowait += arch_idle_time(cpu); |
|---|
| 43 | 43 | return iowait; |
|---|
| .. | .. |
|---|
| 45 | 45 | |
|---|
| 46 | 46 | #else |
|---|
| 47 | 47 | |
|---|
| 48 | | -static u64 get_idle_time(int cpu) |
|---|
| 48 | +u64 get_idle_time(struct kernel_cpustat *kcs, int cpu) |
|---|
| 49 | 49 | { |
|---|
| 50 | 50 | u64 idle, idle_usecs = -1ULL; |
|---|
| 51 | 51 | |
|---|
| .. | .. |
|---|
| 54 | 54 | |
|---|
| 55 | 55 | if (idle_usecs == -1ULL) |
|---|
| 56 | 56 | /* !NO_HZ or cpu offline so we can rely on cpustat.idle */ |
|---|
| 57 | | - idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; |
|---|
| 57 | + idle = kcs->cpustat[CPUTIME_IDLE]; |
|---|
| 58 | 58 | else |
|---|
| 59 | 59 | idle = idle_usecs * NSEC_PER_USEC; |
|---|
| 60 | 60 | |
|---|
| 61 | 61 | return idle; |
|---|
| 62 | 62 | } |
|---|
| 63 | 63 | |
|---|
| 64 | | -static u64 get_iowait_time(int cpu) |
|---|
| 64 | +static u64 get_iowait_time(struct kernel_cpustat *kcs, int cpu) |
|---|
| 65 | 65 | { |
|---|
| 66 | 66 | u64 iowait, iowait_usecs = -1ULL; |
|---|
| 67 | 67 | |
|---|
| .. | .. |
|---|
| 70 | 70 | |
|---|
| 71 | 71 | if (iowait_usecs == -1ULL) |
|---|
| 72 | 72 | /* !NO_HZ or cpu offline so we can rely on cpustat.iowait */ |
|---|
| 73 | | - iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; |
|---|
| 73 | + iowait = kcs->cpustat[CPUTIME_IOWAIT]; |
|---|
| 74 | 74 | else |
|---|
| 75 | 75 | iowait = iowait_usecs * NSEC_PER_USEC; |
|---|
| 76 | 76 | |
|---|
| .. | .. |
|---|
| 78 | 78 | } |
|---|
| 79 | 79 | |
|---|
| 80 | 80 | #endif |
|---|
| 81 | + |
|---|
| 82 | +static void show_irq_gap(struct seq_file *p, unsigned int gap) |
|---|
| 83 | +{ |
|---|
| 84 | + static const char zeros[] = " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; |
|---|
| 85 | + |
|---|
| 86 | + while (gap > 0) { |
|---|
| 87 | + unsigned int inc; |
|---|
| 88 | + |
|---|
| 89 | + inc = min_t(unsigned int, gap, ARRAY_SIZE(zeros) / 2); |
|---|
| 90 | + seq_write(p, zeros, 2 * inc); |
|---|
| 91 | + gap -= inc; |
|---|
| 92 | + } |
|---|
| 93 | +} |
|---|
| 94 | + |
|---|
| 95 | +static void show_all_irqs(struct seq_file *p) |
|---|
| 96 | +{ |
|---|
| 97 | + unsigned int i, next = 0; |
|---|
| 98 | + |
|---|
| 99 | + for_each_active_irq(i) { |
|---|
| 100 | + show_irq_gap(p, i - next); |
|---|
| 101 | + seq_put_decimal_ull(p, " ", kstat_irqs_usr(i)); |
|---|
| 102 | + next = i + 1; |
|---|
| 103 | + } |
|---|
| 104 | + show_irq_gap(p, nr_irqs - next); |
|---|
| 105 | +} |
|---|
| 81 | 106 | |
|---|
| 82 | 107 | static int show_stat(struct seq_file *p, void *v) |
|---|
| 83 | 108 | { |
|---|
| .. | .. |
|---|
| 95 | 120 | getboottime64(&boottime); |
|---|
| 96 | 121 | |
|---|
| 97 | 122 | for_each_possible_cpu(i) { |
|---|
| 98 | | - user += kcpustat_cpu(i).cpustat[CPUTIME_USER]; |
|---|
| 99 | | - nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE]; |
|---|
| 100 | | - system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM]; |
|---|
| 101 | | - idle += get_idle_time(i); |
|---|
| 102 | | - iowait += get_iowait_time(i); |
|---|
| 103 | | - irq += kcpustat_cpu(i).cpustat[CPUTIME_IRQ]; |
|---|
| 104 | | - softirq += kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ]; |
|---|
| 105 | | - steal += kcpustat_cpu(i).cpustat[CPUTIME_STEAL]; |
|---|
| 106 | | - guest += kcpustat_cpu(i).cpustat[CPUTIME_GUEST]; |
|---|
| 107 | | - guest_nice += kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE]; |
|---|
| 108 | | - sum += kstat_cpu_irqs_sum(i); |
|---|
| 109 | | - sum += arch_irq_stat_cpu(i); |
|---|
| 123 | + struct kernel_cpustat kcpustat; |
|---|
| 124 | + u64 *cpustat = kcpustat.cpustat; |
|---|
| 125 | + |
|---|
| 126 | + kcpustat_cpu_fetch(&kcpustat, i); |
|---|
| 127 | + |
|---|
| 128 | + user += cpustat[CPUTIME_USER]; |
|---|
| 129 | + nice += cpustat[CPUTIME_NICE]; |
|---|
| 130 | + system += cpustat[CPUTIME_SYSTEM]; |
|---|
| 131 | + idle += get_idle_time(&kcpustat, i); |
|---|
| 132 | + iowait += get_iowait_time(&kcpustat, i); |
|---|
| 133 | + irq += cpustat[CPUTIME_IRQ]; |
|---|
| 134 | + softirq += cpustat[CPUTIME_SOFTIRQ]; |
|---|
| 135 | + steal += cpustat[CPUTIME_STEAL]; |
|---|
| 136 | + guest += cpustat[CPUTIME_GUEST]; |
|---|
| 137 | + guest_nice += cpustat[CPUTIME_GUEST_NICE]; |
|---|
| 138 | + sum += kstat_cpu_irqs_sum(i); |
|---|
| 139 | + sum += arch_irq_stat_cpu(i); |
|---|
| 110 | 140 | |
|---|
| 111 | 141 | for (j = 0; j < NR_SOFTIRQS; j++) { |
|---|
| 112 | 142 | unsigned int softirq_stat = kstat_softirqs_cpu(j, i); |
|---|
| .. | .. |
|---|
| 130 | 160 | seq_putc(p, '\n'); |
|---|
| 131 | 161 | |
|---|
| 132 | 162 | for_each_online_cpu(i) { |
|---|
| 163 | + struct kernel_cpustat kcpustat; |
|---|
| 164 | + u64 *cpustat = kcpustat.cpustat; |
|---|
| 165 | + |
|---|
| 166 | + kcpustat_cpu_fetch(&kcpustat, i); |
|---|
| 167 | + |
|---|
| 133 | 168 | /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ |
|---|
| 134 | | - user = kcpustat_cpu(i).cpustat[CPUTIME_USER]; |
|---|
| 135 | | - nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE]; |
|---|
| 136 | | - system = kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM]; |
|---|
| 137 | | - idle = get_idle_time(i); |
|---|
| 138 | | - iowait = get_iowait_time(i); |
|---|
| 139 | | - irq = kcpustat_cpu(i).cpustat[CPUTIME_IRQ]; |
|---|
| 140 | | - softirq = kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ]; |
|---|
| 141 | | - steal = kcpustat_cpu(i).cpustat[CPUTIME_STEAL]; |
|---|
| 142 | | - guest = kcpustat_cpu(i).cpustat[CPUTIME_GUEST]; |
|---|
| 143 | | - guest_nice = kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE]; |
|---|
| 169 | + user = cpustat[CPUTIME_USER]; |
|---|
| 170 | + nice = cpustat[CPUTIME_NICE]; |
|---|
| 171 | + system = cpustat[CPUTIME_SYSTEM]; |
|---|
| 172 | + idle = get_idle_time(&kcpustat, i); |
|---|
| 173 | + iowait = get_iowait_time(&kcpustat, i); |
|---|
| 174 | + irq = cpustat[CPUTIME_IRQ]; |
|---|
| 175 | + softirq = cpustat[CPUTIME_SOFTIRQ]; |
|---|
| 176 | + steal = cpustat[CPUTIME_STEAL]; |
|---|
| 177 | + guest = cpustat[CPUTIME_GUEST]; |
|---|
| 178 | + guest_nice = cpustat[CPUTIME_GUEST_NICE]; |
|---|
| 144 | 179 | seq_printf(p, "cpu%d", i); |
|---|
| 145 | 180 | seq_put_decimal_ull(p, " ", nsec_to_clock_t(user)); |
|---|
| 146 | 181 | seq_put_decimal_ull(p, " ", nsec_to_clock_t(nice)); |
|---|
| .. | .. |
|---|
| 156 | 191 | } |
|---|
| 157 | 192 | seq_put_decimal_ull(p, "intr ", (unsigned long long)sum); |
|---|
| 158 | 193 | |
|---|
| 159 | | - /* sum again ? it could be updated? */ |
|---|
| 160 | | - for_each_irq_nr(j) |
|---|
| 161 | | - seq_put_decimal_ull(p, " ", kstat_irqs_usr(j)); |
|---|
| 194 | + show_all_irqs(p); |
|---|
| 162 | 195 | |
|---|
| 163 | 196 | seq_printf(p, |
|---|
| 164 | 197 | "\nctxt %llu\n" |
|---|
| .. | .. |
|---|
| 190 | 223 | return single_open_size(file, show_stat, NULL, size); |
|---|
| 191 | 224 | } |
|---|
| 192 | 225 | |
|---|
| 193 | | -static const struct file_operations proc_stat_operations = { |
|---|
| 194 | | - .open = stat_open, |
|---|
| 195 | | - .read = seq_read, |
|---|
| 196 | | - .llseek = seq_lseek, |
|---|
| 197 | | - .release = single_release, |
|---|
| 226 | +static const struct proc_ops stat_proc_ops = { |
|---|
| 227 | + .proc_flags = PROC_ENTRY_PERMANENT, |
|---|
| 228 | + .proc_open = stat_open, |
|---|
| 229 | + .proc_read_iter = seq_read_iter, |
|---|
| 230 | + .proc_lseek = seq_lseek, |
|---|
| 231 | + .proc_release = single_release, |
|---|
| 198 | 232 | }; |
|---|
| 199 | 233 | |
|---|
| 200 | 234 | static int __init proc_stat_init(void) |
|---|
| 201 | 235 | { |
|---|
| 202 | | - proc_create("stat", 0, NULL, &proc_stat_operations); |
|---|
| 236 | + proc_create("stat", 0, NULL, &stat_proc_ops); |
|---|
| 203 | 237 | return 0; |
|---|
| 204 | 238 | } |
|---|
| 205 | 239 | fs_initcall(proc_stat_init); |
|---|