File: /usr/src/linux/fs/proc/proc_misc.c
1 /*
2 * linux/fs/proc/proc_misc.c
3 *
4 * linux/fs/proc/array.c
5 * Copyright (C) 1992 by Linus Torvalds
6 * based on ideas by Darren Senn
7 *
8 * This used to be the part of array.c. See the rest of history and credits
9 * there. I took this into a separate file and switched the thing to generic
10 * proc_file_inode_operations, leaving in array.c only per-process stuff.
11 * Inumbers allocation made dynamic (via create_proc_entry()). AV, May 1999.
12 *
13 * Changes:
14 * Fulton Green : Encapsulated position metric calculations.
15 * <kernel@FultonGreen.com>
16 */
17
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/sched.h>
21 #include <linux/kernel.h>
22 #include <linux/kernel_stat.h>
23 #include <linux/tty.h>
24 #include <linux/string.h>
25 #include <linux/mman.h>
26 #include <linux/proc_fs.h>
27 #include <linux/ioport.h>
28 #include <linux/config.h>
29 #include <linux/mm.h>
30 #include <linux/pagemap.h>
31 #include <linux/swap.h>
32 #include <linux/slab.h>
33 #include <linux/smp.h>
34 #include <linux/signal.h>
35 #include <linux/module.h>
36 #include <linux/init.h>
37 #include <linux/smp_lock.h>
38
39 #include <asm/uaccess.h>
40 #include <asm/pgtable.h>
41 #include <asm/io.h>
42
43
44 #define LOAD_INT(x) ((x) >> FSHIFT)
45 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
46 /*
47 * Warning: stuff below (imported functions) assumes that its output will fit
48 * into one page. For some of those functions it may be wrong. Moreover, we
49 * have a way to deal with that gracefully. Right now I used straightforward
50 * wrappers, but this needs further analysis wrt potential overflows.
51 */
52 extern int get_cpuinfo(char *);
53 extern int get_hardware_list(char *);
54 extern int get_stram_list(char *);
55 #ifdef CONFIG_DEBUG_MALLOC
56 extern int get_malloc(char * buffer);
57 #endif
58 #ifdef CONFIG_MODULES
59 extern int get_module_list(char *);
60 extern int get_ksyms_list(char *, char **, off_t, int);
61 #endif
62 extern int get_device_list(char *);
63 extern int get_partition_list(char *, char **, off_t, int);
64 extern int get_filesystem_list(char *);
65 extern int get_filesystem_info(char *);
66 extern int get_exec_domain_list(char *);
67 extern int get_irq_list(char *);
68 extern int get_dma_list(char *);
69 extern int get_locks_status (char *, char **, off_t, int);
70 extern int get_swaparea_info (char *);
71 #ifdef CONFIG_SGI_DS1286
72 extern int get_ds1286_status(char *);
73 #endif
74
75 static int proc_calc_metrics(char *page, char **start, off_t off,
76 int count, int *eof, int len)
77 {
78 if (len <= off+count) *eof = 1;
79 *start = page + off;
80 len -= off;
81 if (len>count) len = count;
82 if (len<0) len = 0;
83 return len;
84 }
85
86 static int loadavg_read_proc(char *page, char **start, off_t off,
87 int count, int *eof, void *data)
88 {
89 int a, b, c;
90 int len;
91
92 a = avenrun[0] + (FIXED_1/200);
93 b = avenrun[1] + (FIXED_1/200);
94 c = avenrun[2] + (FIXED_1/200);
95 len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
96 LOAD_INT(a), LOAD_FRAC(a),
97 LOAD_INT(b), LOAD_FRAC(b),
98 LOAD_INT(c), LOAD_FRAC(c),
99 nr_running, nr_threads, last_pid);
100 return proc_calc_metrics(page, start, off, count, eof, len);
101 }
102
103 static int uptime_read_proc(char *page, char **start, off_t off,
104 int count, int *eof, void *data)
105 {
106 unsigned long uptime;
107 unsigned long idle;
108 int len;
109
110 uptime = jiffies;
111 idle = init_tasks[0]->times.tms_utime + init_tasks[0]->times.tms_stime;
112
113 /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
114 that would overflow about every five days at HZ == 100.
115 Therefore the identity a = (a / b) * b + a % b is used so that it is
116 calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100.
117 The part in front of the '+' always evaluates as 0 (mod 100). All divisions
118 in the above formulas are truncating. For HZ being a power of 10, the
119 calculations simplify to the version in the #else part (if the printf
120 format is adapted to the same number of digits as zeroes in HZ.
121 */
122 #if HZ!=100
123 len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
124 uptime / HZ,
125 (((uptime % HZ) * 100) / HZ) % 100,
126 idle / HZ,
127 (((idle % HZ) * 100) / HZ) % 100);
128 #else
129 len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
130 uptime / HZ,
131 uptime % HZ,
132 idle / HZ,
133 idle % HZ);
134 #endif
135 return proc_calc_metrics(page, start, off, count, eof, len);
136 }
137
138 static int meminfo_read_proc(char *page, char **start, off_t off,
139 int count, int *eof, void *data)
140 {
141 struct sysinfo i;
142 int len;
143
144 /*
145 * display in kilobytes.
146 */
147 #define K(x) ((x) << (PAGE_SHIFT - 10))
148 #define B(x) ((unsigned long long)(x) << PAGE_SHIFT)
149 si_meminfo(&i);
150 si_swapinfo(&i);
151 len = sprintf(page, " total: used: free: shared: buffers: cached:\n"
152 "Mem: %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n"
153 "Swap: %8Lu %8Lu %8Lu\n",
154 B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
155 B(i.sharedram), B(i.bufferram),
156 B(atomic_read(&page_cache_size)), B(i.totalswap),
157 B(i.totalswap-i.freeswap), B(i.freeswap));
158 /*
159 * Tagged format, for easy grepping and expansion.
160 * The above will go away eventually, once the tools
161 * have been updated.
162 */
163 len += sprintf(page+len,
164 "MemTotal: %8lu kB\n"
165 "MemFree: %8lu kB\n"
166 "MemShared: %8lu kB\n"
167 "Buffers: %8lu kB\n"
168 "Cached: %8lu kB\n"
169 "SwapCached: %8lu kB\n"
170 "Active: %8u kB\n"
171 "Inactive: %8u kB\n"
172 "HighTotal: %8lu kB\n"
173 "HighFree: %8lu kB\n"
174 "LowTotal: %8lu kB\n"
175 "LowFree: %8lu kB\n"
176 "SwapTotal: %8lu kB\n"
177 "SwapFree: %8lu kB\n",
178 K(i.totalram),
179 K(i.freeram),
180 K(i.sharedram),
181 K(i.bufferram),
182 K(atomic_read(&page_cache_size) - swapper_space.nrpages),
183 K(swapper_space.nrpages),
184 K(nr_active_pages),
185 K(nr_inactive_pages),
186 K(i.totalhigh),
187 K(i.freehigh),
188 K(i.totalram-i.totalhigh),
189 K(i.freeram-i.freehigh),
190 K(i.totalswap),
191 K(i.freeswap));
192
193 return proc_calc_metrics(page, start, off, count, eof, len);
194 #undef B
195 #undef K
196 }
197
198 static int version_read_proc(char *page, char **start, off_t off,
199 int count, int *eof, void *data)
200 {
201 extern char *linux_banner;
202 int len;
203
204 strcpy(page, linux_banner);
205 len = strlen(page);
206 return proc_calc_metrics(page, start, off, count, eof, len);
207 }
208
209 static int cpuinfo_read_proc(char *page, char **start, off_t off,
210 int count, int *eof, void *data)
211 {
212 int len = get_cpuinfo(page);
213 return proc_calc_metrics(page, start, off, count, eof, len);
214 }
215
216 #ifdef CONFIG_PROC_HARDWARE
217 static int hardware_read_proc(char *page, char **start, off_t off,
218 int count, int *eof, void *data)
219 {
220 int len = get_hardware_list(page);
221 return proc_calc_metrics(page, start, off, count, eof, len);
222 }
223 #endif
224
225 #ifdef CONFIG_STRAM_PROC
226 static int stram_read_proc(char *page, char **start, off_t off,
227 int count, int *eof, void *data)
228 {
229 int len = get_stram_list(page);
230 return proc_calc_metrics(page, start, off, count, eof, len);
231 }
232 #endif
233
234 #ifdef CONFIG_DEBUG_MALLOC
235 static int malloc_read_proc(char *page, char **start, off_t off,
236 int count, int *eof, void *data)
237 {
238 int len = get_malloc(page);
239 return proc_calc_metrics(page, start, off, count, eof, len);
240 }
241 #endif
242
243 #ifdef CONFIG_MODULES
244 static int modules_read_proc(char *page, char **start, off_t off,
245 int count, int *eof, void *data)
246 {
247 int len = get_module_list(page);
248 return proc_calc_metrics(page, start, off, count, eof, len);
249 }
250
251 static int ksyms_read_proc(char *page, char **start, off_t off,
252 int count, int *eof, void *data)
253 {
254 int len = get_ksyms_list(page, start, off, count);
255 if (len < count) *eof = 1;
256 return len;
257 }
258 #endif
259
260 static int kstat_read_proc(char *page, char **start, off_t off,
261 int count, int *eof, void *data)
262 {
263 int i, len;
264 extern unsigned long total_forks;
265 unsigned long jif = jiffies;
266 unsigned int sum = 0, user = 0, nice = 0, system = 0;
267 int major, disk;
268
269 for (i = 0 ; i < smp_num_cpus; i++) {
270 int cpu = cpu_logical_map(i), j;
271
272 user += kstat.per_cpu_user[cpu];
273 nice += kstat.per_cpu_nice[cpu];
274 system += kstat.per_cpu_system[cpu];
275 #if !defined(CONFIG_ARCH_S390)
276 for (j = 0 ; j < NR_IRQS ; j++)
277 sum += kstat.irqs[cpu][j];
278 #endif
279 }
280
281 len = sprintf(page, "cpu %u %u %u %lu\n", user, nice, system,
282 jif * smp_num_cpus - (user + nice + system));
283 for (i = 0 ; i < smp_num_cpus; i++)
284 len += sprintf(page + len, "cpu%d %u %u %u %lu\n",
285 i,
286 kstat.per_cpu_user[cpu_logical_map(i)],
287 kstat.per_cpu_nice[cpu_logical_map(i)],
288 kstat.per_cpu_system[cpu_logical_map(i)],
289 jif - ( kstat.per_cpu_user[cpu_logical_map(i)]
290 + kstat.per_cpu_nice[cpu_logical_map(i)]
291 + kstat.per_cpu_system[cpu_logical_map(i)]));
292 len += sprintf(page + len,
293 "page %u %u\n"
294 "swap %u %u\n"
295 "intr %u",
296 kstat.pgpgin >> 1,
297 kstat.pgpgout >> 1,
298 kstat.pswpin,
299 kstat.pswpout,
300 sum
301 );
302 #if !defined(CONFIG_ARCH_S390)
303 for (i = 0 ; i < NR_IRQS ; i++)
304 len += sprintf(page + len, " %u", kstat_irqs(i));
305 #endif
306
307 len += sprintf(page + len, "\ndisk_io: ");
308
309 for (major = 0; major < DK_MAX_MAJOR; major++) {
310 for (disk = 0; disk < DK_MAX_DISK; disk++) {
311 int active = kstat.dk_drive[major][disk] +
312 kstat.dk_drive_rblk[major][disk] +
313 kstat.dk_drive_wblk[major][disk];
314 if (active)
315 len += sprintf(page + len,
316 "(%u,%u):(%u,%u,%u,%u,%u) ",
317 major, disk,
318 kstat.dk_drive[major][disk],
319 kstat.dk_drive_rio[major][disk],
320 kstat.dk_drive_rblk[major][disk],
321 kstat.dk_drive_wio[major][disk],
322 kstat.dk_drive_wblk[major][disk]
323 );
324 }
325 }
326
327 len += sprintf(page + len,
328 "\nctxt %u\n"
329 "btime %lu\n"
330 "processes %lu\n",
331 kstat.context_swtch,
332 xtime.tv_sec - jif / HZ,
333 total_forks);
334
335 return proc_calc_metrics(page, start, off, count, eof, len);
336 }
337
338 static int devices_read_proc(char *page, char **start, off_t off,
339 int count, int *eof, void *data)
340 {
341 int len = get_device_list(page);
342 return proc_calc_metrics(page, start, off, count, eof, len);
343 }
344
345 static int partitions_read_proc(char *page, char **start, off_t off,
346 int count, int *eof, void *data)
347 {
348 int len = get_partition_list(page, start, off, count);
349 if (len < count) *eof = 1;
350 return len;
351 }
352
353 #if !defined(CONFIG_ARCH_S390)
354 static int interrupts_read_proc(char *page, char **start, off_t off,
355 int count, int *eof, void *data)
356 {
357 int len = get_irq_list(page);
358 return proc_calc_metrics(page, start, off, count, eof, len);
359 }
360 #endif
361
362 static int filesystems_read_proc(char *page, char **start, off_t off,
363 int count, int *eof, void *data)
364 {
365 int len = get_filesystem_list(page);
366 return proc_calc_metrics(page, start, off, count, eof, len);
367 }
368
369 static int dma_read_proc(char *page, char **start, off_t off,
370 int count, int *eof, void *data)
371 {
372 int len = get_dma_list(page);
373 return proc_calc_metrics(page, start, off, count, eof, len);
374 }
375
376 static int ioports_read_proc(char *page, char **start, off_t off,
377 int count, int *eof, void *data)
378 {
379 int len = get_ioport_list(page);
380 return proc_calc_metrics(page, start, off, count, eof, len);
381 }
382
383 static int cmdline_read_proc(char *page, char **start, off_t off,
384 int count, int *eof, void *data)
385 {
386 extern char saved_command_line[];
387 int len;
388
389 len = sprintf(page, "%s\n", saved_command_line);
390 len = strlen(page);
391 return proc_calc_metrics(page, start, off, count, eof, len);
392 }
393
394 #ifdef CONFIG_SGI_DS1286
395 static int ds1286_read_proc(char *page, char **start, off_t off,
396 int count, int *eof, void *data)
397 {
398 int len = get_ds1286_status(page);
399 return proc_calc_metrics(page, start, off, count, eof, len);
400 }
401 #endif
402
403 static int locks_read_proc(char *page, char **start, off_t off,
404 int count, int *eof, void *data)
405 {
406 int len;
407 lock_kernel();
408 len = get_locks_status(page, start, off, count);
409 unlock_kernel();
410 if (len < count) *eof = 1;
411 return len;
412 }
413
414 static int mounts_read_proc(char *page, char **start, off_t off,
415 int count, int *eof, void *data)
416 {
417 int len = get_filesystem_info(page);
418 return proc_calc_metrics(page, start, off, count, eof, len);
419 }
420
421 static int execdomains_read_proc(char *page, char **start, off_t off,
422 int count, int *eof, void *data)
423 {
424 int len = get_exec_domain_list(page);
425 return proc_calc_metrics(page, start, off, count, eof, len);
426 }
427
428 static int swaps_read_proc(char *page, char **start, off_t off,
429 int count, int *eof, void *data)
430 {
431 int len = get_swaparea_info(page);
432 return proc_calc_metrics(page, start, off, count, eof, len);
433 }
434
435 static int memory_read_proc(char *page, char **start, off_t off,
436 int count, int *eof, void *data)
437 {
438 int len = get_mem_list(page);
439 return proc_calc_metrics(page, start, off, count, eof, len);
440 }
441
442 /*
443 * This function accesses profiling information. The returned data is
444 * binary: the sampling step and the actual contents of the profile
445 * buffer. Use of the program readprofile is recommended in order to
446 * get meaningful info out of these data.
447 */
448 static ssize_t read_profile(struct file *file, char *buf,
449 size_t count, loff_t *ppos)
450 {
451 unsigned long p = *ppos;
452 ssize_t read;
453 char * pnt;
454 unsigned int sample_step = 1 << prof_shift;
455
456 if (p >= (prof_len+1)*sizeof(unsigned int))
457 return 0;
458 if (count > (prof_len+1)*sizeof(unsigned int) - p)
459 count = (prof_len+1)*sizeof(unsigned int) - p;
460 read = 0;
461
462 while (p < sizeof(unsigned int) && count > 0) {
463 put_user(*((char *)(&sample_step)+p),buf);
464 buf++; p++; count--; read++;
465 }
466 pnt = (char *)prof_buffer + p - sizeof(unsigned int);
467 copy_to_user(buf,(void *)pnt,count);
468 read += count;
469 *ppos += read;
470 return read;
471 }
472
473 /*
474 * Writing to /proc/profile resets the counters
475 *
476 * Writing a 'profiling multiplier' value into it also re-sets the profiling
477 * interrupt frequency, on architectures that support this.
478 */
479 static ssize_t write_profile(struct file * file, const char * buf,
480 size_t count, loff_t *ppos)
481 {
482 #ifdef CONFIG_SMP
483 extern int setup_profiling_timer (unsigned int multiplier);
484
485 if (count==sizeof(int)) {
486 unsigned int multiplier;
487
488 if (copy_from_user(&multiplier, buf, sizeof(int)))
489 return -EFAULT;
490
491 if (setup_profiling_timer(multiplier))
492 return -EINVAL;
493 }
494 #endif
495
496 memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer));
497 return count;
498 }
499
500 static struct file_operations proc_profile_operations = {
501 read: read_profile,
502 write: write_profile,
503 };
504
505 struct proc_dir_entry *proc_root_kcore;
506
507 void __init proc_misc_init(void)
508 {
509 struct proc_dir_entry *entry;
510 static struct {
511 char *name;
512 int (*read_proc)(char*,char**,off_t,int,int*,void*);
513 } *p, simple_ones[] = {
514 {"loadavg", loadavg_read_proc},
515 {"uptime", uptime_read_proc},
516 {"meminfo", meminfo_read_proc},
517 {"version", version_read_proc},
518 {"cpuinfo", cpuinfo_read_proc},
519 #ifdef CONFIG_PROC_HARDWARE
520 {"hardware", hardware_read_proc},
521 #endif
522 #ifdef CONFIG_STRAM_PROC
523 {"stram", stram_read_proc},
524 #endif
525 #ifdef CONFIG_DEBUG_MALLOC
526 {"malloc", malloc_read_proc},
527 #endif
528 #ifdef CONFIG_MODULES
529 {"modules", modules_read_proc},
530 {"ksyms", ksyms_read_proc},
531 #endif
532 {"stat", kstat_read_proc},
533 {"devices", devices_read_proc},
534 {"partitions", partitions_read_proc},
535 #if !defined(CONFIG_ARCH_S390)
536 {"interrupts", interrupts_read_proc},
537 #endif
538 {"filesystems", filesystems_read_proc},
539 {"dma", dma_read_proc},
540 {"ioports", ioports_read_proc},
541 {"cmdline", cmdline_read_proc},
542 #ifdef CONFIG_SGI_DS1286
543 {"rtc", ds1286_read_proc},
544 #endif
545 {"locks", locks_read_proc},
546 {"mounts", mounts_read_proc},
547 {"swaps", swaps_read_proc},
548 {"iomem", memory_read_proc},
549 {"execdomains", execdomains_read_proc},
550 {NULL,}
551 };
552 for (p = simple_ones; p->name; p++)
553 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
554
555 /* And now for trickier ones */
556 entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
557 if (entry)
558 entry->proc_fops = &proc_kmsg_operations;
559 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
560 if (proc_root_kcore) {
561 proc_root_kcore->proc_fops = &proc_kcore_operations;
562 proc_root_kcore->size =
563 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
564 }
565 if (prof_shift) {
566 entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
567 if (entry) {
568 entry->proc_fops = &proc_profile_operations;
569 entry->size = (1+prof_len) * sizeof(unsigned int);
570 }
571 }
572 #ifdef CONFIG_PPC32
573 {
574 extern struct file_operations ppc_htab_operations;
575 entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
576 if (entry)
577 entry->proc_fops = &ppc_htab_operations;
578 }
579 #endif
580 entry = create_proc_read_entry("slabinfo", S_IWUSR | S_IRUGO, NULL,
581 slabinfo_read_proc, NULL);
582 if (entry)
583 entry->write_proc = slabinfo_write_proc;
584 }
585