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/string.h>
21 #include <linux/mman.h>
22 #include <linux/proc_fs.h>
23 #include <linux/ioport.h>
24 #include <linux/config.h>
26 #include <linux/pagemap.h>
27 #include <linux/swap.h>
28 #include <linux/slab.h>
29 #include <linux/smp.h>
30 #include <linux/signal.h>
31 #include <linux/module.h>
32 #include <linux/init.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_locks_status (char *, char **, off_t
, int);
65 extern int get_swaparea_info (char *);
66 #ifdef CONFIG_SGI_DS1286
67 extern int get_ds1286_status(char *);
70 static int loadavg_read_proc(char *page
, char **start
, off_t off
,
71 int count
, int *eof
, void *data
)
76 a
= avenrun
[0] + (FIXED_1
/200);
77 b
= avenrun
[1] + (FIXED_1
/200);
78 c
= avenrun
[2] + (FIXED_1
/200);
79 len
= sprintf(page
,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
80 LOAD_INT(a
), LOAD_FRAC(a
),
81 LOAD_INT(b
), LOAD_FRAC(b
),
82 LOAD_INT(c
), LOAD_FRAC(c
),
83 nr_running
, nr_threads
, last_pid
);
84 if (len
<= off
+count
) *eof
= 1;
87 if (len
>count
) len
= count
;
92 static int uptime_read_proc(char *page
, char **start
, off_t off
,
93 int count
, int *eof
, void *data
)
100 idle
= init_tasks
[0]->times
.tms_utime
+ init_tasks
[0]->times
.tms_stime
;
102 /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
103 that would overflow about every five days at HZ == 100.
104 Therefore the identity a = (a / b) * b + a % b is used so that it is
105 calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100.
106 The part in front of the '+' always evaluates as 0 (mod 100). All divisions
107 in the above formulas are truncating. For HZ being a power of 10, the
108 calculations simplify to the version in the #else part (if the printf
109 format is adapted to the same number of digits as zeroes in HZ.
112 len
= sprintf(page
,"%lu.%02lu %lu.%02lu\n",
114 (((uptime
% HZ
) * 100) / HZ
) % 100,
116 (((idle
% HZ
) * 100) / HZ
) % 100);
118 len
= sprintf(page
,"%lu.%02lu %lu.%02lu\n",
124 if (len
<= off
+count
) *eof
= 1;
127 if (len
>count
) len
= count
;
132 static int meminfo_read_proc(char *page
, char **start
, off_t off
,
133 int count
, int *eof
, void *data
)
139 * display in kilobytes.
141 #define K(x) ((x) << (PAGE_SHIFT - 10))
142 #define B(x) ((x) << PAGE_SHIFT)
145 len
= sprintf(page
, " total: used: free: shared: buffers: cached:\n"
146 "Mem: %8lu %8lu %8lu %8lu %8lu %8u\n"
147 "Swap: %8lu %8lu %8lu\n",
148 B(i
.totalram
), B(i
.totalram
-i
.freeram
), B(i
.freeram
),
149 B(i
.sharedram
), B(i
.bufferram
),
150 B(atomic_read(&page_cache_size
)), B(i
.totalswap
),
151 B(i
.totalswap
-i
.freeswap
), B(i
.freeswap
));
153 * Tagged format, for easy grepping and expansion.
154 * The above will go away eventually, once the tools
157 len
+= sprintf(page
+len
,
158 "MemTotal: %8lu kB\n"
160 "MemShared: %8lu kB\n"
163 "HighTotal: %8lu kB\n"
164 "HighFree: %8lu kB\n"
165 "LowTotal: %8lu kB\n"
167 "SwapTotal: %8lu kB\n"
168 "SwapFree: %8lu kB\n",
173 K(atomic_read(&page_cache_size
)),
176 K(i
.totalram
-i
.totalhigh
),
177 K(i
.freeram
-i
.freehigh
),
181 if (len
<= off
+count
) *eof
= 1;
184 if (len
>count
) len
= count
;
191 static int version_read_proc(char *page
, char **start
, off_t off
,
192 int count
, int *eof
, void *data
)
194 extern char *linux_banner
;
197 strcpy(page
, linux_banner
);
199 if (len
<= off
+count
) *eof
= 1;
202 if (len
>count
) len
= count
;
207 static int cpuinfo_read_proc(char *page
, char **start
, off_t off
,
208 int count
, int *eof
, void *data
)
210 int len
= get_cpuinfo(page
);
211 if (len
<= off
+count
) *eof
= 1;
214 if (len
>count
) len
= count
;
219 #ifdef CONFIG_PROC_HARDWARE
220 static int hardware_read_proc(char *page
, char **start
, off_t off
,
221 int count
, int *eof
, void *data
)
223 int len
= get_hardware_list(page
);
224 if (len
<= off
+count
) *eof
= 1;
227 if (len
>count
) len
= count
;
233 #ifdef CONFIG_STRAM_PROC
234 static int stram_read_proc(char *page
, char **start
, off_t off
,
235 int count
, int *eof
, void *data
)
237 int len
= get_stram_list(page
);
238 if (len
<= off
+count
) *eof
= 1;
241 if (len
>count
) len
= count
;
247 #ifdef CONFIG_DEBUG_MALLOC
248 static int malloc_read_proc(char *page
, char **start
, off_t off
,
249 int count
, int *eof
, void *data
)
251 int len
= get_malloc(page
);
252 if (len
<= off
+count
) *eof
= 1;
255 if (len
>count
) len
= count
;
261 #ifdef CONFIG_MODULES
262 static int modules_read_proc(char *page
, char **start
, off_t off
,
263 int count
, int *eof
, void *data
)
265 int len
= get_module_list(page
);
266 if (len
<= off
+count
) *eof
= 1;
269 if (len
>count
) len
= count
;
274 static int ksyms_read_proc(char *page
, char **start
, off_t off
,
275 int count
, int *eof
, void *data
)
277 int len
= get_ksyms_list(page
, start
, off
, count
);
278 if (len
< count
) *eof
= 1;
283 static int kstat_read_proc(char *page
, char **start
, off_t off
,
284 int count
, int *eof
, void *data
)
288 extern unsigned long total_forks
;
289 unsigned long jif
= jiffies
;
291 for (i
= 0 ; i
< NR_IRQS
; i
++)
292 sum
+= kstat_irqs(i
);
296 "cpu %u %u %u %lu\n",
300 jif
*smp_num_cpus
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
));
301 for (i
= 0 ; i
< smp_num_cpus
; i
++)
302 len
+= sprintf(page
+ len
, "cpu%d %u %u %u %lu\n",
304 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 jif
- ( kstat
.per_cpu_user
[cpu_logical_map(i
)] \
308 + kstat
.per_cpu_nice
[cpu_logical_map(i
)] \
309 + kstat
.per_cpu_system
[cpu_logical_map(i
)]));
310 len
+= sprintf(page
+ len
,
312 "disk_rio %u %u %u %u\n"
313 "disk_wio %u %u %u %u\n"
314 "disk_rblk %u %u %u %u\n"
315 "disk_wblk %u %u %u %u\n"
323 "disk_rio %u %u %u %u\n"
324 "disk_wio %u %u %u %u\n"
325 "disk_rblk %u %u %u %u\n"
326 "disk_wblk %u %u %u %u\n"
333 jif
*smp_num_cpus
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
),
335 kstat
.dk_drive
[0], kstat
.dk_drive
[1],
336 kstat
.dk_drive
[2], kstat
.dk_drive
[3],
337 kstat
.dk_drive_rio
[0], kstat
.dk_drive_rio
[1],
338 kstat
.dk_drive_rio
[2], kstat
.dk_drive_rio
[3],
339 kstat
.dk_drive_wio
[0], kstat
.dk_drive_wio
[1],
340 kstat
.dk_drive_wio
[2], kstat
.dk_drive_wio
[3],
341 kstat
.dk_drive_rblk
[0], kstat
.dk_drive_rblk
[1],
342 kstat
.dk_drive_rblk
[2], kstat
.dk_drive_rblk
[3],
343 kstat
.dk_drive_wblk
[0], kstat
.dk_drive_wblk
[1],
344 kstat
.dk_drive_wblk
[2], kstat
.dk_drive_wblk
[3],
350 for (i
= 0 ; i
< NR_IRQS
; i
++)
351 len
+= sprintf(page
+ len
, " %u", kstat_irqs(i
));
352 len
+= sprintf(page
+ len
,
357 xtime
.tv_sec
- jif
/ HZ
,
359 if (len
<= off
+count
) *eof
= 1;
362 if (len
>count
) len
= count
;
367 static int devices_read_proc(char *page
, char **start
, off_t off
,
368 int count
, int *eof
, void *data
)
370 int len
= get_device_list(page
);
371 if (len
<= off
+count
) *eof
= 1;
374 if (len
>count
) len
= count
;
379 static int partitions_read_proc(char *page
, char **start
, off_t off
,
380 int count
, int *eof
, void *data
)
382 int len
= get_partition_list(page
);
383 if (len
<= off
+count
) *eof
= 1;
386 if (len
>count
) len
= count
;
391 static int interrupts_read_proc(char *page
, char **start
, off_t off
,
392 int count
, int *eof
, void *data
)
394 int len
= get_irq_list(page
);
395 if (len
<= off
+count
) *eof
= 1;
398 if (len
>count
) len
= count
;
403 static int filesystems_read_proc(char *page
, char **start
, off_t off
,
404 int count
, int *eof
, void *data
)
406 int len
= get_filesystem_list(page
);
407 if (len
<= off
+count
) *eof
= 1;
410 if (len
>count
) len
= count
;
415 static int dma_read_proc(char *page
, char **start
, off_t off
,
416 int count
, int *eof
, void *data
)
418 int len
= get_dma_list(page
);
419 if (len
<= off
+count
) *eof
= 1;
422 if (len
>count
) len
= count
;
427 static int ioports_read_proc(char *page
, char **start
, off_t off
,
428 int count
, int *eof
, void *data
)
430 int len
= get_ioport_list(page
);
431 if (len
<= off
+count
) *eof
= 1;
434 if (len
>count
) len
= count
;
439 static int cmdline_read_proc(char *page
, char **start
, off_t off
,
440 int count
, int *eof
, void *data
)
442 extern char saved_command_line
[];
445 len
= sprintf(page
, "%s\n", saved_command_line
);
447 if (len
<= off
+count
) *eof
= 1;
450 if (len
>count
) len
= count
;
455 #ifdef CONFIG_SGI_DS1286
456 static int ds1286_read_proc(char *page
, char **start
, off_t off
,
457 int count
, int *eof
, void *data
)
459 int len
= get_ds1286_status(page
);
460 if (len
<= off
+count
) *eof
= 1;
463 if (len
>count
) len
= count
;
469 static int locks_read_proc(char *page
, char **start
, off_t off
,
470 int count
, int *eof
, void *data
)
472 int len
= get_locks_status(page
, start
, off
, count
);
473 if (len
< count
) *eof
= 1;
477 static int mounts_read_proc(char *page
, char **start
, off_t off
,
478 int count
, int *eof
, void *data
)
480 int len
= get_filesystem_info(page
);
481 if (len
<= off
+count
) *eof
= 1;
484 if (len
>count
) len
= count
;
489 static int execdomains_read_proc(char *page
, char **start
, off_t off
,
490 int count
, int *eof
, void *data
)
492 int len
= get_exec_domain_list(page
);
493 if (len
<= off
+count
) *eof
= 1;
496 if (len
>count
) len
= count
;
501 static int swaps_read_proc(char *page
, char **start
, off_t off
,
502 int count
, int *eof
, void *data
)
504 int len
= get_swaparea_info(page
);
505 if (len
<= off
+count
) *eof
= 1;
508 if (len
>count
) len
= count
;
513 static int slabinfo_read_proc(char *page
, char **start
, off_t off
,
514 int count
, int *eof
, void *data
)
516 int len
= get_slabinfo(page
);
517 if (len
<= off
+count
) *eof
= 1;
520 if (len
>count
) len
= count
;
525 static int memory_read_proc(char *page
, char **start
, off_t off
,
526 int count
, int *eof
, void *data
)
528 int len
= get_mem_list(page
);
529 if (len
<= off
+count
) *eof
= 1;
532 if (len
>count
) len
= count
;
538 * This function accesses profiling information. The returned data is
539 * binary: the sampling step and the actual contents of the profile
540 * buffer. Use of the program readprofile is recommended in order to
541 * get meaningful info out of these data.
543 static ssize_t
read_profile(struct file
*file
, char *buf
,
544 size_t count
, loff_t
*ppos
)
546 unsigned long p
= *ppos
;
549 unsigned int sample_step
= 1 << prof_shift
;
551 if (p
>= (prof_len
+1)*sizeof(unsigned int))
553 if (count
> (prof_len
+1)*sizeof(unsigned int) - p
)
554 count
= (prof_len
+1)*sizeof(unsigned int) - p
;
557 while (p
< sizeof(unsigned int) && count
> 0) {
558 put_user(*((char *)(&sample_step
)+p
),buf
);
559 buf
++; p
++; count
--; read
++;
561 pnt
= (char *)prof_buffer
+ p
- sizeof(unsigned int);
562 copy_to_user(buf
,(void *)pnt
,count
);
569 * Writing to /proc/profile resets the counters
571 * Writing a 'profiling multiplier' value into it also re-sets the profiling
572 * interrupt frequency, on architectures that support this.
574 static ssize_t
write_profile(struct file
* file
, const char * buf
,
575 size_t count
, loff_t
*ppos
)
578 extern int setup_profiling_timer (unsigned int multiplier
);
580 if (count
==sizeof(int)) {
581 unsigned int multiplier
;
583 if (copy_from_user(&multiplier
, buf
, sizeof(int)))
586 if (setup_profiling_timer(multiplier
))
591 memset(prof_buffer
, 0, prof_len
* sizeof(*prof_buffer
));
595 static struct file_operations proc_profile_operations
= {
597 write
: write_profile
,
600 struct proc_dir_entry
*proc_root_kcore
;
602 void __init
proc_misc_init(void)
604 struct proc_dir_entry
*entry
;
607 int (*read_proc
)(char*,char**,off_t
,int,int*,void*);
608 } *p
, simple_ones
[] = {
609 {"loadavg", loadavg_read_proc
},
610 {"uptime", uptime_read_proc
},
611 {"meminfo", meminfo_read_proc
},
612 {"version", version_read_proc
},
613 {"cpuinfo", cpuinfo_read_proc
},
614 #ifdef CONFIG_PROC_HARDWARE
615 {"hardware", hardware_read_proc
},
617 #ifdef CONFIG_STRAM_PROC
618 {"stram", stram_read_proc
},
620 #ifdef CONFIG_DEBUG_MALLOC
621 {"malloc", malloc_read_proc
},
623 #ifdef CONFIG_MODULES
624 {"modules", modules_read_proc
},
625 {"ksyms", ksyms_read_proc
},
627 {"stat", kstat_read_proc
},
628 {"devices", devices_read_proc
},
629 {"partitions", partitions_read_proc
},
630 {"interrupts", interrupts_read_proc
},
631 {"filesystems", filesystems_read_proc
},
632 {"dma", dma_read_proc
},
633 {"ioports", ioports_read_proc
},
634 {"cmdline", cmdline_read_proc
},
635 #ifdef CONFIG_SGI_DS1286
636 {"rtc", ds1286_read_proc
},
638 {"locks", locks_read_proc
},
639 {"mounts", mounts_read_proc
},
640 {"swaps", swaps_read_proc
},
641 {"slabinfo", slabinfo_read_proc
},
642 {"iomem", memory_read_proc
},
643 {"execdomains", execdomains_read_proc
},
646 for(p
=simple_ones
;p
->name
;p
++)
647 create_proc_read_entry(p
->name
, 0, NULL
, p
->read_proc
, NULL
);
649 /* And now for trickier ones */
650 entry
= create_proc_entry("kmsg", S_IRUSR
, &proc_root
);
652 entry
->proc_fops
= &proc_kmsg_operations
;
653 proc_root_kcore
= create_proc_entry("kcore", S_IRUSR
, NULL
);
654 if (proc_root_kcore
) {
655 proc_root_kcore
->proc_fops
= &proc_kcore_operations
;
656 proc_root_kcore
->size
=
657 (size_t)high_memory
- PAGE_OFFSET
+ PAGE_SIZE
;
660 entry
= create_proc_entry("profile", S_IWUSR
| S_IRUGO
, NULL
);
662 entry
->proc_fops
= &proc_profile_operations
;
663 entry
->size
= (1+prof_len
) * sizeof(unsigned int);
667 entry
= create_proc_entry("ppc_htab", S_IRUGO
|S_IWUSR
, NULL
);
669 entry
->proc_fops
= &ppc_htab_operations
;