This source file includes following definitions.
- read_core
- read_profile
- write_profile
- get_loadavg
- get_kstat
- get_uptime
- get_meminfo
- get_version
- get_cmdline
- get_task
- get_phys_addr
- get_array
- get_env
- get_arg
- get_wchan
- task_name
- task_state
- task_mem
- task_sig
- get_status
- get_stat
- statm_pte_range
- statm_pmd_range
- statm_pgd_range
- get_statm
- read_maps
- get_root_array
- get_process_array
- fill_array
- array_read
- arraylong_read
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/types.h>
31 #include <linux/errno.h>
32 #include <linux/sched.h>
33 #include <linux/kernel.h>
34 #include <linux/kernel_stat.h>
35 #include <linux/tty.h>
36 #include <linux/user.h>
37 #include <linux/a.out.h>
38 #include <linux/string.h>
39 #include <linux/mman.h>
40 #include <linux/proc_fs.h>
41 #include <linux/ioport.h>
42 #include <linux/config.h>
43 #include <linux/mm.h>
44 #include <linux/pagemap.h>
45 #include <linux/swap.h>
46
47 #include <asm/segment.h>
48 #include <asm/pgtable.h>
49 #include <asm/io.h>
50
51 #define LOAD_INT(x) ((x) >> FSHIFT)
52 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
53
54 #ifdef CONFIG_DEBUG_MALLOC
55 int get_malloc(char * buffer);
56 #endif
57
58
59 static int read_core(struct inode * inode, struct file * file,char * buf, int count)
60 {
61 unsigned long p = file->f_pos, memsize;
62 int read;
63 int count1;
64 char * pnt;
65 struct user dump;
66 #ifdef __i386__
67 # define FIRST_MAPPED PAGE_SIZE
68 #else
69 # define FIRST_MAPPED 0
70 #endif
71
72 memset(&dump, 0, sizeof(struct user));
73 dump.magic = CMAGIC;
74 dump.u_dsize = MAP_NR(high_memory);
75 #ifdef __alpha__
76 dump.start_data = PAGE_OFFSET;
77 #endif
78
79 if (count < 0)
80 return -EINVAL;
81 memsize = MAP_NR(high_memory + PAGE_SIZE) << PAGE_SHIFT;
82 if (p >= memsize)
83 return 0;
84 if (count > memsize - p)
85 count = memsize - p;
86 read = 0;
87
88 if (p < sizeof(struct user) && count > 0) {
89 count1 = count;
90 if (p + count1 > sizeof(struct user))
91 count1 = sizeof(struct user)-p;
92 pnt = (char *) &dump + p;
93 memcpy_tofs(buf,(void *) pnt, count1);
94 buf += count1;
95 p += count1;
96 count -= count1;
97 read += count1;
98 }
99
100 while (count > 0 && p < PAGE_SIZE + FIRST_MAPPED) {
101 put_user(0,buf);
102 buf++;
103 p++;
104 count--;
105 read++;
106 }
107 memcpy_tofs(buf, (void *) (PAGE_OFFSET + p - PAGE_SIZE), count);
108 read += count;
109 file->f_pos += read;
110 return read;
111 }
112
113 static struct file_operations proc_kcore_operations = {
114 NULL,
115 read_core,
116 };
117
118 struct inode_operations proc_kcore_inode_operations = {
119 &proc_kcore_operations,
120 };
121
122
123
124
125
126
127
128
129 static int read_profile(struct inode *inode, struct file *file, char *buf, int count)
130 {
131 unsigned long p = file->f_pos;
132 int read;
133 char * pnt;
134 unsigned int sample_step = 1 << prof_shift;
135
136 if (count < 0)
137 return -EINVAL;
138 if (p >= (prof_len+1)*sizeof(unsigned int))
139 return 0;
140 if (count > (prof_len+1)*sizeof(unsigned int) - p)
141 count = (prof_len+1)*sizeof(unsigned int) - p;
142 read = 0;
143
144 while (p < sizeof(unsigned int) && count > 0) {
145 put_user(*((char *)(&sample_step)+p),buf);
146 buf++; p++; count--; read++;
147 }
148 pnt = (char *)prof_buffer + p - sizeof(unsigned int);
149 memcpy_tofs(buf,(void *)pnt,count);
150 read += count;
151 file->f_pos += read;
152 return read;
153 }
154
155
156 static int write_profile(struct inode * inode, struct file * file, const char * buf, int count)
157 {
158 int i=prof_len;
159
160 while (i--)
161 prof_buffer[i]=0UL;
162 return count;
163 }
164
165 static struct file_operations proc_profile_operations = {
166 NULL,
167 read_profile,
168 write_profile,
169 };
170
171 struct inode_operations proc_profile_inode_operations = {
172 &proc_profile_operations,
173 };
174
175
176 static int get_loadavg(char * buffer)
177 {
178 int a, b, c;
179
180 a = avenrun[0] + (FIXED_1/200);
181 b = avenrun[1] + (FIXED_1/200);
182 c = avenrun[2] + (FIXED_1/200);
183 return sprintf(buffer,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
184 LOAD_INT(a), LOAD_FRAC(a),
185 LOAD_INT(b), LOAD_FRAC(b),
186 LOAD_INT(c), LOAD_FRAC(c),
187 nr_running, nr_tasks, last_pid);
188 }
189
190 static int get_kstat(char * buffer)
191 {
192 int i, len;
193 unsigned sum = 0;
194 extern unsigned long total_forks;
195
196 for (i = 0 ; i < NR_IRQS ; i++)
197 sum += kstat.interrupts[i];
198 len = sprintf(buffer,
199 "cpu %u %u %u %lu\n"
200 "disk %u %u %u %u\n"
201 "disk_rio %u %u %u %u\n"
202 "disk_wio %u %u %u %u\n"
203 "disk_rblk %u %u %u %u\n"
204 "disk_wblk %u %u %u %u\n"
205 "page %u %u\n"
206 "swap %u %u\n"
207 "intr %u",
208 kstat.cpu_user,
209 kstat.cpu_nice,
210 kstat.cpu_system,
211 jiffies - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system),
212 kstat.dk_drive[0], kstat.dk_drive[1],
213 kstat.dk_drive[2], kstat.dk_drive[3],
214 kstat.dk_drive_rio[0], kstat.dk_drive_rio[1],
215 kstat.dk_drive_rio[2], kstat.dk_drive_rio[3],
216 kstat.dk_drive_wio[0], kstat.dk_drive_wio[1],
217 kstat.dk_drive_wio[2], kstat.dk_drive_wio[3],
218 kstat.dk_drive_rblk[0], kstat.dk_drive_rblk[1],
219 kstat.dk_drive_rblk[2], kstat.dk_drive_rblk[3],
220 kstat.dk_drive_wblk[0], kstat.dk_drive_wblk[1],
221 kstat.dk_drive_wblk[2], kstat.dk_drive_wblk[3],
222 kstat.pgpgin,
223 kstat.pgpgout,
224 kstat.pswpin,
225 kstat.pswpout,
226 sum);
227 for (i = 0 ; i < NR_IRQS ; i++)
228 len += sprintf(buffer + len, " %u", kstat.interrupts[i]);
229 len += sprintf(buffer + len,
230 "\nctxt %u\n"
231 "btime %lu\n"
232 "processes %lu\n",
233 kstat.context_swtch,
234 xtime.tv_sec - jiffies / HZ,
235 total_forks);
236 return len;
237 }
238
239
240 static int get_uptime(char * buffer)
241 {
242 unsigned long uptime;
243 unsigned long idle;
244
245 uptime = jiffies;
246 idle = task[0]->utime + task[0]->stime;
247
248
249
250
251
252
253
254
255
256
257 #if HZ!=100
258 return sprintf(buffer,"%lu.%02lu %lu.%02lu\n",
259 uptime / HZ,
260 (((uptime % HZ) * 100) / HZ) % 100,
261 idle / HZ,
262 (((idle % HZ) * 100) / HZ) % 100);
263 #else
264 return sprintf(buffer,"%lu.%02lu %lu.%02lu\n",
265 uptime / HZ,
266 uptime % HZ,
267 idle / HZ,
268 idle % HZ);
269 #endif
270 }
271
272 static int get_meminfo(char * buffer)
273 {
274 struct sysinfo i;
275 int len;
276
277 si_meminfo(&i);
278 si_swapinfo(&i);
279 len = sprintf(buffer, " total: used: free: shared: buffers: cached:\n"
280 "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n"
281 "Swap: %8lu %8lu %8lu\n",
282 i.totalram, i.totalram-i.freeram, i.freeram, i.sharedram, i.bufferram, page_cache_size*PAGE_SIZE,
283 i.totalswap, i.totalswap-i.freeswap, i.freeswap);
284
285
286
287
288 return len + sprintf(buffer+len,
289 "MemTotal: %8lu kB\n"
290 "MemFree: %8lu kB\n"
291 "MemShared: %8lu kB\n"
292 "Buffers: %8lu kB\n"
293 "Cached: %8lu kB\n"
294 "SwapTotal: %8lu kB\n"
295 "SwapFree: %8lu kB\n",
296 i.totalram >> 10,
297 i.freeram >> 10,
298 i.sharedram >> 10,
299 i.bufferram >> 10,
300 page_cache_size << (PAGE_SHIFT - 10),
301 i.totalswap >> 10,
302 i.freeswap >> 10);
303 }
304
305 static int get_version(char * buffer)
306 {
307 extern char *linux_banner;
308
309 strcpy(buffer, linux_banner);
310 return strlen(buffer);
311 }
312
313 static int get_cmdline(char * buffer)
314 {
315 extern char saved_command_line[];
316
317 return sprintf(buffer, "%s\n", saved_command_line);
318 }
319
320 static struct task_struct ** get_task(pid_t pid)
321 {
322 struct task_struct ** p;
323
324 p = task;
325 while (++p < task+NR_TASKS) {
326 if (*p && (*p)->pid == pid)
327 return p;
328 }
329 return NULL;
330 }
331
332 static unsigned long get_phys_addr(struct task_struct * p, unsigned long ptr)
333 {
334 pgd_t *page_dir;
335 pmd_t *page_middle;
336 pte_t pte;
337
338 if (!p || !p->mm || ptr >= TASK_SIZE)
339 return 0;
340 page_dir = pgd_offset(p->mm,ptr);
341 if (pgd_none(*page_dir))
342 return 0;
343 if (pgd_bad(*page_dir)) {
344 printk("bad page directory entry %08lx\n", pgd_val(*page_dir));
345 pgd_clear(page_dir);
346 return 0;
347 }
348 page_middle = pmd_offset(page_dir,ptr);
349 if (pmd_none(*page_middle))
350 return 0;
351 if (pmd_bad(*page_middle)) {
352 printk("bad page middle entry %08lx\n", pmd_val(*page_middle));
353 pmd_clear(page_middle);
354 return 0;
355 }
356 pte = *pte_offset(page_middle,ptr);
357 if (!pte_present(pte))
358 return 0;
359 return pte_page(pte) + (ptr & ~PAGE_MASK);
360 }
361
362 static int get_array(struct task_struct ** p, unsigned long start, unsigned long end, char * buffer)
363 {
364 unsigned long addr;
365 int size = 0, result = 0;
366 char c;
367
368 if (start >= end)
369 return result;
370 for (;;) {
371 addr = get_phys_addr(*p, start);
372 if (!addr)
373 goto ready;
374 do {
375 c = *(char *) addr;
376 if (!c)
377 result = size;
378 if (size < PAGE_SIZE)
379 buffer[size++] = c;
380 else
381 goto ready;
382 addr++;
383 start++;
384 if (!c && start >= end)
385 goto ready;
386 } while (addr & ~PAGE_MASK);
387 }
388 ready:
389
390 while (result>0 && buffer[result-1]==' ')
391 result--;
392 return result;
393 }
394
395 static int get_env(int pid, char * buffer)
396 {
397 struct task_struct ** p = get_task(pid);
398
399 if (!p || !*p || !(*p)->mm)
400 return 0;
401 return get_array(p, (*p)->mm->env_start, (*p)->mm->env_end, buffer);
402 }
403
404 static int get_arg(int pid, char * buffer)
405 {
406 struct task_struct ** p = get_task(pid);
407
408 if (!p || !*p || !(*p)->mm)
409 return 0;
410 return get_array(p, (*p)->mm->arg_start, (*p)->mm->arg_end, buffer);
411 }
412
413 static unsigned long get_wchan(struct task_struct *p)
414 {
415 if (!p || p == current || p->state == TASK_RUNNING)
416 return 0;
417 #if defined(__i386__)
418 {
419 unsigned long ebp, eip;
420 unsigned long stack_page;
421 int count = 0;
422
423 stack_page = p->kernel_stack_page;
424 if (!stack_page)
425 return 0;
426 ebp = p->tss.ebp;
427 do {
428 if (ebp < stack_page || ebp >= 4092+stack_page)
429 return 0;
430 eip = *(unsigned long *) (ebp+4);
431 if ((void *)eip != sleep_on &&
432 (void *)eip != interruptible_sleep_on)
433 return eip;
434 ebp = *(unsigned long *) ebp;
435 } while (count++ < 16);
436 }
437 #elif defined(__alpha__)
438
439
440
441
442
443
444
445
446
447 {
448 unsigned long schedule_frame;
449 unsigned long pc;
450
451 pc = thread_saved_pc(&p->tss);
452 if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
453 schedule_frame = ((unsigned long *)p->tss.ksp)[6];
454 return ((unsigned long *)schedule_frame)[12];
455 }
456 return pc;
457 }
458 #endif
459 return 0;
460 }
461
462 #if defined(__i386__)
463 # define KSTK_EIP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1019])
464 # define KSTK_ESP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1022])
465 #elif defined(__alpha__)
466
467
468
469 # define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
470 + (long)&((struct pt_regs *)0)->reg)
471 # define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))
472 # define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
473 #elif defined(__sparc__)
474 # define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
475 + (long)&((struct pt_regs *)0)->reg)
476 # define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))
477 # define KSTK_ESP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(u_regs[UREG_FP])))
478 #endif
479
480
481 #define ADDBUF(buffer, string) \
482 do { memcpy(buffer, string, strlen(string)); \
483 buffer += strlen(string); } while (0)
484
485 static inline char * task_name(struct task_struct *p, char * buf)
486 {
487 int i;
488 char * name;
489
490 ADDBUF(buf, "Name:\t");
491 name = p->comm;
492 i = sizeof(p->comm);
493 do {
494 unsigned char c = *name;
495 name++;
496 i--;
497 *buf = c;
498 if (!c)
499 break;
500 if (c == '\\') {
501 buf[1] = c;
502 buf += 2;
503 continue;
504 }
505 if (c == '\n') {
506 buf[0] = '\\';
507 buf[1] = 'n';
508 buf += 2;
509 continue;
510 }
511 buf++;
512 } while (i);
513 *buf = '\n';
514 return buf+1;
515 }
516
517 static inline char * task_state(struct task_struct *p, char *buffer)
518 {
519 #define NR_STATES (sizeof(states)/sizeof(const char *))
520 unsigned int n = p->state;
521 static const char * states[] = {
522 "R (running)",
523 "S (sleeping)",
524 "D (disk sleep)",
525 "Z (zombie)",
526 "T (stopped)",
527 "W (paging)",
528 ". Huh?"
529 };
530
531 if (n >= NR_STATES)
532 n = NR_STATES-1;
533
534 buffer += sprintf(buffer,
535 "State:\t%s\n"
536 "Pid:\t%d\n"
537 "PPid:\t%d\n"
538 "Uid:\t%d\t%d\t%d\t%d\n"
539 "Gid:\t%d\t%d\t%d\t%d\n",
540 states[n],
541 p->pid, p->p_pptr->pid,
542 p->uid, p->euid, p->suid, p->fsuid,
543 p->gid, p->egid, p->sgid, p->fsgid);
544 return buffer;
545 }
546
547 static inline char * task_mem(struct task_struct *p, char *buffer)
548 {
549 struct mm_struct * mm = p->mm;
550
551 if (mm && mm != &init_mm) {
552 struct vm_area_struct * vma = mm->mmap;
553 unsigned long data = 0, stack = 0;
554 unsigned long exec = 0, lib = 0;
555
556 for (vma = mm->mmap; vma; vma = vma->vm_next) {
557 unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
558 if (!vma->vm_inode) {
559 data += len;
560 if (vma->vm_flags & VM_GROWSDOWN)
561 stack += len;
562 continue;
563 }
564 if (vma->vm_flags & VM_WRITE)
565 continue;
566 if (vma->vm_flags & VM_EXEC) {
567 exec += len;
568 if (vma->vm_flags & VM_EXECUTABLE)
569 continue;
570 lib += len;
571 }
572 }
573 buffer += sprintf(buffer,
574 "VmSize:\t%8lu kB\n"
575 "VmLck:\t%8lu kB\n"
576 "VmRSS:\t%8lu kB\n"
577 "VmData:\t%8lu kB\n"
578 "VmStk:\t%8lu kB\n"
579 "VmExe:\t%8lu kB\n"
580 "VmLib:\t%8lu kB\n",
581 mm->total_vm << (PAGE_SHIFT-10),
582 mm->locked_vm << (PAGE_SHIFT-10),
583 mm->rss << (PAGE_SHIFT-10),
584 data - stack, stack,
585 exec - lib, lib);
586 }
587 return buffer;
588 }
589
590 static inline char * task_sig(struct task_struct *p, char *buffer)
591 {
592 buffer += sprintf(buffer,
593 "SigPnd:\t%08lx\n"
594 "SigBlk:\t%08lx\n",
595 p->signal, p->blocked);
596 if (p->sig) {
597 struct sigaction * action = p->sig->action;
598 unsigned long sig_ign = 0, sig_caught = 0;
599 unsigned long bit = 1;
600 int i;
601
602 for (i = 0; i < 32; i++) {
603 switch((unsigned long) action->sa_handler) {
604 case 0:
605 break;
606 case 1:
607 sig_ign |= bit;
608 break;
609 default:
610 sig_caught |= bit;
611 }
612 bit <<= 1;
613 action++;
614 }
615
616 buffer += sprintf(buffer,
617 "SigIgn:\t%08lx\n"
618 "SigCgt:\t%08lx\n",
619 sig_ign, sig_caught);
620 }
621 return buffer;
622 }
623
624 static int get_status(int pid, char * buffer)
625 {
626 char * orig = buffer;
627 struct task_struct ** p = get_task(pid), *tsk;
628
629 if (!p || (tsk = *p) == NULL)
630 return 0;
631 buffer = task_name(tsk, buffer);
632 buffer = task_state(tsk, buffer);
633 buffer = task_mem(tsk, buffer);
634 buffer = task_sig(tsk, buffer);
635 return buffer - orig;
636 }
637
638 static int get_stat(int pid, char * buffer)
639 {
640 struct task_struct ** p = get_task(pid), *tsk;
641 unsigned long sigignore=0, sigcatch=0, wchan;
642 unsigned long vsize, eip, esp;
643 long priority, nice;
644 int i,tty_pgrp;
645 char state;
646
647 if (!p || (tsk = *p) == NULL)
648 return 0;
649 if (tsk->state < 0 || tsk->state > 5)
650 state = '.';
651 else
652 state = "RSDZTW"[tsk->state];
653 vsize = eip = esp = 0;
654 if (tsk->mm && tsk->mm != &init_mm) {
655 struct vm_area_struct *vma = tsk->mm->mmap;
656 while (vma) {
657 vsize += vma->vm_end - vma->vm_start;
658 vma = vma->vm_next;
659 }
660 if (tsk->kernel_stack_page) {
661 eip = KSTK_EIP(tsk);
662 esp = KSTK_ESP(tsk);
663 }
664 }
665 wchan = get_wchan(tsk);
666 if (tsk->sig) {
667 unsigned long bit = 1;
668 for(i=0; i<32; ++i) {
669 switch((unsigned long) tsk->sig->action[i].sa_handler) {
670 case 0:
671 break;
672 case 1:
673 sigignore |= bit;
674 break;
675 default:
676 sigcatch |= bit;
677 }
678 bit <<= 1;
679 }
680 }
681 if (tsk->tty)
682 tty_pgrp = tsk->tty->pgrp;
683 else
684 tty_pgrp = -1;
685
686
687
688 priority = tsk->counter;
689 priority = 20 - (priority * 10 + DEF_PRIORITY / 2) / DEF_PRIORITY;
690 nice = tsk->priority;
691 nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;
692
693 return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
694 %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
695 %lu %lu %lu %lu %lu %lu %lu %lu\n",
696 pid,
697 tsk->comm,
698 state,
699 tsk->p_pptr->pid,
700 tsk->pgrp,
701 tsk->session,
702 tsk->tty ? kdev_t_to_nr(tsk->tty->device) : 0,
703 tty_pgrp,
704 tsk->flags,
705 tsk->min_flt,
706 tsk->cmin_flt,
707 tsk->maj_flt,
708 tsk->cmaj_flt,
709 tsk->utime,
710 tsk->stime,
711 tsk->cutime,
712 tsk->cstime,
713 priority,
714 nice,
715 tsk->timeout,
716 tsk->it_real_value,
717 tsk->start_time,
718 vsize,
719 tsk->mm ? tsk->mm->rss : 0,
720 tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0,
721 tsk->mm ? tsk->mm->start_code : 0,
722 tsk->mm ? tsk->mm->end_code : 0,
723 tsk->mm ? tsk->mm->start_stack : 0,
724 esp,
725 eip,
726 tsk->signal,
727 tsk->blocked,
728 sigignore,
729 sigcatch,
730 wchan,
731 tsk->nswap,
732 tsk->cnswap);
733 }
734
735 static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
736 int * pages, int * shared, int * dirty, int * total)
737 {
738 pte_t * pte;
739 unsigned long end;
740
741 if (pmd_none(*pmd))
742 return;
743 if (pmd_bad(*pmd)) {
744 printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd));
745 pmd_clear(pmd);
746 return;
747 }
748 pte = pte_offset(pmd, address);
749 address &= ~PMD_MASK;
750 end = address + size;
751 if (end > PMD_SIZE)
752 end = PMD_SIZE;
753 do {
754 pte_t page = *pte;
755
756 address += PAGE_SIZE;
757 pte++;
758 if (pte_none(page))
759 continue;
760 ++*total;
761 if (!pte_present(page))
762 continue;
763 ++*pages;
764 if (pte_dirty(page))
765 ++*dirty;
766 if (pte_page(page) >= high_memory)
767 continue;
768 if (mem_map[MAP_NR(pte_page(page))].count > 1)
769 ++*shared;
770 } while (address < end);
771 }
772
773 static inline void statm_pmd_range(pgd_t * pgd, unsigned long address, unsigned long size,
774 int * pages, int * shared, int * dirty, int * total)
775 {
776 pmd_t * pmd;
777 unsigned long end;
778
779 if (pgd_none(*pgd))
780 return;
781 if (pgd_bad(*pgd)) {
782 printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd));
783 pgd_clear(pgd);
784 return;
785 }
786 pmd = pmd_offset(pgd, address);
787 address &= ~PGDIR_MASK;
788 end = address + size;
789 if (end > PGDIR_SIZE)
790 end = PGDIR_SIZE;
791 do {
792 statm_pte_range(pmd, address, end - address, pages, shared, dirty, total);
793 address = (address + PMD_SIZE) & PMD_MASK;
794 pmd++;
795 } while (address < end);
796 }
797
798 static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long end,
799 int * pages, int * shared, int * dirty, int * total)
800 {
801 while (address < end) {
802 statm_pmd_range(pgd, address, end - address, pages, shared, dirty, total);
803 address = (address + PGDIR_SIZE) & PGDIR_MASK;
804 pgd++;
805 }
806 }
807
808 static int get_statm(int pid, char * buffer)
809 {
810 struct task_struct ** p = get_task(pid), *tsk;
811 int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
812
813 if (!p || (tsk = *p) == NULL)
814 return 0;
815 if (tsk->mm && tsk->mm != &init_mm) {
816 struct vm_area_struct * vma = tsk->mm->mmap;
817
818 while (vma) {
819 pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start);
820 int pages = 0, shared = 0, dirty = 0, total = 0;
821
822 statm_pgd_range(pgd, vma->vm_start, vma->vm_end, &pages, &shared, &dirty, &total);
823 resident += pages;
824 share += shared;
825 dt += dirty;
826 size += total;
827 if (vma->vm_flags & VM_EXECUTABLE)
828 trs += pages;
829 else if (vma->vm_flags & VM_GROWSDOWN)
830 drs += pages;
831 else if (vma->vm_end > 0x60000000)
832 lrs += pages;
833 else
834 drs += pages;
835 vma = vma->vm_next;
836 }
837 }
838 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
839 size, resident, share, trs, lrs, drs, dt);
840 }
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858 #define MAPS_LINE_LENGTH 1024
859 #define MAPS_LINE_SHIFT 10
860
861
862
863
864 #define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %s %lu\n"
865 #define MAPS_LINE_MAX 49
866
867 static int read_maps (int pid, struct file * file, char * buf, int count)
868 {
869 struct task_struct ** p = get_task(pid);
870 char * destptr;
871 loff_t lineno;
872 int column;
873 struct vm_area_struct * map;
874 int i;
875
876 if (!p || !*p)
877 return -EINVAL;
878
879 if (!(*p)->mm || (*p)->mm == &init_mm || count == 0)
880 return 0;
881
882
883 lineno = file->f_pos >> MAPS_LINE_SHIFT;
884 column = file->f_pos & (MAPS_LINE_LENGTH-1);
885
886
887 for (map = (*p)->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++)
888 continue;
889
890 destptr = buf;
891
892 for ( ; map ; ) {
893
894 char line[MAPS_LINE_MAX+1];
895 char str[5], *cp = str;
896 int flags;
897 kdev_t dev;
898 unsigned long ino;
899 int len;
900
901 flags = map->vm_flags;
902
903 *cp++ = flags & VM_READ ? 'r' : '-';
904 *cp++ = flags & VM_WRITE ? 'w' : '-';
905 *cp++ = flags & VM_EXEC ? 'x' : '-';
906 *cp++ = flags & VM_MAYSHARE ? 's' : 'p';
907 *cp++ = 0;
908
909 if (map->vm_inode != NULL) {
910 dev = map->vm_inode->i_dev;
911 ino = map->vm_inode->i_ino;
912 } else {
913 dev = 0;
914 ino = 0;
915 }
916
917 len = sprintf(line, MAPS_LINE_FORMAT,
918 map->vm_start, map->vm_end, str, map->vm_offset,
919 kdevname(dev), ino);
920
921 if (column >= len) {
922 column = 0;
923 lineno++;
924 map = map->vm_next;
925 continue;
926 }
927
928 i = len-column;
929 if (i > count)
930 i = count;
931 memcpy_tofs(destptr, line+column, i);
932 destptr += i; count -= i;
933 column += i;
934 if (column >= len) {
935 column = 0;
936 lineno++;
937 map = map->vm_next;
938 }
939
940
941 if (count == 0)
942 break;
943
944
945
946
947 if (*p != current)
948 break;
949 }
950
951
952 file->f_pos = (lineno << MAPS_LINE_SHIFT) + column;
953
954 return destptr-buf;
955 }
956
957 #ifdef CONFIG_MODULES
958 extern int get_module_list(char *);
959 extern int get_ksyms_list(char *, char **, off_t, int);
960 #endif
961 extern int get_device_list(char *);
962 extern int get_filesystem_list(char *);
963 extern int get_filesystem_info( char * );
964 extern int get_irq_list(char *);
965 extern int get_dma_list(char *);
966 extern int get_cpuinfo(char *);
967 extern int get_pci_list(char*);
968 extern int get_md_status (char *);
969 extern int get_rtc_status (char *);
970 #ifdef __SMP_PROF__
971 extern int get_smp_prof_list(char *);
972 #endif
973
974 static int get_root_array(char * page, int type, char **start, off_t offset, int length)
975 {
976 switch (type) {
977 case PROC_LOADAVG:
978 return get_loadavg(page);
979
980 case PROC_UPTIME:
981 return get_uptime(page);
982
983 case PROC_MEMINFO:
984 return get_meminfo(page);
985
986 #ifdef CONFIG_PCI
987 case PROC_PCI:
988 return get_pci_list(page);
989 #endif
990
991 case PROC_CPUINFO:
992 return get_cpuinfo(page);
993
994 case PROC_VERSION:
995 return get_version(page);
996
997 #ifdef CONFIG_DEBUG_MALLOC
998 case PROC_MALLOC:
999 return get_malloc(page);
1000 #endif
1001
1002 #ifdef CONFIG_MODULES
1003 case PROC_MODULES:
1004 return get_module_list(page);
1005
1006 case PROC_KSYMS:
1007 return get_ksyms_list(page, start, offset, length);
1008 #endif
1009
1010 case PROC_STAT:
1011 return get_kstat(page);
1012
1013 case PROC_DEVICES:
1014 return get_device_list(page);
1015
1016 case PROC_INTERRUPTS:
1017 return get_irq_list(page);
1018
1019 case PROC_FILESYSTEMS:
1020 return get_filesystem_list(page);
1021
1022 case PROC_DMA:
1023 return get_dma_list(page);
1024
1025 case PROC_IOPORTS:
1026 return get_ioport_list(page);
1027 #ifdef CONFIG_BLK_DEV_MD
1028 case PROC_MD:
1029 return get_md_status(page);
1030 #endif
1031 #ifdef __SMP_PROF__
1032 case PROC_SMP_PROF:
1033 return get_smp_prof_list(page);
1034 #endif
1035 case PROC_CMDLINE:
1036 return get_cmdline(page);
1037
1038 case PROC_MTAB:
1039 return get_filesystem_info( page );
1040 #ifdef CONFIG_RTC
1041 case PROC_RTC:
1042 return get_rtc_status(page);
1043 #endif
1044 }
1045 return -EBADF;
1046 }
1047
1048 static int get_process_array(char * page, int pid, int type)
1049 {
1050 switch (type) {
1051 case PROC_PID_STATUS:
1052 return get_status(pid, page);
1053 case PROC_PID_ENVIRON:
1054 return get_env(pid, page);
1055 case PROC_PID_CMDLINE:
1056 return get_arg(pid, page);
1057 case PROC_PID_STAT:
1058 return get_stat(pid, page);
1059 case PROC_PID_STATM:
1060 return get_statm(pid, page);
1061 }
1062 return -EBADF;
1063 }
1064
1065
1066 static inline int fill_array(char * page, int pid, int type, char **start, off_t offset, int length)
1067 {
1068 if (pid)
1069 return get_process_array(page, pid, type);
1070 return get_root_array(page, type, start, offset, length);
1071 }
1072
1073 #define PROC_BLOCK_SIZE (3*1024)
1074
1075 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
1076 {
1077 unsigned long page;
1078 char *start;
1079 int length;
1080 int end;
1081 unsigned int type, pid;
1082 struct proc_dir_entry *dp;
1083
1084 if (count < 0)
1085 return -EINVAL;
1086 if (count > PROC_BLOCK_SIZE)
1087 count = PROC_BLOCK_SIZE;
1088 if (!(page = __get_free_page(GFP_KERNEL)))
1089 return -ENOMEM;
1090 type = inode->i_ino;
1091 pid = type >> 16;
1092 type &= 0x0000ffff;
1093 start = NULL;
1094 dp = (struct proc_dir_entry *) inode->u.generic_ip;
1095 if (dp->get_info)
1096 length = dp->get_info((char *)page, &start, file->f_pos,
1097 count, 0);
1098 else
1099 length = fill_array((char *) page, pid, type,
1100 &start, file->f_pos, count);
1101 if (length < 0) {
1102 free_page(page);
1103 return length;
1104 }
1105 if (start != NULL) {
1106
1107 memcpy_tofs(buf, start, length);
1108 file->f_pos += length;
1109 count = length;
1110 } else {
1111
1112 if (file->f_pos >= length) {
1113 free_page(page);
1114 return 0;
1115 }
1116 if (count + file->f_pos > length)
1117 count = length - file->f_pos;
1118 end = count + file->f_pos;
1119 memcpy_tofs(buf, (char *) page + file->f_pos, count);
1120 file->f_pos = end;
1121 }
1122 free_page(page);
1123 return count;
1124 }
1125
1126 static struct file_operations proc_array_operations = {
1127 NULL,
1128 array_read,
1129 NULL,
1130 NULL,
1131 NULL,
1132 NULL,
1133 NULL,
1134 NULL,
1135 NULL,
1136 NULL
1137 };
1138
1139 struct inode_operations proc_array_inode_operations = {
1140 &proc_array_operations,
1141 NULL,
1142 NULL,
1143 NULL,
1144 NULL,
1145 NULL,
1146 NULL,
1147 NULL,
1148 NULL,
1149 NULL,
1150 NULL,
1151 NULL,
1152 NULL,
1153 NULL,
1154 NULL,
1155 NULL,
1156 NULL
1157 };
1158
1159 static int arraylong_read (struct inode * inode, struct file * file, char * buf, int count)
1160 {
1161 unsigned int pid = inode->i_ino >> 16;
1162 unsigned int type = inode->i_ino & 0x0000ffff;
1163
1164 if (count < 0)
1165 return -EINVAL;
1166
1167 switch (type) {
1168 case PROC_PID_MAPS:
1169 return read_maps(pid, file, buf, count);
1170 }
1171 return -EINVAL;
1172 }
1173
1174 static struct file_operations proc_arraylong_operations = {
1175 NULL,
1176 arraylong_read,
1177 NULL,
1178 NULL,
1179 NULL,
1180 NULL,
1181 NULL,
1182 NULL,
1183 NULL,
1184 NULL
1185 };
1186
1187 struct inode_operations proc_arraylong_inode_operations = {
1188 &proc_arraylong_operations,
1189 NULL,
1190 NULL,
1191 NULL,
1192 NULL,
1193 NULL,
1194 NULL,
1195 NULL,
1196 NULL,
1197 NULL,
1198 NULL,
1199 NULL,
1200 NULL,
1201 NULL,
1202 NULL,
1203 NULL,
1204 NULL
1205 };