diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/array.c | 23 | ||||
-rw-r--r-- | fs/proc/base.c | 68 | ||||
-rw-r--r-- | fs/proc/proc_devtree.c | 41 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 4 | ||||
-rw-r--r-- | fs/proc/stat.c | 19 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 45 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 8 |
7 files changed, 170 insertions, 38 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 822c2d506518..4badde179b18 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -410,6 +410,16 @@ static void task_show_stack_usage(struct seq_file *m, struct task_struct *task) | |||
410 | } | 410 | } |
411 | #endif /* CONFIG_MMU */ | 411 | #endif /* CONFIG_MMU */ |
412 | 412 | ||
413 | static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) | ||
414 | { | ||
415 | seq_printf(m, "Cpus_allowed:\t"); | ||
416 | seq_cpumask(m, &task->cpus_allowed); | ||
417 | seq_printf(m, "\n"); | ||
418 | seq_printf(m, "Cpus_allowed_list:\t"); | ||
419 | seq_cpumask_list(m, &task->cpus_allowed); | ||
420 | seq_printf(m, "\n"); | ||
421 | } | ||
422 | |||
413 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | 423 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, |
414 | struct pid *pid, struct task_struct *task) | 424 | struct pid *pid, struct task_struct *task) |
415 | { | 425 | { |
@@ -424,6 +434,7 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | |||
424 | } | 434 | } |
425 | task_sig(m, task); | 435 | task_sig(m, task); |
426 | task_cap(m, task); | 436 | task_cap(m, task); |
437 | task_cpus_allowed(m, task); | ||
427 | cpuset_task_status_allowed(m, task); | 438 | cpuset_task_status_allowed(m, task); |
428 | #if defined(CONFIG_S390) | 439 | #if defined(CONFIG_S390) |
429 | task_show_regs(m, task); | 440 | task_show_regs(m, task); |
@@ -495,20 +506,17 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
495 | 506 | ||
496 | /* add up live thread stats at the group level */ | 507 | /* add up live thread stats at the group level */ |
497 | if (whole) { | 508 | if (whole) { |
498 | struct task_cputime cputime; | ||
499 | struct task_struct *t = task; | 509 | struct task_struct *t = task; |
500 | do { | 510 | do { |
501 | min_flt += t->min_flt; | 511 | min_flt += t->min_flt; |
502 | maj_flt += t->maj_flt; | 512 | maj_flt += t->maj_flt; |
503 | gtime = cputime_add(gtime, task_gtime(t)); | 513 | gtime = cputime_add(gtime, t->gtime); |
504 | t = next_thread(t); | 514 | t = next_thread(t); |
505 | } while (t != task); | 515 | } while (t != task); |
506 | 516 | ||
507 | min_flt += sig->min_flt; | 517 | min_flt += sig->min_flt; |
508 | maj_flt += sig->maj_flt; | 518 | maj_flt += sig->maj_flt; |
509 | thread_group_cputime(task, &cputime); | 519 | thread_group_times(task, &utime, &stime); |
510 | utime = cputime.utime; | ||
511 | stime = cputime.stime; | ||
512 | gtime = cputime_add(gtime, sig->gtime); | 520 | gtime = cputime_add(gtime, sig->gtime); |
513 | } | 521 | } |
514 | 522 | ||
@@ -524,9 +532,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
524 | if (!whole) { | 532 | if (!whole) { |
525 | min_flt = task->min_flt; | 533 | min_flt = task->min_flt; |
526 | maj_flt = task->maj_flt; | 534 | maj_flt = task->maj_flt; |
527 | utime = task_utime(task); | 535 | task_times(task, &utime, &stime); |
528 | stime = task_stime(task); | 536 | gtime = task->gtime; |
529 | gtime = task_gtime(task); | ||
530 | } | 537 | } |
531 | 538 | ||
532 | /* scale priority and nice values from timeslices to -20..20 */ | 539 | /* scale priority and nice values from timeslices to -20..20 */ |
diff --git a/fs/proc/base.c b/fs/proc/base.c index af643b5aefe8..4df4a464a919 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1265,6 +1265,72 @@ static const struct file_operations proc_pid_sched_operations = { | |||
1265 | 1265 | ||
1266 | #endif | 1266 | #endif |
1267 | 1267 | ||
1268 | static ssize_t comm_write(struct file *file, const char __user *buf, | ||
1269 | size_t count, loff_t *offset) | ||
1270 | { | ||
1271 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1272 | struct task_struct *p; | ||
1273 | char buffer[TASK_COMM_LEN]; | ||
1274 | |||
1275 | memset(buffer, 0, sizeof(buffer)); | ||
1276 | if (count > sizeof(buffer) - 1) | ||
1277 | count = sizeof(buffer) - 1; | ||
1278 | if (copy_from_user(buffer, buf, count)) | ||
1279 | return -EFAULT; | ||
1280 | |||
1281 | p = get_proc_task(inode); | ||
1282 | if (!p) | ||
1283 | return -ESRCH; | ||
1284 | |||
1285 | if (same_thread_group(current, p)) | ||
1286 | set_task_comm(p, buffer); | ||
1287 | else | ||
1288 | count = -EINVAL; | ||
1289 | |||
1290 | put_task_struct(p); | ||
1291 | |||
1292 | return count; | ||
1293 | } | ||
1294 | |||
1295 | static int comm_show(struct seq_file *m, void *v) | ||
1296 | { | ||
1297 | struct inode *inode = m->private; | ||
1298 | struct task_struct *p; | ||
1299 | |||
1300 | p = get_proc_task(inode); | ||
1301 | if (!p) | ||
1302 | return -ESRCH; | ||
1303 | |||
1304 | task_lock(p); | ||
1305 | seq_printf(m, "%s\n", p->comm); | ||
1306 | task_unlock(p); | ||
1307 | |||
1308 | put_task_struct(p); | ||
1309 | |||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1313 | static int comm_open(struct inode *inode, struct file *filp) | ||
1314 | { | ||
1315 | int ret; | ||
1316 | |||
1317 | ret = single_open(filp, comm_show, NULL); | ||
1318 | if (!ret) { | ||
1319 | struct seq_file *m = filp->private_data; | ||
1320 | |||
1321 | m->private = inode; | ||
1322 | } | ||
1323 | return ret; | ||
1324 | } | ||
1325 | |||
1326 | static const struct file_operations proc_pid_set_comm_operations = { | ||
1327 | .open = comm_open, | ||
1328 | .read = seq_read, | ||
1329 | .write = comm_write, | ||
1330 | .llseek = seq_lseek, | ||
1331 | .release = single_release, | ||
1332 | }; | ||
1333 | |||
1268 | /* | 1334 | /* |
1269 | * We added or removed a vma mapping the executable. The vmas are only mapped | 1335 | * We added or removed a vma mapping the executable. The vmas are only mapped |
1270 | * during exec and are not mapped with the mmap system call. | 1336 | * during exec and are not mapped with the mmap system call. |
@@ -2504,6 +2570,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2504 | #ifdef CONFIG_SCHED_DEBUG | 2570 | #ifdef CONFIG_SCHED_DEBUG |
2505 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 2571 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2506 | #endif | 2572 | #endif |
2573 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), | ||
2507 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2574 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2508 | INF("syscall", S_IRUSR, proc_pid_syscall), | 2575 | INF("syscall", S_IRUSR, proc_pid_syscall), |
2509 | #endif | 2576 | #endif |
@@ -2838,6 +2905,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2838 | #ifdef CONFIG_SCHED_DEBUG | 2905 | #ifdef CONFIG_SCHED_DEBUG |
2839 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 2906 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2840 | #endif | 2907 | #endif |
2908 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), | ||
2841 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2909 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2842 | INF("syscall", S_IRUSR, proc_pid_syscall), | 2910 | INF("syscall", S_IRUSR, proc_pid_syscall), |
2843 | #endif | 2911 | #endif |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index 7ba79a54948c..123257bb356b 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/time.h> | 8 | #include <linux/time.h> |
9 | #include <linux/proc_fs.h> | 9 | #include <linux/proc_fs.h> |
10 | #include <linux/seq_file.h> | ||
10 | #include <linux/stat.h> | 11 | #include <linux/stat.h> |
11 | #include <linux/string.h> | 12 | #include <linux/string.h> |
12 | #include <asm/prom.h> | 13 | #include <asm/prom.h> |
@@ -25,26 +26,27 @@ static struct proc_dir_entry *proc_device_tree; | |||
25 | /* | 26 | /* |
26 | * Supply data on a read from /proc/device-tree/node/property. | 27 | * Supply data on a read from /proc/device-tree/node/property. |
27 | */ | 28 | */ |
28 | static int property_read_proc(char *page, char **start, off_t off, | 29 | static int property_proc_show(struct seq_file *m, void *v) |
29 | int count, int *eof, void *data) | ||
30 | { | 30 | { |
31 | struct property *pp = data; | 31 | struct property *pp = m->private; |
32 | int n; | ||
33 | 32 | ||
34 | if (off >= pp->length) { | 33 | seq_write(m, pp->value, pp->length); |
35 | *eof = 1; | 34 | return 0; |
36 | return 0; | 35 | } |
37 | } | 36 | |
38 | n = pp->length - off; | 37 | static int property_proc_open(struct inode *inode, struct file *file) |
39 | if (n > count) | 38 | { |
40 | n = count; | 39 | return single_open(file, property_proc_show, PDE(inode)->data); |
41 | else | ||
42 | *eof = 1; | ||
43 | memcpy(page, (char *)pp->value + off, n); | ||
44 | *start = page; | ||
45 | return n; | ||
46 | } | 40 | } |
47 | 41 | ||
42 | static const struct file_operations property_proc_fops = { | ||
43 | .owner = THIS_MODULE, | ||
44 | .open = property_proc_open, | ||
45 | .read = seq_read, | ||
46 | .llseek = seq_lseek, | ||
47 | .release = single_release, | ||
48 | }; | ||
49 | |||
48 | /* | 50 | /* |
49 | * For a node with a name like "gc@10", we make symlinks called "gc" | 51 | * For a node with a name like "gc@10", we make symlinks called "gc" |
50 | * and "@10" to it. | 52 | * and "@10" to it. |
@@ -63,10 +65,9 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp, | |||
63 | * Unfortunately proc_register puts each new entry | 65 | * Unfortunately proc_register puts each new entry |
64 | * at the beginning of the list. So we rearrange them. | 66 | * at the beginning of the list. So we rearrange them. |
65 | */ | 67 | */ |
66 | ent = create_proc_read_entry(name, | 68 | ent = proc_create_data(name, |
67 | strncmp(name, "security-", 9) | 69 | strncmp(name, "security-", 9) ? S_IRUGO : S_IRUSR, |
68 | ? S_IRUGO : S_IRUSR, de, | 70 | de, &property_proc_fops, pp); |
69 | property_read_proc, pp); | ||
70 | if (ent == NULL) | 71 | if (ent == NULL) |
71 | return NULL; | 72 | return NULL; |
72 | 73 | ||
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index f667e8aeabdf..6ff9981f0a18 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -48,7 +48,7 @@ out: | |||
48 | static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name) | 48 | static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name) |
49 | { | 49 | { |
50 | int len; | 50 | int len; |
51 | for ( ; p->ctl_name || p->procname; p++) { | 51 | for ( ; p->procname; p++) { |
52 | 52 | ||
53 | if (!p->procname) | 53 | if (!p->procname) |
54 | continue; | 54 | continue; |
@@ -218,7 +218,7 @@ static int scan(struct ctl_table_header *head, ctl_table *table, | |||
218 | void *dirent, filldir_t filldir) | 218 | void *dirent, filldir_t filldir) |
219 | { | 219 | { |
220 | 220 | ||
221 | for (; table->ctl_name || table->procname; table++, (*pos)++) { | 221 | for (; table->procname; table++, (*pos)++) { |
222 | int res; | 222 | int res; |
223 | 223 | ||
224 | /* Can't do anything without a proc name */ | 224 | /* Can't do anything without a proc name */ |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 7cc726c6d70a..b9b7aad2003d 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -27,7 +27,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
27 | int i, j; | 27 | int i, j; |
28 | unsigned long jif; | 28 | unsigned long jif; |
29 | cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; | 29 | cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; |
30 | cputime64_t guest; | 30 | cputime64_t guest, guest_nice; |
31 | u64 sum = 0; | 31 | u64 sum = 0; |
32 | u64 sum_softirq = 0; | 32 | u64 sum_softirq = 0; |
33 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; | 33 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; |
@@ -36,7 +36,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
36 | 36 | ||
37 | user = nice = system = idle = iowait = | 37 | user = nice = system = idle = iowait = |
38 | irq = softirq = steal = cputime64_zero; | 38 | irq = softirq = steal = cputime64_zero; |
39 | guest = cputime64_zero; | 39 | guest = guest_nice = cputime64_zero; |
40 | getboottime(&boottime); | 40 | getboottime(&boottime); |
41 | jif = boottime.tv_sec; | 41 | jif = boottime.tv_sec; |
42 | 42 | ||
@@ -51,6 +51,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
51 | softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); | 51 | softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); |
52 | steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); | 52 | steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); |
53 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); | 53 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); |
54 | guest_nice = cputime64_add(guest_nice, | ||
55 | kstat_cpu(i).cpustat.guest_nice); | ||
54 | for_each_irq_nr(j) { | 56 | for_each_irq_nr(j) { |
55 | sum += kstat_irqs_cpu(j, i); | 57 | sum += kstat_irqs_cpu(j, i); |
56 | } | 58 | } |
@@ -65,7 +67,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
65 | } | 67 | } |
66 | sum += arch_irq_stat(); | 68 | sum += arch_irq_stat(); |
67 | 69 | ||
68 | seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", | 70 | seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu " |
71 | "%llu\n", | ||
69 | (unsigned long long)cputime64_to_clock_t(user), | 72 | (unsigned long long)cputime64_to_clock_t(user), |
70 | (unsigned long long)cputime64_to_clock_t(nice), | 73 | (unsigned long long)cputime64_to_clock_t(nice), |
71 | (unsigned long long)cputime64_to_clock_t(system), | 74 | (unsigned long long)cputime64_to_clock_t(system), |
@@ -74,7 +77,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
74 | (unsigned long long)cputime64_to_clock_t(irq), | 77 | (unsigned long long)cputime64_to_clock_t(irq), |
75 | (unsigned long long)cputime64_to_clock_t(softirq), | 78 | (unsigned long long)cputime64_to_clock_t(softirq), |
76 | (unsigned long long)cputime64_to_clock_t(steal), | 79 | (unsigned long long)cputime64_to_clock_t(steal), |
77 | (unsigned long long)cputime64_to_clock_t(guest)); | 80 | (unsigned long long)cputime64_to_clock_t(guest), |
81 | (unsigned long long)cputime64_to_clock_t(guest_nice)); | ||
78 | for_each_online_cpu(i) { | 82 | for_each_online_cpu(i) { |
79 | 83 | ||
80 | /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ | 84 | /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ |
@@ -88,8 +92,10 @@ static int show_stat(struct seq_file *p, void *v) | |||
88 | softirq = kstat_cpu(i).cpustat.softirq; | 92 | softirq = kstat_cpu(i).cpustat.softirq; |
89 | steal = kstat_cpu(i).cpustat.steal; | 93 | steal = kstat_cpu(i).cpustat.steal; |
90 | guest = kstat_cpu(i).cpustat.guest; | 94 | guest = kstat_cpu(i).cpustat.guest; |
95 | guest_nice = kstat_cpu(i).cpustat.guest_nice; | ||
91 | seq_printf(p, | 96 | seq_printf(p, |
92 | "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", | 97 | "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu " |
98 | "%llu\n", | ||
93 | i, | 99 | i, |
94 | (unsigned long long)cputime64_to_clock_t(user), | 100 | (unsigned long long)cputime64_to_clock_t(user), |
95 | (unsigned long long)cputime64_to_clock_t(nice), | 101 | (unsigned long long)cputime64_to_clock_t(nice), |
@@ -99,7 +105,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
99 | (unsigned long long)cputime64_to_clock_t(irq), | 105 | (unsigned long long)cputime64_to_clock_t(irq), |
100 | (unsigned long long)cputime64_to_clock_t(softirq), | 106 | (unsigned long long)cputime64_to_clock_t(softirq), |
101 | (unsigned long long)cputime64_to_clock_t(steal), | 107 | (unsigned long long)cputime64_to_clock_t(steal), |
102 | (unsigned long long)cputime64_to_clock_t(guest)); | 108 | (unsigned long long)cputime64_to_clock_t(guest), |
109 | (unsigned long long)cputime64_to_clock_t(guest_nice)); | ||
103 | } | 110 | } |
104 | seq_printf(p, "intr %llu", (unsigned long long)sum); | 111 | seq_printf(p, "intr %llu", (unsigned long long)sum); |
105 | 112 | ||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 2a1bef9203c6..47c03f4336b8 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -650,6 +650,50 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
650 | return err; | 650 | return err; |
651 | } | 651 | } |
652 | 652 | ||
653 | static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset) | ||
654 | { | ||
655 | u64 pme = 0; | ||
656 | if (pte_present(pte)) | ||
657 | pme = PM_PFRAME(pte_pfn(pte) + offset) | ||
658 | | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; | ||
659 | return pme; | ||
660 | } | ||
661 | |||
662 | static int pagemap_hugetlb_range(pte_t *pte, unsigned long addr, | ||
663 | unsigned long end, struct mm_walk *walk) | ||
664 | { | ||
665 | struct vm_area_struct *vma; | ||
666 | struct pagemapread *pm = walk->private; | ||
667 | struct hstate *hs = NULL; | ||
668 | int err = 0; | ||
669 | |||
670 | vma = find_vma(walk->mm, addr); | ||
671 | if (vma) | ||
672 | hs = hstate_vma(vma); | ||
673 | for (; addr != end; addr += PAGE_SIZE) { | ||
674 | u64 pfn = PM_NOT_PRESENT; | ||
675 | |||
676 | if (vma && (addr >= vma->vm_end)) { | ||
677 | vma = find_vma(walk->mm, addr); | ||
678 | if (vma) | ||
679 | hs = hstate_vma(vma); | ||
680 | } | ||
681 | |||
682 | if (vma && (vma->vm_start <= addr) && is_vm_hugetlb_page(vma)) { | ||
683 | /* calculate pfn of the "raw" page in the hugepage. */ | ||
684 | int offset = (addr & ~huge_page_mask(hs)) >> PAGE_SHIFT; | ||
685 | pfn = huge_pte_to_pagemap_entry(*pte, offset); | ||
686 | } | ||
687 | err = add_to_pagemap(addr, pfn, pm); | ||
688 | if (err) | ||
689 | return err; | ||
690 | } | ||
691 | |||
692 | cond_resched(); | ||
693 | |||
694 | return err; | ||
695 | } | ||
696 | |||
653 | /* | 697 | /* |
654 | * /proc/pid/pagemap - an array mapping virtual pages to pfns | 698 | * /proc/pid/pagemap - an array mapping virtual pages to pfns |
655 | * | 699 | * |
@@ -742,6 +786,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
742 | 786 | ||
743 | pagemap_walk.pmd_entry = pagemap_pte_range; | 787 | pagemap_walk.pmd_entry = pagemap_pte_range; |
744 | pagemap_walk.pte_hole = pagemap_pte_hole; | 788 | pagemap_walk.pte_hole = pagemap_pte_hole; |
789 | pagemap_walk.hugetlb_entry = pagemap_hugetlb_range; | ||
745 | pagemap_walk.mm = mm; | 790 | pagemap_walk.mm = mm; |
746 | pagemap_walk.private = ± | 791 | pagemap_walk.private = ± |
747 | 792 | ||
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 8f5c05d3dbd3..5d9fd64ef81a 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -110,9 +110,13 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | 112 | ||
113 | size += (*text = mm->end_code - mm->start_code); | 113 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) |
114 | size += (*data = mm->start_stack - mm->start_data); | 114 | >> PAGE_SHIFT; |
115 | *data = (PAGE_ALIGN(mm->start_stack) - (mm->start_data & PAGE_MASK)) | ||
116 | >> PAGE_SHIFT; | ||
115 | up_read(&mm->mmap_sem); | 117 | up_read(&mm->mmap_sem); |
118 | size >>= PAGE_SHIFT; | ||
119 | size += *text + *data; | ||
116 | *resident = size; | 120 | *resident = size; |
117 | return size; | 121 | return size; |
118 | } | 122 | } |