2 * linux/fs/proc/array.c
4 * Copyright (C) 1992 by Linus Torvalds
5 * based on ideas by Darren Senn
8 * Michael. K. Johnson: stat,statm extensions.
9 * <johnsonm@stolaf.edu>
11 * Pauline Middelink : Made cmdline,envline only break at '\0's, to
12 * make sure SET_PROCTITLE works. Also removed
13 * bad '!' which forced address recalculation for
14 * EVERY character on the current page.
15 * <middelin@polyware.iaf.nl>
17 * Danny ter Haar : added cpuinfo
20 * Alessandro Rubini : profile extension.
21 * <rubini@ipvvis.unipv.it>
23 * Jeff Tranter : added BogoMips field to cpuinfo
24 * <Jeff_Tranter@Mitel.COM>
26 * Bruno Haible : remove 4K limit for the maps file
27 * <haible@ma2s2.mathematik.uni-karlsruhe.de>
29 * Yves Arrouye : remove removal of trailing spaces in get_array.
30 * <Yves.Arrouye@marin.fdn.fr>
32 * Jerome Forissier : added per-CPU time information to /proc/stat
33 * and /proc/<pid>/cpu extension
34 * <forissier@isia.cma.fr>
35 * - Incorporation and non-SMP safe operation
36 * of forissier patch in 2.1.78 by
37 * Hans Marcus <crowbar@concepts.nl>
39 * aeb@cwi.nl : /proc/partitions
42 #include <linux/types.h>
43 #include <linux/errno.h>
44 #include <linux/sched.h>
45 #include <linux/kernel.h>
46 #include <linux/kernel_stat.h>
47 #include <linux/tty.h>
48 #include <linux/user.h>
49 #include <linux/a.out.h>
50 #include <linux/string.h>
51 #include <linux/mman.h>
52 #include <linux/proc_fs.h>
53 #include <linux/ioport.h>
54 #include <linux/config.h>
56 #include <linux/pagemap.h>
57 #include <linux/swap.h>
58 #include <linux/slab.h>
59 #include <linux/smp.h>
60 #include <linux/signal.h>
62 #include <asm/uaccess.h>
63 #include <asm/pgtable.h>
66 #define LOAD_INT(x) ((x) >> FSHIFT)
67 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
69 #ifdef CONFIG_DEBUG_MALLOC
70 int get_malloc(char * buffer
);
74 static ssize_t
read_core(struct file
* file
, char * buf
,
75 size_t count
, loff_t
*ppos
)
77 unsigned long p
= *ppos
, memsize
;
82 #if defined (__i386__) || defined (__mc68000__)
83 # define FIRST_MAPPED PAGE_SIZE /* we don't have page 0 mapped on x86.. */
85 # define FIRST_MAPPED 0
88 memset(&dump
, 0, sizeof(struct user
));
90 dump
.u_dsize
= max_mapnr
;
92 dump
.start_data
= PAGE_OFFSET
;
95 memsize
= (max_mapnr
+ 1) << PAGE_SHIFT
;
98 if (count
> memsize
- p
)
102 if (p
< sizeof(struct user
) && count
> 0) {
104 if (p
+ count1
> sizeof(struct user
))
105 count1
= sizeof(struct user
)-p
;
106 pnt
= (char *) &dump
+ p
;
107 copy_to_user(buf
,(void *) pnt
, count1
);
114 if (count
> 0 && p
< PAGE_SIZE
+ FIRST_MAPPED
) {
115 count1
= PAGE_SIZE
+ FIRST_MAPPED
- p
;
118 clear_user(buf
, count1
);
125 copy_to_user(buf
, (void *) (PAGE_OFFSET
+p
-PAGE_SIZE
), count
);
132 static struct file_operations proc_kcore_operations
= {
137 struct inode_operations proc_kcore_inode_operations
= {
138 &proc_kcore_operations
,
142 * This function accesses profiling information. The returned data is
143 * binary: the sampling step and the actual contents of the profile
144 * buffer. Use of the program readprofile is recommended in order to
145 * get meaningful info out of these data.
147 static ssize_t
read_profile(struct file
*file
, char *buf
,
148 size_t count
, loff_t
*ppos
)
150 unsigned long p
= *ppos
;
153 unsigned int sample_step
= 1 << prof_shift
;
155 if (p
>= (prof_len
+1)*sizeof(unsigned int))
157 if (count
> (prof_len
+1)*sizeof(unsigned int) - p
)
158 count
= (prof_len
+1)*sizeof(unsigned int) - p
;
161 while (p
< sizeof(unsigned int) && count
> 0) {
162 put_user(*((char *)(&sample_step
)+p
),buf
);
163 buf
++; p
++; count
--; read
++;
165 pnt
= (char *)prof_buffer
+ p
- sizeof(unsigned int);
166 copy_to_user(buf
,(void *)pnt
,count
);
173 * Writing to /proc/profile resets the counters
175 * Writing a 'profiling multiplier' value into it also re-sets the profiling
176 * interrupt frequency, on architectures that support this.
178 static ssize_t
write_profile(struct file
* file
, const char * buf
,
179 size_t count
, loff_t
*ppos
)
182 extern int setup_profiling_timer (unsigned int multiplier
);
184 if (count
==sizeof(int)) {
185 unsigned int multiplier
;
187 if (copy_from_user(&multiplier
, buf
, sizeof(int)))
190 if (setup_profiling_timer(multiplier
))
195 memset(prof_buffer
, 0, prof_len
* sizeof(*prof_buffer
));
199 static struct file_operations proc_profile_operations
= {
205 struct inode_operations proc_profile_inode_operations
= {
206 &proc_profile_operations
,
210 static int get_loadavg(char * buffer
)
214 a
= avenrun
[0] + (FIXED_1
/200);
215 b
= avenrun
[1] + (FIXED_1
/200);
216 c
= avenrun
[2] + (FIXED_1
/200);
217 return sprintf(buffer
,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
218 LOAD_INT(a
), LOAD_FRAC(a
),
219 LOAD_INT(b
), LOAD_FRAC(b
),
220 LOAD_INT(c
), LOAD_FRAC(c
),
221 nr_running
, nr_tasks
, last_pid
);
224 static int get_kstat(char * buffer
)
228 extern unsigned long total_forks
;
231 ticks
= jiffies
* smp_num_cpus
;
232 for (i
= 0 ; i
< NR_IRQS
; i
++)
233 sum
+= kstat_irqs(i
);
236 len
= sprintf(buffer
,
237 "cpu %u %u %u %lu\n",
241 jiffies
*smp_num_cpus
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
));
242 for (i
= 0 ; i
< smp_num_cpus
; i
++)
243 len
+= sprintf(buffer
+ len
, "cpu%d %u %u %u %lu\n",
245 kstat
.per_cpu_user
[cpu_logical_map(i
)],
246 kstat
.per_cpu_nice
[cpu_logical_map(i
)],
247 kstat
.per_cpu_system
[cpu_logical_map(i
)],
248 jiffies
- ( kstat
.per_cpu_user
[cpu_logical_map(i
)] \
249 + kstat
.per_cpu_nice
[cpu_logical_map(i
)] \
250 + kstat
.per_cpu_system
[cpu_logical_map(i
)]));
251 len
+= sprintf(buffer
+ len
,
253 "disk_rio %u %u %u %u\n"
254 "disk_wio %u %u %u %u\n"
255 "disk_rblk %u %u %u %u\n"
256 "disk_wblk %u %u %u %u\n"
261 len
= sprintf(buffer
,
264 "disk_rio %u %u %u %u\n"
265 "disk_wio %u %u %u %u\n"
266 "disk_rblk %u %u %u %u\n"
267 "disk_wblk %u %u %u %u\n"
274 ticks
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
),
276 kstat
.dk_drive
[0], kstat
.dk_drive
[1],
277 kstat
.dk_drive
[2], kstat
.dk_drive
[3],
278 kstat
.dk_drive_rio
[0], kstat
.dk_drive_rio
[1],
279 kstat
.dk_drive_rio
[2], kstat
.dk_drive_rio
[3],
280 kstat
.dk_drive_wio
[0], kstat
.dk_drive_wio
[1],
281 kstat
.dk_drive_wio
[2], kstat
.dk_drive_wio
[3],
282 kstat
.dk_drive_rblk
[0], kstat
.dk_drive_rblk
[1],
283 kstat
.dk_drive_rblk
[2], kstat
.dk_drive_rblk
[3],
284 kstat
.dk_drive_wblk
[0], kstat
.dk_drive_wblk
[1],
285 kstat
.dk_drive_wblk
[2], kstat
.dk_drive_wblk
[3],
291 for (i
= 0 ; i
< NR_IRQS
; i
++)
292 len
+= sprintf(buffer
+ len
, " %u", kstat_irqs(i
));
293 len
+= sprintf(buffer
+ len
,
298 xtime
.tv_sec
- jiffies
/ HZ
,
304 static int get_uptime(char * buffer
)
306 unsigned long uptime
;
310 idle
= task
[0]->times
.tms_utime
+ task
[0]->times
.tms_stime
;
312 /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
313 that would overflow about every five days at HZ == 100.
314 Therefore the identity a = (a / b) * b + a % b is used so that it is
315 calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100.
316 The part in front of the '+' always evaluates as 0 (mod 100). All divisions
317 in the above formulas are truncating. For HZ being a power of 10, the
318 calculations simplify to the version in the #else part (if the printf
319 format is adapted to the same number of digits as zeroes in HZ.
322 return sprintf(buffer
,"%lu.%02lu %lu.%02lu\n",
324 (((uptime
% HZ
) * 100) / HZ
) % 100,
326 (((idle
% HZ
) * 100) / HZ
) % 100);
328 return sprintf(buffer
,"%lu.%02lu %lu.%02lu\n",
336 static int get_meminfo(char * buffer
)
343 len
= sprintf(buffer
, " total: used: free: shared: buffers: cached:\n"
344 "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n"
345 "Swap: %8lu %8lu %8lu\n",
346 i
.totalram
, i
.totalram
-i
.freeram
, i
.freeram
, i
.sharedram
, i
.bufferram
, page_cache_size
*PAGE_SIZE
,
347 i
.totalswap
, i
.totalswap
-i
.freeswap
, i
.freeswap
);
349 * Tagged format, for easy grepping and expansion. The above will go away
350 * eventually, once the tools have been updated.
352 return len
+ sprintf(buffer
+len
,
353 "MemTotal: %8lu kB\n"
355 "MemShared: %8lu kB\n"
358 "SwapTotal: %8lu kB\n"
359 "SwapFree: %8lu kB\n",
364 page_cache_size
<< (PAGE_SHIFT
- 10),
369 static int get_version(char * buffer
)
371 extern char *linux_banner
;
373 strcpy(buffer
, linux_banner
);
374 return strlen(buffer
);
377 static int get_cmdline(char * buffer
)
379 extern char saved_command_line
[];
381 return sprintf(buffer
, "%s\n", saved_command_line
);
384 static unsigned long get_phys_addr(struct task_struct
* p
, unsigned long ptr
)
390 if (!p
|| !p
->mm
|| ptr
>= TASK_SIZE
)
392 /* Check for NULL pgd .. shouldn't happen! */
394 printk("get_phys_addr: pid %d has NULL pgd!\n", p
->pid
);
398 page_dir
= pgd_offset(p
->mm
,ptr
);
399 if (pgd_none(*page_dir
))
401 if (pgd_bad(*page_dir
)) {
402 printk("bad page directory entry %08lx\n", pgd_val(*page_dir
));
406 page_middle
= pmd_offset(page_dir
,ptr
);
407 if (pmd_none(*page_middle
))
409 if (pmd_bad(*page_middle
)) {
410 printk("bad page middle entry %08lx\n", pmd_val(*page_middle
));
411 pmd_clear(page_middle
);
414 pte
= *pte_offset(page_middle
,ptr
);
415 if (!pte_present(pte
))
417 return pte_page(pte
) + (ptr
& ~PAGE_MASK
);
420 static int get_array(struct task_struct
*p
, unsigned long start
, unsigned long end
, char * buffer
)
423 int size
= 0, result
= 0;
429 addr
= get_phys_addr(p
, start
);
436 if (size
< PAGE_SIZE
)
442 if (!c
&& start
>= end
)
444 } while (addr
& ~PAGE_MASK
);
449 static int get_env(int pid
, char * buffer
)
451 struct task_struct
*p
;
453 read_lock(&tasklist_lock
);
454 p
= find_task_by_pid(pid
);
455 read_unlock(&tasklist_lock
); /* FIXME!! This should be done after the last use */
459 return get_array(p
, p
->mm
->env_start
, p
->mm
->env_end
, buffer
);
462 static int get_arg(int pid
, char * buffer
)
464 struct task_struct
*p
;
466 read_lock(&tasklist_lock
);
467 p
= find_task_by_pid(pid
);
468 read_unlock(&tasklist_lock
); /* FIXME!! This should be done after the last use */
471 return get_array(p
, p
->mm
->arg_start
, p
->mm
->arg_end
, buffer
);
475 * These bracket the sleeping functions..
477 extern void scheduling_functions_start_here(void);
478 extern void scheduling_functions_end_here(void);
479 #define first_sched ((unsigned long) scheduling_functions_start_here)
480 #define last_sched ((unsigned long) scheduling_functions_end_here)
482 static unsigned long get_wchan(struct task_struct
*p
)
484 if (!p
|| p
== current
|| p
->state
== TASK_RUNNING
)
486 #if defined(__i386__)
488 unsigned long ebp
, eip
;
489 unsigned long stack_page
;
492 stack_page
= 4096 + (unsigned long)p
;
497 if (ebp
< stack_page
|| ebp
>= 4092+stack_page
)
499 eip
= *(unsigned long *) (ebp
+4);
500 if (eip
< first_sched
|| eip
>= last_sched
)
502 ebp
= *(unsigned long *) ebp
;
503 } while (count
++ < 16);
505 #elif defined(__alpha__)
507 * This one depends on the frame size of schedule(). Do a
508 * "disass schedule" in gdb to find the frame size. Also, the
509 * code assumes that sleep_on() follows immediately after
510 * interruptible_sleep_on() and that add_timer() follows
511 * immediately after interruptible_sleep(). Ugly, isn't it?
512 * Maybe adding a wchan field to task_struct would be better,
516 unsigned long schedule_frame
;
519 pc
= thread_saved_pc(&p
->tss
);
520 if (pc
>= first_sched
&& pc
< last_sched
) {
521 schedule_frame
= ((unsigned long *)p
->tss
.ksp
)[6];
522 return ((unsigned long *)schedule_frame
)[12];
526 #elif defined(__mc68000__)
528 unsigned long fp
, pc
;
529 unsigned long stack_page
;
531 extern int sys_pause (void);
533 stack_page
= p
->kernel_stack_page
;
536 fp
= ((struct switch_stack
*)p
->tss
.ksp
)->a6
;
538 if (fp
< stack_page
|| fp
>= 4088+stack_page
)
540 pc
= ((unsigned long *)fp
)[1];
541 /* FIXME: This depends on the order of these functions. */
542 if (pc
< first_sched
|| pc
>= last_sched
)
544 fp
= *(unsigned long *) fp
;
545 } while (count
++ < 16);
547 #elif defined(__powerpc__)
548 return (p
->tss
.wchan
);
549 #elif defined (CONFIG_ARM)
551 unsigned long fp
, lr
;
552 unsigned long stack_page
;
555 stack_page
= 4096 + (unsigned long)p
;
556 fp
= get_css_fp (&p
->tss
);
558 if (fp
< stack_page
|| fp
> 4092+stack_page
)
560 lr
= pc_pointer (((unsigned long *)fp
)[-1]);
561 if (lr
< first_sched
|| lr
> last_sched
)
563 fp
= *(unsigned long *) (fp
- 12);
564 } while (count
++ < 16);
570 #if defined(__i386__)
571 # define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
572 # define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
573 #elif defined(__alpha__)
575 * See arch/alpha/kernel/ptrace.c for details.
577 # define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
578 + (long)&((struct pt_regs *)0)->reg)
579 # define KSTK_EIP(tsk) \
580 (*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk)))
581 # define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
582 #elif defined(CONFIG_ARM)
583 # define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
584 # define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
585 #elif defined(__mc68000__)
586 #define KSTK_EIP(tsk) \
588 unsigned long eip = 0; \
589 if ((tsk)->tss.esp0 > PAGE_SIZE && \
590 MAP_NR((tsk)->tss.esp0) < max_mapnr) \
591 eip = ((struct pt_regs *) (tsk)->tss.esp0)->pc; \
593 #define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
594 #elif defined(__powerpc__)
595 #define KSTK_EIP(tsk) ((tsk)->tss.regs->nip)
596 #define KSTK_ESP(tsk) ((tsk)->tss.regs->gpr[1])
597 #elif defined (__sparc_v9__)
598 # define KSTK_EIP(tsk) ((tsk)->tss.kregs->tpc)
599 # define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP])
600 #elif defined(__sparc__)
601 # define KSTK_EIP(tsk) ((tsk)->tss.kregs->pc)
602 # define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP])
605 /* Gcc optimizes away "strlen(x)" for constant x */
606 #define ADDBUF(buffer, string) \
607 do { memcpy(buffer, string, strlen(string)); \
608 buffer += strlen(string); } while (0)
610 static inline char * task_name(struct task_struct
*p
, char * buf
)
615 ADDBUF(buf
, "Name:\t");
619 unsigned char c
= *name
;
643 * The task state array is a strange "bitmap" of
644 * reasons to sleep. Thus "running" is zero, and
645 * you can test for combinations of others with
648 static const char *task_state_array
[] = {
649 "R (running)", /* 0 */
650 "S (sleeping)", /* 1 */
651 "D (disk sleep)", /* 2 */
652 "Z (zombie)", /* 4 */
653 "T (stopped)", /* 8 */
654 "W (paging)" /* 16 */
657 static inline const char * get_task_state(struct task_struct
*tsk
)
659 unsigned int state
= tsk
->state
& (TASK_RUNNING
|
661 TASK_UNINTERRUPTIBLE
|
665 const char **p
= &task_state_array
[0];
674 static inline char * task_state(struct task_struct
*p
, char *buffer
)
676 buffer
+= sprintf(buffer
,
680 "Uid:\t%d\t%d\t%d\t%d\n"
681 "Gid:\t%d\t%d\t%d\t%d\n",
683 p
->pid
, p
->p_pptr
->pid
,
684 p
->uid
, p
->euid
, p
->suid
, p
->fsuid
,
685 p
->gid
, p
->egid
, p
->sgid
, p
->fsgid
);
689 static inline char * task_mem(struct task_struct
*p
, char *buffer
)
691 struct mm_struct
* mm
= p
->mm
;
693 if (mm
&& mm
!= &init_mm
) {
694 struct vm_area_struct
* vma
= mm
->mmap
;
695 unsigned long data
= 0, stack
= 0;
696 unsigned long exec
= 0, lib
= 0;
698 for (vma
= mm
->mmap
; vma
; vma
= vma
->vm_next
) {
699 unsigned long len
= (vma
->vm_end
- vma
->vm_start
) >> 10;
702 if (vma
->vm_flags
& VM_GROWSDOWN
)
706 if (vma
->vm_flags
& VM_WRITE
)
708 if (vma
->vm_flags
& VM_EXEC
) {
710 if (vma
->vm_flags
& VM_EXECUTABLE
)
715 buffer
+= sprintf(buffer
,
723 mm
->total_vm
<< (PAGE_SHIFT
-10),
724 mm
->locked_vm
<< (PAGE_SHIFT
-10),
725 mm
->rss
<< (PAGE_SHIFT
-10),
732 static void collect_sigign_sigcatch(struct task_struct
*p
, sigset_t
*ign
,
735 struct k_sigaction
*k
;
743 for (i
= 1; i
<= _NSIG
; ++i
, ++k
) {
744 if (k
->sa
.sa_handler
== SIG_IGN
)
746 else if (k
->sa
.sa_handler
!= SIG_DFL
)
752 static inline char * task_sig(struct task_struct
*p
, char *buffer
)
756 buffer
+= sprintf(buffer
, "SigPnd:\t");
757 buffer
= render_sigset_t(&p
->signal
, buffer
);
759 buffer
+= sprintf(buffer
, "SigBlk:\t");
760 buffer
= render_sigset_t(&p
->blocked
, buffer
);
763 collect_sigign_sigcatch(p
, &ign
, &catch);
764 buffer
+= sprintf(buffer
, "SigIgn:\t");
765 buffer
= render_sigset_t(&ign
, buffer
);
767 buffer
+= sprintf(buffer
, "SigCgt:\t"); /* Linux 2.0 uses "SigCgt" */
768 buffer
= render_sigset_t(&catch, buffer
);
774 extern inline char *task_cap(struct task_struct
*p
, char *buffer
)
776 return buffer
+ sprintf(buffer
, "CapInh:\t%016x\n"
779 p
->cap_inheritable
.cap
,
780 p
->cap_permitted
.cap
,
781 p
->cap_effective
.cap
);
785 static int get_status(int pid
, char * buffer
)
787 char * orig
= buffer
;
788 struct task_struct
*tsk
;
790 read_lock(&tasklist_lock
);
791 tsk
= find_task_by_pid(pid
);
792 read_unlock(&tasklist_lock
); /* FIXME!! This should be done after the last use */
795 buffer
= task_name(tsk
, buffer
);
796 buffer
= task_state(tsk
, buffer
);
797 buffer
= task_mem(tsk
, buffer
);
798 buffer
= task_sig(tsk
, buffer
);
799 buffer
= task_cap(tsk
, buffer
);
800 return buffer
- orig
;
803 static int get_stat(int pid
, char * buffer
)
805 struct task_struct
*tsk
;
806 unsigned long vsize
, eip
, esp
, wchan
;
809 sigset_t sigign
, sigcatch
;
812 read_lock(&tasklist_lock
);
813 tsk
= find_task_by_pid(pid
);
814 read_unlock(&tasklist_lock
); /* FIXME!! This should be done after the last use */
817 state
= *get_task_state(tsk
);
818 vsize
= eip
= esp
= 0;
819 if (tsk
->mm
&& tsk
->mm
!= &init_mm
) {
820 struct vm_area_struct
*vma
= tsk
->mm
->mmap
;
822 vsize
+= vma
->vm_end
- vma
->vm_start
;
829 wchan
= get_wchan(tsk
);
831 collect_sigign_sigcatch(tsk
, &sigign
, &sigcatch
);
834 tty_pgrp
= tsk
->tty
->pgrp
;
838 /* scale priority and nice values from timeslices to -20..20 */
839 /* to make it look like a "normal" Unix priority/nice value */
840 priority
= tsk
->counter
;
841 priority
= 20 - (priority
* 10 + DEF_PRIORITY
/ 2) / DEF_PRIORITY
;
842 nice
= tsk
->priority
;
843 nice
= 20 - (nice
* 20 + DEF_PRIORITY
/ 2) / DEF_PRIORITY
;
845 return sprintf(buffer
,"%d (%s) %c %d %d %d %d %d %lu %lu \
846 %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
847 %lu %lu %lu %lu %lu %lu %lu %lu\n",
854 tsk
->tty
? kdev_t_to_nr(tsk
->tty
->device
) : 0,
861 tsk
->times
.tms_utime
,
862 tsk
->times
.tms_stime
,
863 tsk
->times
.tms_cutime
,
864 tsk
->times
.tms_cstime
,
871 tsk
->mm
? tsk
->mm
->rss
: 0, /* you might want to shift this left 3 */
872 tsk
->rlim
? tsk
->rlim
[RLIMIT_RSS
].rlim_cur
: 0,
873 tsk
->mm
? tsk
->mm
->start_code
: 0,
874 tsk
->mm
? tsk
->mm
->end_code
: 0,
875 tsk
->mm
? tsk
->mm
->start_stack
: 0,
878 /* The signal information here is obsolete.
879 * It must be decimal for Linux 2.0 compatibility.
880 * Use /proc/#/status for real-time signals.
882 tsk
->signal
.sig
[0] & 0x7fffffffUL
,
883 tsk
->blocked
.sig
[0] & 0x7fffffffUL
,
884 sigign
.sig
[0] & 0x7fffffffUL
,
885 sigcatch
.sig
[0] & 0x7fffffffUL
,
891 static inline void statm_pte_range(pmd_t
* pmd
, unsigned long address
, unsigned long size
,
892 int * pages
, int * shared
, int * dirty
, int * total
)
900 printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd
));
904 pte
= pte_offset(pmd
, address
);
905 address
&= ~PMD_MASK
;
906 end
= address
+ size
;
912 address
+= PAGE_SIZE
;
917 if (!pte_present(page
))
922 if (MAP_NR(pte_page(page
)) >= max_mapnr
)
924 if (atomic_read(&mem_map
[MAP_NR(pte_page(page
))].count
) > 1)
926 } while (address
< end
);
929 static inline void statm_pmd_range(pgd_t
* pgd
, unsigned long address
, unsigned long size
,
930 int * pages
, int * shared
, int * dirty
, int * total
)
938 printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd
));
942 pmd
= pmd_offset(pgd
, address
);
943 address
&= ~PGDIR_MASK
;
944 end
= address
+ size
;
945 if (end
> PGDIR_SIZE
)
948 statm_pte_range(pmd
, address
, end
- address
, pages
, shared
, dirty
, total
);
949 address
= (address
+ PMD_SIZE
) & PMD_MASK
;
951 } while (address
< end
);
954 static void statm_pgd_range(pgd_t
* pgd
, unsigned long address
, unsigned long end
,
955 int * pages
, int * shared
, int * dirty
, int * total
)
957 while (address
< end
) {
958 statm_pmd_range(pgd
, address
, end
- address
, pages
, shared
, dirty
, total
);
959 address
= (address
+ PGDIR_SIZE
) & PGDIR_MASK
;
964 static int get_statm(int pid
, char * buffer
)
966 struct task_struct
*tsk
;
967 int size
=0, resident
=0, share
=0, trs
=0, lrs
=0, drs
=0, dt
=0;
969 read_lock(&tasklist_lock
);
970 tsk
= find_task_by_pid(pid
);
971 read_unlock(&tasklist_lock
); /* FIXME!! This should be done after the last use */
974 if (tsk
->mm
&& tsk
->mm
!= &init_mm
) {
975 struct vm_area_struct
* vma
= tsk
->mm
->mmap
;
978 pgd_t
*pgd
= pgd_offset(tsk
->mm
, vma
->vm_start
);
979 int pages
= 0, shared
= 0, dirty
= 0, total
= 0;
981 statm_pgd_range(pgd
, vma
->vm_start
, vma
->vm_end
, &pages
, &shared
, &dirty
, &total
);
986 if (vma
->vm_flags
& VM_EXECUTABLE
)
987 trs
+= pages
; /* text */
988 else if (vma
->vm_flags
& VM_GROWSDOWN
)
989 drs
+= pages
; /* stack */
990 else if (vma
->vm_end
> 0x60000000)
991 lrs
+= pages
; /* library */
997 return sprintf(buffer
,"%d %d %d %d %d %d %d\n",
998 size
, resident
, share
, trs
, lrs
, drs
, dt
);
1002 * The way we support synthetic files > 4K
1003 * - without storing their contents in some buffer and
1004 * - without walking through the entire synthetic file until we reach the
1005 * position of the requested data
1006 * is to cleverly encode the current position in the file's f_pos field.
1007 * There is no requirement that a read() call which returns `count' bytes
1008 * of data increases f_pos by exactly `count'.
1010 * This idea is Linus' one. Bruno implemented it.
1014 * For the /proc/<pid>/maps file, we use fixed length records, each containing
1017 #define MAPS_LINE_LENGTH 4096
1018 #define MAPS_LINE_SHIFT 12
1020 * f_pos = (number of the vma in the task->mm->mmap list) * MAPS_LINE_LENGTH
1021 * + (index into the line)
1023 /* for systems with sizeof(void*) == 4: */
1024 #define MAPS_LINE_FORMAT4 "%08lx-%08lx %s %08lx %s %lu"
1025 #define MAPS_LINE_MAX4 49 /* sum of 8 1 8 1 4 1 8 1 5 1 10 1 */
1027 /* for systems with sizeof(void*) == 8: */
1028 #define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %s %lu"
1029 #define MAPS_LINE_MAX8 73 /* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */
1031 #define MAPS_LINE_MAX MAPS_LINE_MAX8
1034 static ssize_t
read_maps (int pid
, struct file
* file
, char * buf
,
1035 size_t count
, loff_t
*ppos
)
1037 struct task_struct
*p
;
1038 struct vm_area_struct
* map
, * next
;
1039 char * destptr
= buf
, * buffer
;
1046 * We might sleep getting the page, so get it first.
1049 buffer
= (char*)__get_free_page(GFP_KERNEL
);
1054 read_lock(&tasklist_lock
);
1055 p
= find_task_by_pid(pid
);
1056 read_unlock(&tasklist_lock
); /* FIXME!! This should be done after the last use */
1060 if (!p
->mm
|| p
->mm
== &init_mm
|| count
== 0)
1063 /* Check whether the mmaps could change if we sleep */
1064 volatile_task
= (p
!= current
|| atomic_read(&p
->mm
->count
) > 1);
1067 lineno
= *ppos
>> MAPS_LINE_SHIFT
;
1068 column
= *ppos
& (MAPS_LINE_LENGTH
-1);
1070 /* quickly go to line lineno */
1071 for (map
= p
->mm
->mmap
, i
= 0; map
&& (i
< lineno
); map
= map
->vm_next
, i
++)
1074 for ( ; map
; map
= next
) {
1075 /* produce the next line */
1077 char str
[5], *cp
= str
;
1081 int maxlen
= (sizeof(void*) == 4) ?
1082 MAPS_LINE_MAX4
: MAPS_LINE_MAX8
;
1086 * Get the next vma now (but it won't be used if we sleep).
1088 next
= map
->vm_next
;
1089 flags
= map
->vm_flags
;
1091 *cp
++ = flags
& VM_READ
? 'r' : '-';
1092 *cp
++ = flags
& VM_WRITE
? 'w' : '-';
1093 *cp
++ = flags
& VM_EXEC
? 'x' : '-';
1094 *cp
++ = flags
& VM_MAYSHARE
? 's' : 'p';
1099 if (map
->vm_file
!= NULL
) {
1100 dev
= map
->vm_file
->f_dentry
->d_inode
->i_dev
;
1101 ino
= map
->vm_file
->f_dentry
->d_inode
->i_ino
;
1102 line
= d_path(map
->vm_file
->f_dentry
, buffer
, PAGE_SIZE
);
1103 buffer
[PAGE_SIZE
-1] = '\n';
1111 sizeof(void*) == 4 ? MAPS_LINE_FORMAT4
: MAPS_LINE_FORMAT8
,
1112 map
->vm_start
, map
->vm_end
, str
, map
->vm_offset
,
1113 kdevname(dev
), ino
);
1116 for(i
= len
; i
< maxlen
; i
++)
1118 len
= buffer
+ PAGE_SIZE
- line
;
1121 if (column
>= len
) {
1122 column
= 0; /* continue with next line at column 0 */
1124 continue; /* we haven't slept */
1130 copy_to_user(destptr
, line
+column
, i
); /* may have slept */
1134 if (column
>= len
) {
1135 column
= 0; /* next time: next line at column 0 */
1143 /* By writing to user space, we might have slept.
1144 * Stop the loop, to avoid a race condition.
1151 *ppos
= (lineno
<< MAPS_LINE_SHIFT
) + column
;
1154 retval
= destptr
- buf
;
1157 free_page((unsigned long)buffer
);
1163 static int get_pidcpu(int pid
, char * buffer
)
1165 struct task_struct
* tsk
= current
;
1168 read_lock(&tasklist_lock
);
1169 if (pid
!= tsk
->pid
)
1170 tsk
= find_task_by_pid(pid
);
1171 read_unlock(&tasklist_lock
); /* FIXME!! This should be done after the last use */
1176 len
= sprintf(buffer
,
1178 tsk
->times
.tms_utime
,
1179 tsk
->times
.tms_stime
);
1181 for (i
= 0 ; i
< smp_num_cpus
; i
++)
1182 len
+= sprintf(buffer
+ len
, "cpu%d %lu %lu\n",
1184 tsk
->per_cpu_utime
[cpu_logical_map(i
)],
1185 tsk
->per_cpu_stime
[cpu_logical_map(i
)]);
1191 #ifdef CONFIG_MODULES
1192 extern int get_module_list(char *);
1193 extern int get_ksyms_list(char *, char **, off_t
, int);
1195 extern int get_device_list(char *);
1196 extern int get_partition_list(char *);
1197 extern int get_filesystem_list(char *);
1198 extern int get_filesystem_info( char * );
1199 extern int get_irq_list(char *);
1200 extern int get_dma_list(char *);
1201 extern int get_cpuinfo(char *);
1202 extern int get_pci_list(char *);
1203 extern int get_md_status (char *);
1204 extern int get_rtc_status (char *);
1205 extern int get_locks_status (char *, char **, off_t
, int);
1206 extern int get_swaparea_info (char *);
1207 extern int get_hardware_list(char *);
1208 extern int get_stram_list(char *);
1210 static long get_root_array(char * page
, int type
, char **start
,
1211 off_t offset
, unsigned long length
)
1215 return get_loadavg(page
);
1218 return get_uptime(page
);
1221 return get_meminfo(page
);
1223 #ifdef CONFIG_PCI_OLD_PROC
1225 return get_pci_list(page
);
1229 return get_cpuinfo(page
);
1232 return get_version(page
);
1234 #ifdef CONFIG_DEBUG_MALLOC
1236 return get_malloc(page
);
1239 #ifdef CONFIG_MODULES
1241 return get_module_list(page
);
1244 return get_ksyms_list(page
, start
, offset
, length
);
1248 return get_kstat(page
);
1251 return get_slabinfo(page
);
1254 return get_device_list(page
);
1256 case PROC_PARTITIONS
:
1257 return get_partition_list(page
);
1259 case PROC_INTERRUPTS
:
1260 return get_irq_list(page
);
1262 case PROC_FILESYSTEMS
:
1263 return get_filesystem_list(page
);
1266 return get_dma_list(page
);
1269 return get_ioport_list(page
);
1270 #ifdef CONFIG_BLK_DEV_MD
1272 return get_md_status(page
);
1275 return get_cmdline(page
);
1278 return get_filesystem_info( page
);
1281 return get_swaparea_info(page
);
1284 return get_rtc_status(page
);
1287 return get_locks_status(page
, start
, offset
, length
);
1288 #ifdef CONFIG_PROC_HARDWARE
1290 return get_hardware_list(page
);
1292 #ifdef CONFIG_STRAM_PROC
1294 return get_stram_list(page
);
1300 static int get_process_array(char * page
, int pid
, int type
)
1303 case PROC_PID_STATUS
:
1304 return get_status(pid
, page
);
1305 case PROC_PID_ENVIRON
:
1306 return get_env(pid
, page
);
1307 case PROC_PID_CMDLINE
:
1308 return get_arg(pid
, page
);
1310 return get_stat(pid
, page
);
1311 case PROC_PID_STATM
:
1312 return get_statm(pid
, page
);
1315 return get_pidcpu(pid
, page
);
1322 static inline int fill_array(char * page
, int pid
, int type
, char **start
, off_t offset
, int length
)
1325 return get_process_array(page
, pid
, type
);
1326 return get_root_array(page
, type
, start
, offset
, length
);
1329 #define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */
1331 static ssize_t
array_read(struct file
* file
, char * buf
,
1332 size_t count
, loff_t
*ppos
)
1334 struct inode
* inode
= file
->f_dentry
->d_inode
;
1339 unsigned int type
, pid
;
1340 struct proc_dir_entry
*dp
;
1342 if (count
> PROC_BLOCK_SIZE
)
1343 count
= PROC_BLOCK_SIZE
;
1344 if (!(page
= __get_free_page(GFP_KERNEL
)))
1346 type
= inode
->i_ino
;
1350 dp
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
1352 length
= dp
->get_info((char *)page
, &start
, *ppos
,
1355 length
= fill_array((char *) page
, pid
, type
,
1356 &start
, *ppos
, count
);
1361 if (start
!= NULL
) {
1362 /* We have had block-adjusting processing! */
1363 copy_to_user(buf
, start
, length
);
1367 /* Static 4kB (or whatever) block capacity */
1368 if (*ppos
>= length
) {
1372 if (count
+ *ppos
> length
)
1373 count
= length
- *ppos
;
1374 end
= count
+ *ppos
;
1375 copy_to_user(buf
, (char *) page
+ *ppos
, count
);
1382 static struct file_operations proc_array_operations
= {
1383 NULL
, /* array_lseek */
1385 NULL
, /* array_write */
1386 NULL
, /* array_readdir */
1387 NULL
, /* array_poll */
1388 NULL
, /* array_ioctl */
1390 NULL
, /* no special open code */
1391 NULL
, /* no special release code */
1392 NULL
/* can't fsync */
1395 struct inode_operations proc_array_inode_operations
= {
1396 &proc_array_operations
, /* default base directory file-ops */
1406 NULL
, /* readlink */
1407 NULL
, /* follow_link */
1408 NULL
, /* readpage */
1409 NULL
, /* writepage */
1411 NULL
, /* truncate */
1412 NULL
/* permission */
1415 static ssize_t
arraylong_read(struct file
* file
, char * buf
,
1416 size_t count
, loff_t
*ppos
)
1418 struct inode
* inode
= file
->f_dentry
->d_inode
;
1419 unsigned int pid
= inode
->i_ino
>> 16;
1420 unsigned int type
= inode
->i_ino
& 0x0000ffff;
1424 return read_maps(pid
, file
, buf
, count
, ppos
);
1429 static struct file_operations proc_arraylong_operations
= {
1430 NULL
, /* array_lseek */
1432 NULL
, /* array_write */
1433 NULL
, /* array_readdir */
1434 NULL
, /* array_poll */
1435 NULL
, /* array_ioctl */
1437 NULL
, /* no special open code */
1438 NULL
, /* no special release code */
1439 NULL
/* can't fsync */
1442 struct inode_operations proc_arraylong_inode_operations
= {
1443 &proc_arraylong_operations
, /* default base directory file-ops */
1453 NULL
, /* readlink */
1454 NULL
, /* follow_link */
1455 NULL
, /* readpage */
1456 NULL
, /* writepage */
1458 NULL
, /* truncate */
1459 NULL
/* permission */