2 * linux/fs/proc/proc_misc.c
4 * linux/fs/proc/array.c
5 * Copyright (C) 1992 by Linus Torvalds
6 * based on ideas by Darren Senn
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.
14 #include <linux/types.h>
15 #include <linux/errno.h>
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
18 #include <linux/kernel_stat.h>
19 #include <linux/tty.h>
20 #include <linux/user.h>
21 #include <linux/a.out.h>
22 #include <linux/string.h>
23 #include <linux/mman.h>
24 #include <linux/proc_fs.h>
25 #include <linux/ioport.h>
26 #include <linux/config.h>
28 #include <linux/pagemap.h>
29 #include <linux/swap.h>
30 #include <linux/slab.h>
31 #include <linux/smp.h>
32 #include <linux/signal.h>
34 #include <asm/uaccess.h>
35 #include <asm/pgtable.h>
39 #define LOAD_INT(x) ((x) >> FSHIFT)
40 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
42 * Warning: stuff below (imported functions) assumes that its output will fit
43 * into one page. For some of those functions it may be wrong. Moreover, we
44 * have a way to deal with that gracefully. Right now I used straightforward
45 * wrappers, but this needs further analysis wrt potential overflows.
47 extern int get_cpuinfo(char *);
48 extern int get_hardware_list(char *);
49 extern int get_stram_list(char *);
50 #ifdef CONFIG_DEBUG_MALLOC
51 extern int get_malloc(char * buffer
);
54 extern int get_module_list(char *);
55 extern int get_ksyms_list(char *, char **, off_t
, int);
57 extern int get_device_list(char *);
58 extern int get_partition_list(char *);
59 extern int get_filesystem_list(char *);
60 extern int get_filesystem_info(char *);
61 extern int get_exec_domain_list(char *);
62 extern int get_irq_list(char *);
63 extern int get_dma_list(char *);
64 extern int get_rtc_status (char *);
65 extern int get_locks_status (char *, char **, off_t
, int);
66 extern int get_swaparea_info (char *);
67 #ifdef CONFIG_SGI_DS1286
68 extern int get_ds1286_status(char *);
71 static int loadavg_read_proc(char *page
, char **start
, off_t off
,
72 int count
, int *eof
, void *data
)
77 a
= avenrun
[0] + (FIXED_1
/200);
78 b
= avenrun
[1] + (FIXED_1
/200);
79 c
= avenrun
[2] + (FIXED_1
/200);
80 len
= sprintf(page
,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
81 LOAD_INT(a
), LOAD_FRAC(a
),
82 LOAD_INT(b
), LOAD_FRAC(b
),
83 LOAD_INT(c
), LOAD_FRAC(c
),
84 nr_running
, nr_threads
, last_pid
);
85 if (len
<= off
+count
) *eof
= 1;
88 if (len
>count
) len
= count
;
93 static int uptime_read_proc(char *page
, char **start
, off_t off
,
94 int count
, int *eof
, void *data
)
101 idle
= init_tasks
[0]->times
.tms_utime
+ init_tasks
[0]->times
.tms_stime
;
103 /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
104 that would overflow about every five days at HZ == 100.
105 Therefore the identity a = (a / b) * b + a % b is used so that it is
106 calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100.
107 The part in front of the '+' always evaluates as 0 (mod 100). All divisions
108 in the above formulas are truncating. For HZ being a power of 10, the
109 calculations simplify to the version in the #else part (if the printf
110 format is adapted to the same number of digits as zeroes in HZ.
113 len
= sprintf(page
,"%lu.%02lu %lu.%02lu\n",
115 (((uptime
% HZ
) * 100) / HZ
) % 100,
117 (((idle
% HZ
) * 100) / HZ
) % 100);
119 len
= sprintf(page
,"%lu.%02lu %lu.%02lu\n",
125 if (len
<= off
+count
) *eof
= 1;
128 if (len
>count
) len
= count
;
133 static int meminfo_read_proc(char *page
, char **start
, off_t off
,
134 int count
, int *eof
, void *data
)
140 * display in kilobytes.
142 #define K(x) ((x) << (PAGE_SHIFT - 10))
143 #define B(x) ((x) << PAGE_SHIFT)
146 len
= sprintf(page
, " total: used: free: shared: buffers: cached:\n"
147 "Mem: %8lu %8lu %8lu %8lu %8lu %8u\n"
148 "Swap: %8lu %8lu %8lu\n",
149 B(i
.totalram
), B(i
.totalram
-i
.freeram
), B(i
.freeram
),
150 B(i
.sharedram
), B(i
.bufferram
),
151 B(atomic_read(&page_cache_size
)), B(i
.totalswap
),
152 B(i
.totalswap
-i
.freeswap
), B(i
.freeswap
));
154 * Tagged format, for easy grepping and expansion.
155 * The above will go away eventually, once the tools
158 len
+= sprintf(page
+len
,
159 "MemTotal: %8lu kB\n"
161 "MemShared: %8lu kB\n"
164 "HighTotal: %8lu kB\n"
165 "HighFree: %8lu kB\n"
166 "SwapTotal: %8lu kB\n"
167 "SwapFree: %8lu kB\n",
172 K(atomic_read(&page_cache_size
)),
178 if (len
<= off
+count
) *eof
= 1;
181 if (len
>count
) len
= count
;
188 static int version_read_proc(char *page
, char **start
, off_t off
,
189 int count
, int *eof
, void *data
)
191 extern char *linux_banner
;
194 strcpy(page
, linux_banner
);
196 if (len
<= off
+count
) *eof
= 1;
199 if (len
>count
) len
= count
;
204 static int cpuinfo_read_proc(char *page
, char **start
, off_t off
,
205 int count
, int *eof
, void *data
)
207 int len
= get_cpuinfo(page
);
208 if (len
<= off
+count
) *eof
= 1;
211 if (len
>count
) len
= count
;
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
)
220 int len
= get_hardware_list(page
);
221 if (len
<= off
+count
) *eof
= 1;
224 if (len
>count
) len
= count
;
230 #ifdef CONFIG_STRAM_PROC
231 static int stram_read_proc(char *page
, char **start
, off_t off
,
232 int count
, int *eof
, void *data
)
234 int len
= get_stram_list(page
);
235 if (len
<= off
+count
) *eof
= 1;
238 if (len
>count
) len
= count
;
244 #ifdef CONFIG_DEBUG_MALLOC
245 static int malloc_read_proc(char *page
, char **start
, off_t off
,
246 int count
, int *eof
, void *data
)
248 int len
= get_malloc(page
);
249 if (len
<= off
+count
) *eof
= 1;
252 if (len
>count
) len
= count
;
258 #ifdef CONFIG_MODULES
259 static int modules_read_proc(char *page
, char **start
, off_t off
,
260 int count
, int *eof
, void *data
)
262 int len
= get_module_list(page
);
263 if (len
<= off
+count
) *eof
= 1;
266 if (len
>count
) len
= count
;
271 static int ksyms_read_proc(char *page
, char **start
, off_t off
,
272 int count
, int *eof
, void *data
)
274 int len
= get_ksyms_list(page
, start
, off
, count
);
275 if (len
< count
) *eof
= 1;
280 static int kstat_read_proc(char *page
, char **start
, off_t off
,
281 int count
, int *eof
, void *data
)
285 extern unsigned long total_forks
;
286 unsigned long jif
= jiffies
;
288 for (i
= 0 ; i
< NR_IRQS
; i
++)
289 sum
+= kstat_irqs(i
);
293 "cpu %u %u %u %lu\n",
297 jif
*smp_num_cpus
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
));
298 for (i
= 0 ; i
< smp_num_cpus
; i
++)
299 len
+= sprintf(page
+ len
, "cpu%d %u %u %u %lu\n",
301 kstat
.per_cpu_user
[cpu_logical_map(i
)],
302 kstat
.per_cpu_nice
[cpu_logical_map(i
)],
303 kstat
.per_cpu_system
[cpu_logical_map(i
)],
304 jif
- ( kstat
.per_cpu_user
[cpu_logical_map(i
)] \
305 + kstat
.per_cpu_nice
[cpu_logical_map(i
)] \
306 + kstat
.per_cpu_system
[cpu_logical_map(i
)]));
307 len
+= sprintf(page
+ len
,
309 "disk_rio %u %u %u %u\n"
310 "disk_wio %u %u %u %u\n"
311 "disk_rblk %u %u %u %u\n"
312 "disk_wblk %u %u %u %u\n"
320 "disk_rio %u %u %u %u\n"
321 "disk_wio %u %u %u %u\n"
322 "disk_rblk %u %u %u %u\n"
323 "disk_wblk %u %u %u %u\n"
330 jif
*smp_num_cpus
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
),
332 kstat
.dk_drive
[0], kstat
.dk_drive
[1],
333 kstat
.dk_drive
[2], kstat
.dk_drive
[3],
334 kstat
.dk_drive_rio
[0], kstat
.dk_drive_rio
[1],
335 kstat
.dk_drive_rio
[2], kstat
.dk_drive_rio
[3],
336 kstat
.dk_drive_wio
[0], kstat
.dk_drive_wio
[1],
337 kstat
.dk_drive_wio
[2], kstat
.dk_drive_wio
[3],
338 kstat
.dk_drive_rblk
[0], kstat
.dk_drive_rblk
[1],
339 kstat
.dk_drive_rblk
[2], kstat
.dk_drive_rblk
[3],
340 kstat
.dk_drive_wblk
[0], kstat
.dk_drive_wblk
[1],
341 kstat
.dk_drive_wblk
[2], kstat
.dk_drive_wblk
[3],
347 for (i
= 0 ; i
< NR_IRQS
; i
++)
348 len
+= sprintf(page
+ len
, " %u", kstat_irqs(i
));
349 len
+= sprintf(page
+ len
,
354 xtime
.tv_sec
- jif
/ HZ
,
356 if (len
<= off
+count
) *eof
= 1;
359 if (len
>count
) len
= count
;
364 static int devices_read_proc(char *page
, char **start
, off_t off
,
365 int count
, int *eof
, void *data
)
367 int len
= get_device_list(page
);
368 if (len
<= off
+count
) *eof
= 1;
371 if (len
>count
) len
= count
;
376 static int partitions_read_proc(char *page
, char **start
, off_t off
,
377 int count
, int *eof
, void *data
)
379 int len
= get_partition_list(page
);
380 if (len
<= off
+count
) *eof
= 1;
383 if (len
>count
) len
= count
;
388 static int interrupts_read_proc(char *page
, char **start
, off_t off
,
389 int count
, int *eof
, void *data
)
391 int len
= get_irq_list(page
);
392 if (len
<= off
+count
) *eof
= 1;
395 if (len
>count
) len
= count
;
400 static int filesystems_read_proc(char *page
, char **start
, off_t off
,
401 int count
, int *eof
, void *data
)
403 int len
= get_filesystem_list(page
);
404 if (len
<= off
+count
) *eof
= 1;
407 if (len
>count
) len
= count
;
412 static int dma_read_proc(char *page
, char **start
, off_t off
,
413 int count
, int *eof
, void *data
)
415 int len
= get_dma_list(page
);
416 if (len
<= off
+count
) *eof
= 1;
419 if (len
>count
) len
= count
;
424 static int ioports_read_proc(char *page
, char **start
, off_t off
,
425 int count
, int *eof
, void *data
)
427 int len
= get_ioport_list(page
);
428 if (len
<= off
+count
) *eof
= 1;
431 if (len
>count
) len
= count
;
436 static int cmdline_read_proc(char *page
, char **start
, off_t off
,
437 int count
, int *eof
, void *data
)
439 extern char saved_command_line
[];
442 len
= sprintf(page
, "%s\n", saved_command_line
);
444 if (len
<= off
+count
) *eof
= 1;
447 if (len
>count
) len
= count
;
453 static int rtc_read_proc(char *page
, char **start
, off_t off
,
454 int count
, int *eof
, void *data
)
456 int len
= get_rtc_status(page
);
457 if (len
<= off
+count
) *eof
= 1;
460 if (len
>count
) len
= count
;
466 #ifdef CONFIG_SGI_DS1286
467 static int ds1286_read_proc(char *page
, char **start
, off_t off
,
468 int count
, int *eof
, void *data
)
470 int len
= get_ds1286_status(page
);
471 if (len
<= off
+count
) *eof
= 1;
474 if (len
>count
) len
= count
;
480 static int locks_read_proc(char *page
, char **start
, off_t off
,
481 int count
, int *eof
, void *data
)
483 int len
= get_locks_status(page
, start
, off
, count
);
484 if (len
< count
) *eof
= 1;
488 static int mounts_read_proc(char *page
, char **start
, off_t off
,
489 int count
, int *eof
, void *data
)
491 int len
= get_filesystem_info(page
);
492 if (len
<= off
+count
) *eof
= 1;
495 if (len
>count
) len
= count
;
500 static int execdomains_read_proc(char *page
, char **start
, off_t off
,
501 int count
, int *eof
, void *data
)
503 int len
= get_exec_domain_list(page
);
504 if (len
<= off
+count
) *eof
= 1;
507 if (len
>count
) len
= count
;
512 static int swaps_read_proc(char *page
, char **start
, off_t off
,
513 int count
, int *eof
, void *data
)
515 int len
= get_swaparea_info(page
);
516 if (len
<= off
+count
) *eof
= 1;
519 if (len
>count
) len
= count
;
524 static int slabinfo_read_proc(char *page
, char **start
, off_t off
,
525 int count
, int *eof
, void *data
)
527 int len
= get_slabinfo(page
);
528 if (len
<= off
+count
) *eof
= 1;
531 if (len
>count
) len
= count
;
536 static int memory_read_proc(char *page
, char **start
, off_t off
,
537 int count
, int *eof
, void *data
)
539 int len
= get_mem_list(page
);
540 if (len
<= off
+count
) *eof
= 1;
543 if (len
>count
) len
= count
;
548 static struct proc_dir_entry proc_root_kmsg
= {
550 S_IFREG
| S_IRUSR
, 1, 0, 0,
551 0, &proc_kmsg_inode_operations
553 static struct proc_dir_entry proc_root_kcore
= {
555 S_IFREG
| S_IRUSR
, 1, 0, 0,
556 0, &proc_kcore_inode_operations
558 static struct proc_dir_entry proc_root_profile
= {
560 S_IFREG
| S_IRUGO
| S_IWUSR
, 1, 0, 0,
561 0, &proc_profile_inode_operations
564 void proc_misc_init(void)
568 int (*read_proc
)(char*,char**,off_t
,int,int*,void*);
569 } *p
, simple_ones
[] = {
570 {"loadavg", loadavg_read_proc
},
571 {"uptime", uptime_read_proc
},
572 {"meminfo", meminfo_read_proc
},
573 {"version", version_read_proc
},
574 {"cpuinfo", cpuinfo_read_proc
},
575 #ifdef CONFIG_PROC_HARDWARE
576 {"hardware", hardware_read_proc
},
578 #ifdef CONFIG_STRAM_PROC
579 {"stram", stram_read_proc
},
581 #ifdef CONFIG_DEBUG_MALLOC
582 {"malloc", malloc_read_proc
},
584 #ifdef CONFIG_MODULES
585 {"modules", modules_read_proc
},
586 {"ksyms", ksyms_read_proc
},
588 {"stat", kstat_read_proc
},
589 {"devices", devices_read_proc
},
590 {"partitions", partitions_read_proc
},
591 {"interrupts", interrupts_read_proc
},
592 {"filesystems", filesystems_read_proc
},
593 {"dma", dma_read_proc
},
594 {"ioports", ioports_read_proc
},
595 {"cmdline", cmdline_read_proc
},
597 {"rtc", rtc_read_proc
},
599 #ifdef CONFIG_SGI_DS1286
600 {"rtc", ds1286_read_proc
},
602 {"locks", locks_read_proc
},
603 {"mounts", mounts_read_proc
},
604 {"swaps", swaps_read_proc
},
605 {"slabinfo", slabinfo_read_proc
},
606 {"iomem", memory_read_proc
},
607 {"execdomains", execdomains_read_proc
},
610 for(p
=simple_ones
;p
->name
;p
++)
611 create_proc_read_entry(p
->name
, 0, NULL
, p
->read_proc
, NULL
);
613 /* And now for trickier ones */
614 proc_register(&proc_root
, &proc_root_kmsg
);
615 proc_register(&proc_root
, &proc_root_kcore
);
616 proc_root_kcore
.size
= (MAP_NR(high_memory
) << PAGE_SHIFT
) + PAGE_SIZE
;
618 proc_register(&proc_root
, &proc_root_profile
);
619 proc_root_profile
.size
= (1+prof_len
) * sizeof(unsigned int);