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 extern int get_locks_status (char *);
971 #ifdef __SMP_PROF__
972 extern int get_smp_prof_list(char *);
973 #endif
974
975 static int get_root_array(char * page, int type, char **start, off_t offset, int length)
976 {
977 switch (type) {
978 case PROC_LOADAVG:
979 return get_loadavg(page);
980
981 case PROC_UPTIME:
982 return get_uptime(page);
983
984 case PROC_MEMINFO:
985 return get_meminfo(page);
986
987 #ifdef CONFIG_PCI
988 case PROC_PCI:
989 return get_pci_list(page);
990 #endif
991
992 case PROC_CPUINFO:
993 return get_cpuinfo(page);
994
995 case PROC_VERSION:
996 return get_version(page);
997
998 #ifdef CONFIG_DEBUG_MALLOC
999 case PROC_MALLOC:
1000 return get_malloc(page);
1001 #endif
1002
1003 #ifdef CONFIG_MODULES
1004 case PROC_MODULES:
1005 return get_module_list(page);
1006
1007 case PROC_KSYMS:
1008 return get_ksyms_list(page, start, offset, length);
1009 #endif
1010
1011 case PROC_STAT:
1012 return get_kstat(page);
1013
1014 case PROC_DEVICES:
1015 return get_device_list(page);
1016
1017 case PROC_INTERRUPTS:
1018 return get_irq_list(page);
1019
1020 case PROC_FILESYSTEMS:
1021 return get_filesystem_list(page);
1022
1023 case PROC_DMA:
1024 return get_dma_list(page);
1025
1026 case PROC_IOPORTS:
1027 return get_ioport_list(page);
1028 #ifdef CONFIG_BLK_DEV_MD
1029 case PROC_MD:
1030 return get_md_status(page);
1031 #endif
1032 #ifdef __SMP_PROF__
1033 case PROC_SMP_PROF:
1034 return get_smp_prof_list(page);
1035 #endif
1036 case PROC_CMDLINE:
1037 return get_cmdline(page);
1038
1039 case PROC_MTAB:
1040 return get_filesystem_info( page );
1041 #ifdef CONFIG_RTC
1042 case PROC_RTC:
1043 return get_rtc_status(page);
1044 #endif
1045 case PROC_LOCKS:
1046 return get_locks_status(page);
1047 }
1048 return -EBADF;
1049 }
1050
1051 static int get_process_array(char * page, int pid, int type)
1052 {
1053 switch (type) {
1054 case PROC_PID_STATUS:
1055 return get_status(pid, page);
1056 case PROC_PID_ENVIRON:
1057 return get_env(pid, page);
1058 case PROC_PID_CMDLINE:
1059 return get_arg(pid, page);
1060 case PROC_PID_STAT:
1061 return get_stat(pid, page);
1062 case PROC_PID_STATM:
1063 return get_statm(pid, page);
1064 }
1065 return -EBADF;
1066 }
1067
1068
1069 static inline int fill_array(char * page, int pid, int type, char **start, off_t offset, int length)
1070 {
1071 if (pid)
1072 return get_process_array(page, pid, type);
1073 return get_root_array(page, type, start, offset, length);
1074 }
1075
1076 #define PROC_BLOCK_SIZE (3*1024)
1077
1078 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
1079 {
1080 unsigned long page;
1081 char *start;
1082 int length;
1083 int end;
1084 unsigned int type, pid;
1085 struct proc_dir_entry *dp;
1086
1087 if (count < 0)
1088 return -EINVAL;
1089 if (count > PROC_BLOCK_SIZE)
1090 count = PROC_BLOCK_SIZE;
1091 if (!(page = __get_free_page(GFP_KERNEL)))
1092 return -ENOMEM;
1093 type = inode->i_ino;
1094 pid = type >> 16;
1095 type &= 0x0000ffff;
1096 start = NULL;
1097 dp = (struct proc_dir_entry *) inode->u.generic_ip;
1098 if (dp->get_info)
1099 length = dp->get_info((char *)page, &start, file->f_pos,
1100 count, 0);
1101 else
1102 length = fill_array((char *) page, pid, type,
1103 &start, file->f_pos, count);
1104 if (length < 0) {
1105 free_page(page);
1106 return length;
1107 }
1108 if (start != NULL) {
1109
1110 memcpy_tofs(buf, start, length);
1111 file->f_pos += length;
1112 count = length;
1113 } else {
1114
1115 if (file->f_pos >= length) {
1116 free_page(page);
1117 return 0;
1118 }
1119 if (count + file->f_pos > length)
1120 count = length - file->f_pos;
1121 end = count + file->f_pos;
1122 memcpy_tofs(buf, (char *) page + file->f_pos, count);
1123 file->f_pos = end;
1124 }
1125 free_page(page);
1126 return count;
1127 }
1128
1129 static struct file_operations proc_array_operations = {
1130 NULL,
1131 array_read,
1132 NULL,
1133 NULL,
1134 NULL,
1135 NULL,
1136 NULL,
1137 NULL,
1138 NULL,
1139 NULL
1140 };
1141
1142 struct inode_operations proc_array_inode_operations = {
1143 &proc_array_operations,
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 NULL,
1158 NULL,
1159 NULL
1160 };
1161
1162 static int arraylong_read (struct inode * inode, struct file * file, char * buf, int count)
1163 {
1164 unsigned int pid = inode->i_ino >> 16;
1165 unsigned int type = inode->i_ino & 0x0000ffff;
1166
1167 if (count < 0)
1168 return -EINVAL;
1169
1170 switch (type) {
1171 case PROC_PID_MAPS:
1172 return read_maps(pid, file, buf, count);
1173 }
1174 return -EINVAL;
1175 }
1176
1177 static struct file_operations proc_arraylong_operations = {
1178 NULL,
1179 arraylong_read,
1180 NULL,
1181 NULL,
1182 NULL,
1183 NULL,
1184 NULL,
1185 NULL,
1186 NULL,
1187 NULL
1188 };
1189
1190 struct inode_operations proc_arraylong_inode_operations = {
1191 &proc_arraylong_operations,
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 NULL,
1206 NULL,
1207 NULL
1208 };