aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c23
-rw-r--r--fs/proc/base.c68
-rw-r--r--fs/proc/proc_devtree.c41
-rw-r--r--fs/proc/proc_sysctl.c4
-rw-r--r--fs/proc/stat.c19
-rw-r--r--fs/proc/task_mmu.c45
-rw-r--r--fs/proc/task_nommu.c8
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
413static 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
413int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, 423int 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
1268static 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
1295static 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
1313static 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
1326static 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 */
28static int property_read_proc(char *page, char **start, off_t off, 29static 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; 37static 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
42static 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:
48static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name) 48static 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
653static 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
662static 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 = &pm; 791 pagemap_walk.private = &pm;
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}