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> 40 #include <linux/types.h> 41 #include <linux/errno.h> 42 #include <linux/sched.h> 43 #include <linux/kernel.h> 44 #include <linux/kernel_stat.h> 45 #include <linux/tty.h> 46 #include <linux/user.h> 47 #include <linux/a.out.h> 48 #include <linux/string.h> 49 #include <linux/mman.h> 50 #include <linux/proc_fs.h> 51 #include <linux/ioport.h> 52 #include <linux/config.h> 54 #include <linux/pagemap.h> 55 #include <linux/swap.h> 56 #include <linux/slab.h> 57 #include <linux/smp.h> 58 #include <linux/signal.h> 60 #include <asm/uaccess.h> 61 #include <asm/pgtable.h> 64 #define LOAD_INT(x) ((x) >> FSHIFT) 65 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) 67 #ifdef CONFIG_DEBUG_MALLOC 68 intget_malloc(char* buffer
); 72 static ssize_t
read_core(struct file
* file
,char* buf
, 73 size_t count
, loff_t
*ppos
) 75 unsigned long p
= *ppos
, memsize
; 80 #if defined (__i386__) || defined (__mc68000__) 81 # define FIRST_MAPPED PAGE_SIZE/* we don't have page 0 mapped on x86.. */ 83 # define FIRST_MAPPED 0 86 memset(&dump
,0,sizeof(struct user
)); 88 dump
.u_dsize
= max_mapnr
; 90 dump
.start_data
= PAGE_OFFSET
; 93 memsize
= (max_mapnr
+1) << PAGE_SHIFT
; 96 if(count
> memsize
- p
) 100 if(p
<sizeof(struct user
) && count
>0) { 102 if(p
+ count1
>sizeof(struct user
)) 103 count1
=sizeof(struct user
)-p
; 104 pnt
= (char*) &dump
+ p
; 105 copy_to_user(buf
,(void*) pnt
, count1
); 112 if(count
>0&& p
< PAGE_SIZE
+ FIRST_MAPPED
) { 113 count1
= PAGE_SIZE
+ FIRST_MAPPED
- p
; 116 clear_user(buf
, count1
); 123 copy_to_user(buf
, (void*) (PAGE_OFFSET
+p
-PAGE_SIZE
), count
); 130 static struct file_operations proc_kcore_operations
= { 135 struct inode_operations proc_kcore_inode_operations
= { 136 &proc_kcore_operations
, 140 * This function accesses profiling information. The returned data is 141 * binary: the sampling step and the actual contents of the profile 142 * buffer. Use of the program readprofile is recommended in order to 143 * get meaningful info out of these data. 145 static ssize_t
read_profile(struct file
*file
,char*buf
, 146 size_t count
, loff_t
*ppos
) 148 unsigned long p
= *ppos
; 151 unsigned int sample_step
=1<< prof_shift
; 153 if(p
>= (prof_len
+1)*sizeof(unsigned int)) 155 if(count
> (prof_len
+1)*sizeof(unsigned int) - p
) 156 count
= (prof_len
+1)*sizeof(unsigned int) - p
; 159 while(p
<sizeof(unsigned int) && count
>0) { 160 put_user(*((char*)(&sample_step
)+p
),buf
); 161 buf
++; p
++; count
--; read
++; 163 pnt
= (char*)prof_buffer
+ p
-sizeof(unsigned int); 164 copy_to_user(buf
,(void*)pnt
,count
); 171 * Writing to /proc/profile resets the counters 173 * Writing a 'profiling multiplier' value into it also re-sets the profiling 174 * interrupt frequency, on architectures that support this. 176 static ssize_t
write_profile(struct file
* file
,const char* buf
, 177 size_t count
, loff_t
*ppos
) 180 externintsetup_profiling_timer(unsigned int multiplier
); 182 if(count
==sizeof(int)) { 183 unsigned int multiplier
; 185 if(copy_from_user(&multiplier
, buf
,sizeof(int))) 188 if(setup_profiling_timer(multiplier
)) 193 memset(prof_buffer
,0, prof_len
*sizeof(*prof_buffer
)); 197 static struct file_operations proc_profile_operations
= { 203 struct inode_operations proc_profile_inode_operations
= { 204 &proc_profile_operations
, 208 static intget_loadavg(char* buffer
) 212 a
= avenrun
[0] + (FIXED_1
/200); 213 b
= avenrun
[1] + (FIXED_1
/200); 214 c
= avenrun
[2] + (FIXED_1
/200); 215 returnsprintf(buffer
,"%d.%02d %d.%02d %d.%02d %d/%d %d\n", 216 LOAD_INT(a
),LOAD_FRAC(a
), 217 LOAD_INT(b
),LOAD_FRAC(b
), 218 LOAD_INT(c
),LOAD_FRAC(c
), 219 nr_running
, nr_tasks
, last_pid
); 222 static intget_kstat(char* buffer
) 226 externunsigned long total_forks
; 229 ticks
= jiffies
* smp_num_cpus
; 230 for(i
=0; i
< NR_IRQS
; i
++) 235 "cpu %u %u %u %lu\n", 239 jiffies
*smp_num_cpus
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
)); 240 for(i
=0; i
< smp_num_cpus
; i
++) 241 len
+=sprintf(buffer
+ len
,"cpu%d %u %u %u %lu\n", 243 kstat
.per_cpu_user
[cpu_logical_map(i
)], 244 kstat
.per_cpu_nice
[cpu_logical_map(i
)], 245 kstat
.per_cpu_system
[cpu_logical_map(i
)], 246 jiffies
- ( kstat
.per_cpu_user
[cpu_logical_map(i
)] \
247 + kstat
.per_cpu_nice
[cpu_logical_map(i
)] \
248 + kstat
.per_cpu_system
[cpu_logical_map(i
)])); 249 len
+=sprintf(buffer
+ len
, 251 "disk_rio %u %u %u %u\n" 252 "disk_wio %u %u %u %u\n" 253 "disk_rblk %u %u %u %u\n" 254 "disk_wblk %u %u %u %u\n" 262 "disk_rio %u %u %u %u\n" 263 "disk_wio %u %u %u %u\n" 264 "disk_rblk %u %u %u %u\n" 265 "disk_wblk %u %u %u %u\n" 272 ticks
- (kstat
.cpu_user
+ kstat
.cpu_nice
+ kstat
.cpu_system
), 274 kstat
.dk_drive
[0], kstat
.dk_drive
[1], 275 kstat
.dk_drive
[2], kstat
.dk_drive
[3], 276 kstat
.dk_drive_rio
[0], kstat
.dk_drive_rio
[1], 277 kstat
.dk_drive_rio
[2], kstat
.dk_drive_rio
[3], 278 kstat
.dk_drive_wio
[0], kstat
.dk_drive_wio
[1], 279 kstat
.dk_drive_wio
[2], kstat
.dk_drive_wio
[3], 280 kstat
.dk_drive_rblk
[0], kstat
.dk_drive_rblk
[1], 281 kstat
.dk_drive_rblk
[2], kstat
.dk_drive_rblk
[3], 282 kstat
.dk_drive_wblk
[0], kstat
.dk_drive_wblk
[1], 283 kstat
.dk_drive_wblk
[2], kstat
.dk_drive_wblk
[3], 289 for(i
=0; i
< NR_IRQS
; i
++) 290 len
+=sprintf(buffer
+ len
," %u",kstat_irqs(i
)); 291 len
+=sprintf(buffer
+ len
, 296 xtime
.tv_sec
- jiffies
/ HZ
, 302 static intget_uptime(char* buffer
) 304 unsigned long uptime
; 308 idle
= task
[0]->times
.tms_utime
+ task
[0]->times
.tms_stime
; 310 /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but 311 that would overflow about every five days at HZ == 100. 312 Therefore the identity a = (a / b) * b + a % b is used so that it is 313 calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100. 314 The part in front of the '+' always evaluates as 0 (mod 100). All divisions 315 in the above formulas are truncating. For HZ being a power of 10, the 316 calculations simplify to the version in the #else part (if the printf 317 format is adapted to the same number of digits as zeroes in HZ. 320 returnsprintf(buffer
,"%lu.%02lu %lu.%02lu\n", 322 (((uptime
% HZ
) *100) / HZ
) %100, 324 (((idle
% HZ
) *100) / HZ
) %100); 326 returnsprintf(buffer
,"%lu.%02lu %lu.%02lu\n", 334 static intget_meminfo(char* buffer
) 341 len
=sprintf(buffer
," total: used: free: shared: buffers: cached:\n" 342 "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n" 343 "Swap: %8lu %8lu %8lu\n", 344 i
.totalram
, i
.totalram
-i
.freeram
, i
.freeram
, i
.sharedram
, i
.bufferram
, page_cache_size
*PAGE_SIZE
, 345 i
.totalswap
, i
.totalswap
-i
.freeswap
, i
.freeswap
); 347 * Tagged format, for easy grepping and expansion. The above will go away 348 * eventually, once the tools have been updated. 350 return len
+sprintf(buffer
+len
, 351 "MemTotal: %8lu kB\n" 353 "MemShared: %8lu kB\n" 356 "SwapTotal: %8lu kB\n" 357 "SwapFree: %8lu kB\n", 362 page_cache_size
<< (PAGE_SHIFT
-10), 367 static intget_version(char* buffer
) 369 externchar*linux_banner
; 371 strcpy(buffer
, linux_banner
); 372 returnstrlen(buffer
); 375 static intget_cmdline(char* buffer
) 377 externchar saved_command_line
[]; 379 returnsprintf(buffer
,"%s\n", saved_command_line
); 382 static unsigned longget_phys_addr(struct task_struct
* p
,unsigned long ptr
) 388 if(!p
|| !p
->mm
|| ptr
>= TASK_SIZE
) 390 /* Check for NULL pgd .. shouldn't happen! */ 392 printk("get_phys_addr: pid %d has NULL pgd!\n", p
->pid
); 396 page_dir
=pgd_offset(p
->mm
,ptr
); 397 if(pgd_none(*page_dir
)) 399 if(pgd_bad(*page_dir
)) { 400 printk("bad page directory entry %08lx\n",pgd_val(*page_dir
)); 404 page_middle
=pmd_offset(page_dir
,ptr
); 405 if(pmd_none(*page_middle
)) 407 if(pmd_bad(*page_middle
)) { 408 printk("bad page middle entry %08lx\n",pmd_val(*page_middle
)); 409 pmd_clear(page_middle
); 412 pte
= *pte_offset(page_middle
,ptr
); 413 if(!pte_present(pte
)) 415 returnpte_page(pte
) + (ptr
& ~PAGE_MASK
); 418 static intget_array(struct task_struct
*p
,unsigned long start
,unsigned long end
,char* buffer
) 421 int size
=0, result
=0; 427 addr
=get_phys_addr(p
, start
); 440 if(!c
&& start
>= end
) 442 }while(addr
& ~PAGE_MASK
); 447 static intget_env(int pid
,char* buffer
) 449 struct task_struct
*p
=find_task_by_pid(pid
); 453 returnget_array(p
, p
->mm
->env_start
, p
->mm
->env_end
, buffer
); 456 static intget_arg(int pid
,char* buffer
) 458 struct task_struct
*p
=find_task_by_pid(pid
); 462 returnget_array(p
, p
->mm
->arg_start
, p
->mm
->arg_end
, buffer
); 466 * These bracket the sleeping functions.. 468 externvoidscheduling_functions_start_here(void); 469 externvoidscheduling_functions_end_here(void); 470 #define first_sched ((unsigned long) scheduling_functions_start_here) 471 #define last_sched ((unsigned long) scheduling_functions_end_here) 473 static unsigned longget_wchan(struct task_struct
*p
) 475 if(!p
|| p
== current
|| p
->state
== TASK_RUNNING
) 477 #if defined(__i386__) 479 unsigned long ebp
, eip
; 480 unsigned long stack_page
; 483 stack_page
=4096+ (unsigned long)p
; 488 if(ebp
< stack_page
|| ebp
>=4092+stack_page
) 490 eip
= *(unsigned long*) (ebp
+4); 491 if(eip
< first_sched
|| eip
>= last_sched
) 493 ebp
= *(unsigned long*) ebp
; 496 #elif defined(__alpha__) 498 * This one depends on the frame size of schedule(). Do a 499 * "disass schedule" in gdb to find the frame size. Also, the 500 * code assumes that sleep_on() follows immediately after 501 * interruptible_sleep_on() and that add_timer() follows 502 * immediately after interruptible_sleep(). Ugly, isn't it? 503 * Maybe adding a wchan field to task_struct would be better, 507 unsigned long schedule_frame
; 510 pc
=thread_saved_pc(&p
->tss
); 511 if(pc
>= first_sched
&& pc
< last_sched
) { 512 schedule_frame
= ((unsigned long*)p
->tss
.ksp
)[6]; 513 return((unsigned long*)schedule_frame
)[12]; 517 #elif defined(__mc68000__) 519 unsigned long fp
, pc
; 520 unsigned long stack_page
; 522 externintsys_pause(void); 524 stack_page
= p
->kernel_stack_page
; 527 fp
= ((struct switch_stack
*)p
->tss
.ksp
)->a6
; 529 if(fp
< stack_page
|| fp
>=4088+stack_page
) 531 pc
= ((unsigned long*)fp
)[1]; 532 /* FIXME: This depends on the order of these functions. */ 533 if(pc
< first_sched
|| pc
>= last_sched
) 535 fp
= *(unsigned long*) fp
; 538 #elif defined(__powerpc__) 539 return(p
->tss
.wchan
); 544 #if defined(__i386__) 545 # define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) 546 # define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) 547 #elif defined(__alpha__) 549 * See arch/alpha/kernel/ptrace.c for details. 551 # define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \ 552 + (long)&((struct pt_regs *)0)->reg) 553 # define KSTK_EIP(tsk) \ 554 (*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk))) 555 # define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp) 556 #elif defined(__mc68000__) 557 #define KSTK_EIP(tsk) \ 559 unsigned long eip = 0; \ 560 if ((tsk)->tss.esp0 > PAGE_SIZE && \ 561 MAP_NR((tsk)->tss.esp0) < max_mapnr) \ 562 eip = ((struct pt_regs *) (tsk)->tss.esp0)->pc; \ 564 #define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp) 565 #elif defined(__powerpc__) 566 #define KSTK_EIP(tsk) ((tsk)->tss.regs->nip) 567 #define KSTK_ESP(tsk) ((tsk)->tss.regs->gpr[1]) 568 #elif defined (__sparc_v9__) 569 # define KSTK_EIP(tsk) ((tsk)->tss.kregs->tpc) 570 # define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP]) 571 #elif defined(__sparc__) 572 # define KSTK_EIP(tsk) ((tsk)->tss.kregs->pc) 573 # define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP]) 576 /* Gcc optimizes away "strlen(x)" for constant x */ 577 #define ADDBUF(buffer, string) \ 578 do { memcpy(buffer, string, strlen(string)); \ 579 buffer += strlen(string); } while (0) 581 staticinlinechar*task_name(struct task_struct
*p
,char* buf
) 586 ADDBUF(buf
,"Name:\t"); 590 unsigned char c
= *name
; 614 * The task state array is a strange "bitmap" of 615 * reasons to sleep. Thus "running" is zero, and 616 * you can test for combinations of others with 619 static const char*task_state_array
[] = { 620 "R (running)",/* 0 */ 621 "S (sleeping)",/* 1 */ 622 "D (disk sleep)",/* 2 */ 624 "T (stopped)",/* 8 */ 628 staticinlineconst char*get_task_state(struct task_struct
*tsk
) 630 unsigned int state
= tsk
->state
& (TASK_RUNNING
| 632 TASK_UNINTERRUPTIBLE
| 636 const char**p
= &task_state_array
[0]; 645 staticinlinechar*task_state(struct task_struct
*p
,char*buffer
) 647 buffer
+=sprintf(buffer
, 651 "Uid:\t%d\t%d\t%d\t%d\n" 652 "Gid:\t%d\t%d\t%d\t%d\n", 654 p
->pid
, p
->p_pptr
->pid
, 655 p
->uid
, p
->euid
, p
->suid
, p
->fsuid
, 656 p
->gid
, p
->egid
, p
->sgid
, p
->fsgid
); 660 staticinlinechar*task_mem(struct task_struct
*p
,char*buffer
) 662 struct mm_struct
* mm
= p
->mm
; 664 if(mm
&& mm
!= &init_mm
) { 665 struct vm_area_struct
* vma
= mm
->mmap
; 666 unsigned long data
=0, stack
=0; 667 unsigned long exec
=0, lib
=0; 669 for(vma
= mm
->mmap
; vma
; vma
= vma
->vm_next
) { 670 unsigned long len
= (vma
->vm_end
- vma
->vm_start
) >>10; 673 if(vma
->vm_flags
& VM_GROWSDOWN
) 677 if(vma
->vm_flags
& VM_WRITE
) 679 if(vma
->vm_flags
& VM_EXEC
) { 681 if(vma
->vm_flags
& VM_EXECUTABLE
) 686 buffer
+=sprintf(buffer
, 694 mm
->total_vm
<< (PAGE_SHIFT
-10), 695 mm
->locked_vm
<< (PAGE_SHIFT
-10), 696 mm
->rss
<< (PAGE_SHIFT
-10), 703 char*render_sigset_t(sigset_t
*set
,char*buffer
) 708 if(sigismember(set
, i
+1)) x
|=1; 709 if(sigismember(set
, i
+2)) x
|=2; 710 if(sigismember(set
, i
+3)) x
|=4; 711 if(sigismember(set
, i
+4)) x
|=8; 712 *buffer
++ = (x
<10?'0':'a'-10) + x
; 718 static voidcollect_sigign_sigcatch(struct task_struct
*p
, sigset_t
*ign
, 721 struct k_sigaction
*k
; 729 for(i
=1; i
<= _NSIG
; ++i
, ++k
) { 730 if(k
->sa
.sa_handler
== SIG_IGN
) 732 else if(k
->sa
.sa_handler
!= SIG_DFL
) 738 staticinlinechar*task_sig(struct task_struct
*p
,char*buffer
) 742 buffer
+=sprintf(buffer
,"SigPnd:\t"); 743 buffer
=render_sigset_t(&p
->signal
, buffer
); 745 buffer
+=sprintf(buffer
,"SigBlk:\t"); 746 buffer
=render_sigset_t(&p
->blocked
, buffer
); 749 collect_sigign_sigcatch(p
, &ign
, &catch); 750 buffer
+=sprintf(buffer
,"SigIgn:\t"); 751 buffer
=render_sigset_t(&ign
, buffer
); 753 buffer
+=sprintf(buffer
,"SigCat:\t"); 754 buffer
=render_sigset_t(&catch, buffer
); 760 static intget_status(int pid
,char* buffer
) 763 struct task_struct
*tsk
=find_task_by_pid(pid
); 767 buffer
=task_name(tsk
, buffer
); 768 buffer
=task_state(tsk
, buffer
); 769 buffer
=task_mem(tsk
, buffer
); 770 buffer
=task_sig(tsk
, buffer
); 771 return buffer
- orig
; 774 static intget_stat(int pid
,char* buffer
) 776 struct task_struct
*tsk
=find_task_by_pid(pid
); 777 unsigned long vsize
, eip
, esp
, wchan
; 780 sigset_t sigign
, sigcatch
; 781 char signal_str
[sizeof(sigset_t
)*2+1]; 782 char blocked_str
[sizeof(sigset_t
)*2+1]; 783 char sigign_str
[sizeof(sigset_t
)*2+1]; 784 char sigcatch_str
[sizeof(sigset_t
)*2+1]; 789 state
= *get_task_state(tsk
); 790 vsize
= eip
= esp
=0; 791 if(tsk
->mm
&& tsk
->mm
!= &init_mm
) { 792 struct vm_area_struct
*vma
= tsk
->mm
->mmap
; 794 vsize
+= vma
->vm_end
- vma
->vm_start
; 801 wchan
=get_wchan(tsk
); 803 collect_sigign_sigcatch(tsk
, &sigign
, &sigcatch
); 804 render_sigset_t(&tsk
->signal
, signal_str
); 805 render_sigset_t(&tsk
->blocked
, blocked_str
); 806 render_sigset_t(&sigign
, sigign_str
); 807 render_sigset_t(&sigcatch
, sigcatch_str
); 810 tty_pgrp
= tsk
->tty
->pgrp
; 814 /* scale priority and nice values from timeslices to -20..20 */ 815 /* to make it look like a "normal" unix priority/nice value */ 816 priority
= tsk
->counter
; 817 priority
=20- (priority
*10+ DEF_PRIORITY
/2) / DEF_PRIORITY
; 818 nice
= tsk
->priority
; 819 nice
=20- (nice
*20+ DEF_PRIORITY
/2) / DEF_PRIORITY
; 821 returnsprintf(buffer
,"%d (%s) %c %d %d %d %d %d %lu %lu \ 822 %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \ 823 %lu %s %s %s %s %lu %lu %lu\n", 830 tsk
->tty
?kdev_t_to_nr(tsk
->tty
->device
) :0, 837 tsk
->times
.tms_utime
, 838 tsk
->times
.tms_stime
, 839 tsk
->times
.tms_cutime
, 840 tsk
->times
.tms_cstime
, 847 tsk
->mm
? tsk
->mm
->rss
:0,/* you might want to shift this left 3 */ 848 tsk
->rlim
? tsk
->rlim
[RLIMIT_RSS
].rlim_cur
:0, 849 tsk
->mm
? tsk
->mm
->start_code
:0, 850 tsk
->mm
? tsk
->mm
->end_code
:0, 851 tsk
->mm
? tsk
->mm
->start_stack
:0, 863 staticinlinevoidstatm_pte_range(pmd_t
* pmd
,unsigned long address
,unsigned long size
, 864 int* pages
,int* shared
,int* dirty
,int* total
) 872 printk("statm_pte_range: bad pmd (%08lx)\n",pmd_val(*pmd
)); 876 pte
=pte_offset(pmd
, address
); 877 address
&= ~PMD_MASK
; 878 end
= address
+ size
; 884 address
+= PAGE_SIZE
; 889 if(!pte_present(page
)) 894 if(MAP_NR(pte_page(page
)) >= max_mapnr
) 896 if(atomic_read(&mem_map
[MAP_NR(pte_page(page
))].count
) >1) 898 }while(address
< end
); 901 staticinlinevoidstatm_pmd_range(pgd_t
* pgd
,unsigned long address
,unsigned long size
, 902 int* pages
,int* shared
,int* dirty
,int* total
) 910 printk("statm_pmd_range: bad pgd (%08lx)\n",pgd_val(*pgd
)); 914 pmd
=pmd_offset(pgd
, address
); 915 address
&= ~PGDIR_MASK
; 916 end
= address
+ size
; 920 statm_pte_range(pmd
, address
, end
- address
, pages
, shared
, dirty
, total
); 921 address
= (address
+ PMD_SIZE
) & PMD_MASK
; 923 }while(address
< end
); 926 static voidstatm_pgd_range(pgd_t
* pgd
,unsigned long address
,unsigned long end
, 927 int* pages
,int* shared
,int* dirty
,int* total
) 929 while(address
< end
) { 930 statm_pmd_range(pgd
, address
, end
- address
, pages
, shared
, dirty
, total
); 931 address
= (address
+ PGDIR_SIZE
) & PGDIR_MASK
; 936 static intget_statm(int pid
,char* buffer
) 938 struct task_struct
*tsk
=find_task_by_pid(pid
); 939 int size
=0, resident
=0, share
=0, trs
=0, lrs
=0, drs
=0, dt
=0; 943 if(tsk
->mm
&& tsk
->mm
!= &init_mm
) { 944 struct vm_area_struct
* vma
= tsk
->mm
->mmap
; 947 pgd_t
*pgd
=pgd_offset(tsk
->mm
, vma
->vm_start
); 948 int pages
=0, shared
=0, dirty
=0, total
=0; 950 statm_pgd_range(pgd
, vma
->vm_start
, vma
->vm_end
, &pages
, &shared
, &dirty
, &total
); 955 if(vma
->vm_flags
& VM_EXECUTABLE
) 956 trs
+= pages
;/* text */ 957 else if(vma
->vm_flags
& VM_GROWSDOWN
) 958 drs
+= pages
;/* stack */ 959 else if(vma
->vm_end
>0x60000000) 960 lrs
+= pages
;/* library */ 966 returnsprintf(buffer
,"%d %d %d %d %d %d %d\n", 967 size
, resident
, share
, trs
, lrs
, drs
, dt
); 971 * The way we support synthetic files > 4K 972 * - without storing their contents in some buffer and 973 * - without walking through the entire synthetic file until we reach the 974 * position of the requested data 975 * is to cleverly encode the current position in the file's f_pos field. 976 * There is no requirement that a read() call which returns `count' bytes 977 * of data increases f_pos by exactly `count'. 979 * This idea is Linus' one. Bruno implemented it. 983 * For the /proc/<pid>/maps file, we use fixed length records, each containing 986 #define MAPS_LINE_LENGTH 4096 987 #define MAPS_LINE_SHIFT 12 989 * f_pos = (number of the vma in the task->mm->mmap list) * MAPS_LINE_LENGTH 990 * + (index into the line) 992 /* for systems with sizeof(void*) == 4: */ 993 #define MAPS_LINE_FORMAT4"%08lx-%08lx %s %08lx %s %lu" 994 #define MAPS_LINE_MAX4 49/* sum of 8 1 8 1 4 1 8 1 5 1 10 1 */ 996 /* for systems with sizeof(void*) == 8: */ 997 #define MAPS_LINE_FORMAT8"%016lx-%016lx %s %016lx %s %lu" 998 #define MAPS_LINE_MAX8 73/* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */ 1000 #define MAPS_LINE_MAX MAPS_LINE_MAX8 1003 static ssize_t
read_maps(int pid
,struct file
* file
,char* buf
, 1004 size_t count
, loff_t
*ppos
) 1006 struct task_struct
*p
; 1007 struct vm_area_struct
* map
, * next
; 1008 char* destptr
= buf
, * buffer
; 1015 * We might sleep getting the page, so get it first. 1018 buffer
= (char*)__get_free_page(GFP_KERNEL
); 1023 p
=find_task_by_pid(pid
); 1027 if(!p
->mm
|| p
->mm
== &init_mm
|| count
==0) 1030 /* Check whether the mmaps could change if we sleep */ 1031 volatile_task
= (p
!= current
|| p
->mm
->count
>1); 1034 lineno
= *ppos
>> MAPS_LINE_SHIFT
; 1035 column
= *ppos
& (MAPS_LINE_LENGTH
-1); 1037 /* quickly go to line lineno */ 1038 for(map
= p
->mm
->mmap
, i
=0; map
&& (i
< lineno
); map
= map
->vm_next
, i
++) 1041 for( ; map
; map
= next
) { 1042 /* produce the next line */ 1044 char str
[5], *cp
= str
; 1048 int maxlen
= (sizeof(void*) ==4) ? 1049 MAPS_LINE_MAX4
: MAPS_LINE_MAX8
; 1053 * Get the next vma now (but it won't be used if we sleep). 1055 next
= map
->vm_next
; 1056 flags
= map
->vm_flags
; 1058 *cp
++ = flags
& VM_READ
?'r':'-'; 1059 *cp
++ = flags
& VM_WRITE
?'w':'-'; 1060 *cp
++ = flags
& VM_EXEC
?'x':'-'; 1061 *cp
++ = flags
& VM_MAYSHARE
?'s':'p'; 1066 if(map
->vm_file
!= NULL
) { 1067 dev
= map
->vm_file
->f_dentry
->d_inode
->i_dev
; 1068 ino
= map
->vm_file
->f_dentry
->d_inode
->i_ino
; 1069 line
=d_path(map
->vm_file
->f_dentry
, buffer
, PAGE_SIZE
); 1070 buffer
[PAGE_SIZE
-1] ='\n'; 1078 sizeof(void*) ==4? MAPS_LINE_FORMAT4
: MAPS_LINE_FORMAT8
, 1079 map
->vm_start
, map
->vm_end
, str
, map
->vm_offset
, 1080 kdevname(dev
), ino
); 1083 for(i
= len
; i
< maxlen
; i
++) 1085 len
= buffer
+ PAGE_SIZE
- line
; 1089 column
=0;/* continue with next line at column 0 */ 1091 continue;/* we haven't slept */ 1097 copy_to_user(destptr
, line
+column
, i
);/* may have slept */ 1102 column
=0;/* next time: next line at column 0 */ 1110 /* By writing to user space, we might have slept. 1111 * Stop the loop, to avoid a race condition. 1118 *ppos
= (lineno
<< MAPS_LINE_SHIFT
) + column
; 1121 retval
= destptr
- buf
; 1124 free_page((unsigned long)buffer
); 1130 static intget_pidcpu(int pid
,char* buffer
) 1132 struct task_struct
* tsk
= current
; 1136 tsk
=find_task_by_pid(pid
); 1141 len
=sprintf(buffer
, 1143 tsk
->times
.tms_utime
, 1144 tsk
->times
.tms_stime
); 1146 for(i
=0; i
< smp_num_cpus
; i
++) 1147 len
+=sprintf(buffer
+ len
,"cpu%d %lu %lu\n", 1149 tsk
->per_cpu_utime
[cpu_logical_map(i
)], 1150 tsk
->per_cpu_stime
[cpu_logical_map(i
)]); 1156 #ifdef CONFIG_MODULES 1157 externintget_module_list(char*); 1158 externintget_ksyms_list(char*,char**, off_t
,int); 1160 externintget_device_list(char*); 1161 externintget_filesystem_list(char*); 1162 externintget_filesystem_info(char* ); 1163 externintget_irq_list(char*); 1164 externintget_dma_list(char*); 1165 externintget_cpuinfo(char*); 1166 externintget_pci_list(char*); 1167 externintget_md_status(char*); 1168 externintget_rtc_status(char*); 1169 externintget_locks_status(char*,char**, off_t
,int); 1170 externintget_swaparea_info(char*); 1172 externintzorro_get_list(char*); 1174 #if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI) 1175 externintget_hardware_list(char*); 1178 static longget_root_array(char* page
,int type
,char**start
, 1179 off_t offset
,unsigned long length
) 1183 returnget_loadavg(page
); 1186 returnget_uptime(page
); 1189 returnget_meminfo(page
); 1191 #ifdef CONFIG_PCI_OLD_PROC 1193 returnget_pci_list(page
); 1197 returnget_cpuinfo(page
); 1200 returnget_version(page
); 1202 #ifdef CONFIG_DEBUG_MALLOC 1204 returnget_malloc(page
); 1207 #ifdef CONFIG_MODULES 1209 returnget_module_list(page
); 1212 returnget_ksyms_list(page
, start
, offset
, length
); 1216 returnget_kstat(page
); 1219 returnget_slabinfo(page
); 1222 returnget_device_list(page
); 1224 case PROC_INTERRUPTS
: 1225 returnget_irq_list(page
); 1227 case PROC_FILESYSTEMS
: 1228 returnget_filesystem_list(page
); 1231 returnget_dma_list(page
); 1234 returnget_ioport_list(page
); 1235 #ifdef CONFIG_BLK_DEV_MD 1237 returnget_md_status(page
); 1240 returnget_cmdline(page
); 1243 returnget_filesystem_info( page
); 1246 returnget_swaparea_info(page
); 1249 returnget_rtc_status(page
); 1252 returnget_locks_status(page
, start
, offset
, length
); 1255 returnzorro_get_list(page
); 1257 #if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI) 1259 returnget_hardware_list(page
); 1265 static intget_process_array(char* page
,int pid
,int type
) 1268 case PROC_PID_STATUS
: 1269 returnget_status(pid
, page
); 1270 case PROC_PID_ENVIRON
: 1271 returnget_env(pid
, page
); 1272 case PROC_PID_CMDLINE
: 1273 returnget_arg(pid
, page
); 1275 returnget_stat(pid
, page
); 1276 case PROC_PID_STATM
: 1277 returnget_statm(pid
, page
); 1280 returnget_pidcpu(pid
, page
); 1287 staticinlineintfill_array(char* page
,int pid
,int type
,char**start
, off_t offset
,int length
) 1290 returnget_process_array(page
, pid
, type
); 1291 returnget_root_array(page
, type
, start
, offset
, length
); 1294 #define PROC_BLOCK_SIZE (3*1024)/* 4K page size but our output routines use some slack for overruns */ 1296 static ssize_t
array_read(struct file
* file
,char* buf
, 1297 size_t count
, loff_t
*ppos
) 1299 struct inode
* inode
= file
->f_dentry
->d_inode
; 1304 unsigned int type
, pid
; 1305 struct proc_dir_entry
*dp
; 1307 if(count
> PROC_BLOCK_SIZE
) 1308 count
= PROC_BLOCK_SIZE
; 1309 if(!(page
=__get_free_page(GFP_KERNEL
))) 1311 type
= inode
->i_ino
; 1315 dp
= (struct proc_dir_entry
*) inode
->u
.generic_ip
; 1317 length
= dp
->get_info((char*)page
, &start
, *ppos
, 1320 length
=fill_array((char*) page
, pid
, type
, 1321 &start
, *ppos
, count
); 1327 /* We have had block-adjusting processing! */ 1328 copy_to_user(buf
, start
, length
); 1332 /* Static 4kB (or whatever) block capacity */ 1333 if(*ppos
>= length
) { 1337 if(count
+ *ppos
> length
) 1338 count
= length
- *ppos
; 1339 end
= count
+ *ppos
; 1340 copy_to_user(buf
, (char*) page
+ *ppos
, count
); 1347 static struct file_operations proc_array_operations
= { 1348 NULL
,/* array_lseek */ 1350 NULL
,/* array_write */ 1351 NULL
,/* array_readdir */ 1352 NULL
,/* array_poll */ 1353 NULL
,/* array_ioctl */ 1355 NULL
,/* no special open code */ 1356 NULL
,/* no special release code */ 1357 NULL
/* can't fsync */ 1360 struct inode_operations proc_array_inode_operations
= { 1361 &proc_array_operations
,/* default base directory file-ops */ 1372 NULL
,/* follow_link */ 1374 NULL
,/* writepage */ 1377 NULL
/* permission */ 1380 static ssize_t
arraylong_read(struct file
* file
,char* buf
, 1381 size_t count
, loff_t
*ppos
) 1383 struct inode
* inode
= file
->f_dentry
->d_inode
; 1384 unsigned int pid
= inode
->i_ino
>>16; 1385 unsigned int type
= inode
->i_ino
&0x0000ffff; 1389 returnread_maps(pid
, file
, buf
, count
, ppos
); 1394 static struct file_operations proc_arraylong_operations
= { 1395 NULL
,/* array_lseek */ 1397 NULL
,/* array_write */ 1398 NULL
,/* array_readdir */ 1399 NULL
,/* array_poll */ 1400 NULL
,/* array_ioctl */ 1402 NULL
,/* no special open code */ 1403 NULL
,/* no special release code */ 1404 NULL
/* can't fsync */ 1407 struct inode_operations proc_arraylong_inode_operations
= { 1408 &proc_arraylong_operations
,/* default base directory file-ops */ 1419 NULL
,/* follow_link */ 1421 NULL
,/* writepage */ 1424 NULL
/* permission */