diff options
| author | Christoph Hellwig <hch@lst.de> | 2003-01-14 16:32:37 -0800 |
|---|---|---|
| committer | Christoph Hellwig <hch@lst.de> | 2003-01-14 16:32:37 -0800 |
| commit | 36ece8f9024c249c5604ff5d6c2dfd6298fcdb3c (patch) | |
| tree | b8adee10e2d435c08b11305e5062b0a4d6641858 /fs/proc/array.c | |
| parent | 7a8f29d23fe7faf2e015df2cdd5a9bd34f05b17b (diff) | |
[PATCH] more procfs bits for !CONFIG_MMU
New version with all ifdef CONFIG_MMU gone from procfs.
Instead, the conditional code is in either task_mmu.c/task_nommu.c, and
the Makefile will select the proper file for inclusion depending on
CONFIG_MMU.
Diffstat (limited to 'fs/proc/array.c')
| -rw-r--r-- | fs/proc/array.c | 260 |
1 files changed, 15 insertions, 245 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index fd826e15234c..29b41941d83e 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -180,47 +180,6 @@ static inline char * task_state(struct task_struct *p, char *buffer) return buffer; } -static inline char * task_mem(struct mm_struct *mm, char *buffer) -{ - struct vm_area_struct * vma; - unsigned long data = 0, stack = 0; - unsigned long exec = 0, lib = 0; - - down_read(&mm->mmap_sem); - for (vma = mm->mmap; vma; vma = vma->vm_next) { - unsigned long len = (vma->vm_end - vma->vm_start) >> 10; - if (!vma->vm_file) { - data += len; - if (vma->vm_flags & VM_GROWSDOWN) - stack += len; - continue; - } - if (vma->vm_flags & VM_WRITE) - continue; - if (vma->vm_flags & VM_EXEC) { - exec += len; - if (vma->vm_flags & VM_EXECUTABLE) - continue; - lib += len; - } - } - buffer += sprintf(buffer, - "VmSize:\t%8lu kB\n" - "VmLck:\t%8lu kB\n" - "VmRSS:\t%8lu kB\n" - "VmData:\t%8lu kB\n" - "VmStk:\t%8lu kB\n" - "VmExe:\t%8lu kB\n" - "VmLib:\t%8lu kB\n", - mm->total_vm << (PAGE_SHIFT-10), - mm->locked_vm << (PAGE_SHIFT-10), - mm->rss << (PAGE_SHIFT-10), - data - stack, stack, - exec - lib, lib); - up_read(&mm->mmap_sem); - return buffer; -} - static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, sigset_t *catch) { @@ -277,7 +236,7 @@ static inline char *task_cap(struct task_struct *p, char *buffer) cap_t(p->cap_effective)); } - +extern char *task_mem(struct mm_struct *, char *); int proc_pid_status(struct task_struct *task, char * buffer) { char * orig = buffer; @@ -298,6 +257,7 @@ int proc_pid_status(struct task_struct *task, char * buffer) return buffer - orig; } +extern unsigned long task_vsize(struct mm_struct *); int proc_pid_stat(struct task_struct *task, char * buffer) { unsigned long vsize, eip, esp, wchan; @@ -321,13 +281,8 @@ int proc_pid_stat(struct task_struct *task, char * buffer) } task_unlock(task); if (mm) { - struct vm_area_struct *vma; down_read(&mm->mmap_sem); - vma = mm->mmap; - while (vma) { - vsize += vma->vm_end - vma->vm_start; - vma = vma->vm_next; - } + vsize = task_vsize(mm); eip = KSTK_EIP(task); esp = KSTK_ESP(task); up_read(&mm->mmap_sem); @@ -397,206 +352,21 @@ int proc_pid_stat(struct task_struct *task, char * buffer) mmput(mm); return res; } - -int proc_pid_statm(task_t *task, char *buffer) -{ - int size, resident, shared, text, lib, data, dirty; - struct mm_struct *mm = get_task_mm(task); - struct vm_area_struct * vma; - size = resident = shared = text = lib = data = dirty = 0; - - if (!mm) - goto out; - - down_read(&mm->mmap_sem); - resident = mm->rss; - for (vma = mm->mmap; vma; vma = vma->vm_next) { - int pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - - size += pages; - if (is_vm_hugetlb_page(vma)) { - if (!(vma->vm_flags & VM_DONTCOPY)) - shared += pages; - continue; - } - if (vma->vm_flags & VM_SHARED || !list_empty(&vma->shared)) - shared += pages; - if (vma->vm_flags & VM_EXECUTABLE) - text += pages; - else - data += pages; - } - up_read(&mm->mmap_sem); - mmput(mm); -out: - return sprintf(buffer,"%d %d %d %d %d %d %d\n", - size, resident, shared, text, lib, data, dirty); -} - -/* - * The way we support synthetic files > 4K - * - without storing their contents in some buffer and - * - without walking through the entire synthetic file until we reach the - * position of the requested data - * is to cleverly encode the current position in the file's f_pos field. - * There is no requirement that a read() call which returns `count' bytes - * of data increases f_pos by exactly `count'. - * - * This idea is Linus' one. Bruno implemented it. - */ - -/* - * For the /proc/<pid>/maps file, we use fixed length records, each containing - * a single line. - * - * f_pos = (number of the vma in the task->mm->mmap list) * PAGE_SIZE - * + (index into the line) - */ -/* for systems with sizeof(void*) == 4: */ -#define MAPS_LINE_FORMAT4 "%08lx-%08lx %s %08lx %02x:%02x %lu" -#define MAPS_LINE_MAX4 49 /* sum of 8 1 8 1 4 1 8 1 5 1 10 1 */ - -/* for systems with sizeof(void*) == 8: */ -#define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %02x:%02x %lu" -#define MAPS_LINE_MAX8 73 /* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */ - -#define MAPS_LINE_FORMAT (sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8) -#define MAPS_LINE_MAX (sizeof(void*) == 4 ? MAPS_LINE_MAX4 : MAPS_LINE_MAX8) - -static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map) -{ - /* produce the next line */ - char *line; - char str[5]; - int flags; - dev_t dev; - unsigned long ino; - int len; - - flags = map->vm_flags; - - str[0] = flags & VM_READ ? 'r' : '-'; - str[1] = flags & VM_WRITE ? 'w' : '-'; - str[2] = flags & VM_EXEC ? 'x' : '-'; - str[3] = flags & VM_MAYSHARE ? 's' : 'p'; - str[4] = 0; - - dev = 0; - ino = 0; - if (map->vm_file != NULL) { - struct inode *inode = map->vm_file->f_dentry->d_inode; - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - line = d_path(map->vm_file->f_dentry, - map->vm_file->f_vfsmnt, - buf, PAGE_SIZE); - buf[PAGE_SIZE-1] = '\n'; - line -= MAPS_LINE_MAX; - if(line < buf) - line = buf; - } else - line = buf; - - len = sprintf(line, - MAPS_LINE_FORMAT, - map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT, - MAJOR(dev), MINOR(dev), ino); - - if(map->vm_file) { - int i; - for(i = len; i < MAPS_LINE_MAX; i++) - line[i] = ' '; - len = buf + PAGE_SIZE - line; - memmove(buf, line, len); - } else - line[len++] = '\n'; - return len; -} - -#ifdef CONFIG_MMU -ssize_t proc_pid_read_maps(struct task_struct *task, struct file *file, - char *buf, size_t count, loff_t *ppos) +extern int task_statm(struct mm_struct *, int *, int *, int *, int *); +int proc_pid_statm(struct task_struct *task, char *buffer) { - struct mm_struct *mm; - struct vm_area_struct * map; - char *tmp, *kbuf; - long retval; - int off, lineno, loff; - - /* reject calls with out of range parameters immediately */ - retval = 0; - if (*ppos > LONG_MAX) - goto out; - if (count == 0) - goto out; - off = (long)*ppos; - /* - * We might sleep getting the page, so get it first. - */ - retval = -ENOMEM; - kbuf = (char*)__get_free_page(GFP_KERNEL); - if (!kbuf) - goto out; - - tmp = (char*)__get_free_page(GFP_KERNEL); - if (!tmp) - goto out_free1; - - mm = get_task_mm(task); - - retval = 0; - if (!mm) - goto out_free2; + int size = 0, resident = 0, shared = 0, text = 0, lib = 0, data = 0; + struct mm_struct *mm = get_task_mm(task); + + if (mm) { + down_read(&mm->mmap_sem); + size = task_statm(mm, &shared, &text, &data, &resident); + up_read(&mm->mmap_sem); - down_read(&mm->mmap_sem); - map = mm->mmap; - lineno = 0; - loff = 0; - if (count > PAGE_SIZE) - count = PAGE_SIZE; - while (map) { - int len; - if (off > PAGE_SIZE) { - off -= PAGE_SIZE; - goto next; - } - len = proc_pid_maps_get_line(tmp, map); - len -= off; - if (len > 0) { - if (retval+len > count) { - /* only partial line transfer possible */ - len = count - retval; - /* save the offset where the next read - * must start */ - loff = len+off; - } - memcpy(kbuf+retval, tmp+off, len); - retval += len; - } - off = 0; -next: - if (!loff) - lineno++; - if (retval >= count) - break; - if (loff) BUG(); - map = map->vm_next; + mmput(mm); } - up_read(&mm->mmap_sem); - mmput(mm); - - if (retval > count) BUG(); - if (copy_to_user(buf, kbuf, retval)) - retval = -EFAULT; - else - *ppos = (lineno << PAGE_SHIFT) + loff; -out_free2: - free_page((unsigned long)tmp); -out_free1: - free_page((unsigned long)kbuf); -out: - return retval; + return sprintf(buffer,"%d %d %d %d %d %d %d\n", + size, resident, shared, text, lib, data, 0); } -#endif /* CONFIG_MMU */ |
