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 | } |
