aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c129
-rw-r--r--fs/proc/base.c106
-rw-r--r--fs/proc/generic.c21
-rw-r--r--fs/proc/inode.c31
-rw-r--r--fs/proc/internal.h10
-rw-r--r--fs/proc/page.c45
-rw-r--r--fs/proc/proc_devtree.c48
-rw-r--r--fs/proc/proc_sysctl.c4
-rw-r--r--fs/proc/stat.c19
-rw-r--r--fs/proc/task_mmu.c48
-rw-r--r--fs/proc/task_nommu.c8
11 files changed, 241 insertions, 228 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 07f77a7945c3..18e20feee251 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -134,13 +134,16 @@ static inline void task_name(struct seq_file *m, struct task_struct *p)
134 * simple bit tests. 134 * simple bit tests.
135 */ 135 */
136static const char *task_state_array[] = { 136static const char *task_state_array[] = {
137 "R (running)", /* 0 */ 137 "R (running)", /* 0 */
138 "S (sleeping)", /* 1 */ 138 "S (sleeping)", /* 1 */
139 "D (disk sleep)", /* 2 */ 139 "D (disk sleep)", /* 2 */
140 "T (stopped)", /* 4 */ 140 "T (stopped)", /* 4 */
141 "T (tracing stop)", /* 8 */ 141 "t (tracing stop)", /* 8 */
142 "Z (zombie)", /* 16 */ 142 "Z (zombie)", /* 16 */
143 "X (dead)" /* 32 */ 143 "X (dead)", /* 32 */
144 "x (dead)", /* 64 */
145 "K (wakekill)", /* 128 */
146 "W (waking)", /* 256 */
144}; 147};
145 148
146static inline const char *get_task_state(struct task_struct *tsk) 149static inline const char *get_task_state(struct task_struct *tsk)
@@ -148,6 +151,8 @@ static inline const char *get_task_state(struct task_struct *tsk)
148 unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state; 151 unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state;
149 const char **p = &task_state_array[0]; 152 const char **p = &task_state_array[0];
150 153
154 BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array));
155
151 while (state) { 156 while (state) {
152 p++; 157 p++;
153 state >>= 1; 158 state >>= 1;
@@ -265,7 +270,9 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
265 blocked = p->blocked; 270 blocked = p->blocked;
266 collect_sigign_sigcatch(p, &ignored, &caught); 271 collect_sigign_sigcatch(p, &ignored, &caught);
267 num_threads = atomic_read(&p->signal->count); 272 num_threads = atomic_read(&p->signal->count);
273 rcu_read_lock(); /* FIXME: is this correct? */
268 qsize = atomic_read(&__task_cred(p)->user->sigpending); 274 qsize = atomic_read(&__task_cred(p)->user->sigpending);
275 rcu_read_unlock();
269 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; 276 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
270 unlock_task_sighand(p, &flags); 277 unlock_task_sighand(p, &flags);
271 } 278 }
@@ -322,93 +329,15 @@ static inline void task_context_switch_counts(struct seq_file *m,
322 p->nivcsw); 329 p->nivcsw);
323} 330}
324 331
325#ifdef CONFIG_MMU 332static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
326
327struct stack_stats {
328 struct vm_area_struct *vma;
329 unsigned long startpage;
330 unsigned long usage;
331};
332
333static int stack_usage_pte_range(pmd_t *pmd, unsigned long addr,
334 unsigned long end, struct mm_walk *walk)
335{
336 struct stack_stats *ss = walk->private;
337 struct vm_area_struct *vma = ss->vma;
338 pte_t *pte, ptent;
339 spinlock_t *ptl;
340 int ret = 0;
341
342 pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
343 for (; addr != end; pte++, addr += PAGE_SIZE) {
344 ptent = *pte;
345
346#ifdef CONFIG_STACK_GROWSUP
347 if (pte_present(ptent) || is_swap_pte(ptent))
348 ss->usage = addr - ss->startpage + PAGE_SIZE;
349#else
350 if (pte_present(ptent) || is_swap_pte(ptent)) {
351 ss->usage = ss->startpage - addr + PAGE_SIZE;
352 pte++;
353 ret = 1;
354 break;
355 }
356#endif
357 }
358 pte_unmap_unlock(pte - 1, ptl);
359 cond_resched();
360 return ret;
361}
362
363static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
364 struct task_struct *task)
365{
366 struct stack_stats ss;
367 struct mm_walk stack_walk = {
368 .pmd_entry = stack_usage_pte_range,
369 .mm = vma->vm_mm,
370 .private = &ss,
371 };
372
373 if (!vma->vm_mm || is_vm_hugetlb_page(vma))
374 return 0;
375
376 ss.vma = vma;
377 ss.startpage = task->stack_start & PAGE_MASK;
378 ss.usage = 0;
379
380#ifdef CONFIG_STACK_GROWSUP
381 walk_page_range(KSTK_ESP(task) & PAGE_MASK, vma->vm_end,
382 &stack_walk);
383#else
384 walk_page_range(vma->vm_start, (KSTK_ESP(task) & PAGE_MASK) + PAGE_SIZE,
385 &stack_walk);
386#endif
387 return ss.usage;
388}
389
390static inline void task_show_stack_usage(struct seq_file *m,
391 struct task_struct *task)
392{
393 struct vm_area_struct *vma;
394 struct mm_struct *mm = get_task_mm(task);
395
396 if (mm) {
397 down_read(&mm->mmap_sem);
398 vma = find_vma(mm, task->stack_start);
399 if (vma)
400 seq_printf(m, "Stack usage:\t%lu kB\n",
401 get_stack_usage_in_bytes(vma, task) >> 10);
402
403 up_read(&mm->mmap_sem);
404 mmput(mm);
405 }
406}
407#else
408static void task_show_stack_usage(struct seq_file *m, struct task_struct *task)
409{ 333{
334 seq_printf(m, "Cpus_allowed:\t");
335 seq_cpumask(m, &task->cpus_allowed);
336 seq_printf(m, "\n");
337 seq_printf(m, "Cpus_allowed_list:\t");
338 seq_cpumask_list(m, &task->cpus_allowed);
339 seq_printf(m, "\n");
410} 340}
411#endif /* CONFIG_MMU */
412 341
413int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, 342int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
414 struct pid *pid, struct task_struct *task) 343 struct pid *pid, struct task_struct *task)
@@ -424,12 +353,12 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
424 } 353 }
425 task_sig(m, task); 354 task_sig(m, task);
426 task_cap(m, task); 355 task_cap(m, task);
356 task_cpus_allowed(m, task);
427 cpuset_task_status_allowed(m, task); 357 cpuset_task_status_allowed(m, task);
428#if defined(CONFIG_S390) 358#if defined(CONFIG_S390)
429 task_show_regs(m, task); 359 task_show_regs(m, task);
430#endif 360#endif
431 task_context_switch_counts(m, task); 361 task_context_switch_counts(m, task);
432 task_show_stack_usage(m, task);
433 return 0; 362 return 0;
434} 363}
435 364
@@ -495,20 +424,17 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
495 424
496 /* add up live thread stats at the group level */ 425 /* add up live thread stats at the group level */
497 if (whole) { 426 if (whole) {
498 struct task_cputime cputime;
499 struct task_struct *t = task; 427 struct task_struct *t = task;
500 do { 428 do {
501 min_flt += t->min_flt; 429 min_flt += t->min_flt;
502 maj_flt += t->maj_flt; 430 maj_flt += t->maj_flt;
503 gtime = cputime_add(gtime, task_gtime(t)); 431 gtime = cputime_add(gtime, t->gtime);
504 t = next_thread(t); 432 t = next_thread(t);
505 } while (t != task); 433 } while (t != task);
506 434
507 min_flt += sig->min_flt; 435 min_flt += sig->min_flt;
508 maj_flt += sig->maj_flt; 436 maj_flt += sig->maj_flt;
509 thread_group_cputime(task, &cputime); 437 thread_group_times(task, &utime, &stime);
510 utime = cputime.utime;
511 stime = cputime.stime;
512 gtime = cputime_add(gtime, sig->gtime); 438 gtime = cputime_add(gtime, sig->gtime);
513 } 439 }
514 440
@@ -524,9 +450,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
524 if (!whole) { 450 if (!whole) {
525 min_flt = task->min_flt; 451 min_flt = task->min_flt;
526 maj_flt = task->maj_flt; 452 maj_flt = task->maj_flt;
527 utime = task_utime(task); 453 task_times(task, &utime, &stime);
528 stime = task_stime(task); 454 gtime = task->gtime;
529 gtime = task_gtime(task);
530 } 455 }
531 456
532 /* scale priority and nice values from timeslices to -20..20 */ 457 /* scale priority and nice values from timeslices to -20..20 */
@@ -571,7 +496,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
571 rsslim, 496 rsslim,
572 mm ? mm->start_code : 0, 497 mm ? mm->start_code : 0,
573 mm ? mm->end_code : 0, 498 mm ? mm->end_code : 0,
574 (permitted) ? task->stack_start : 0, 499 (permitted && mm) ? task->stack_start : 0,
575 esp, 500 esp,
576 eip, 501 eip,
577 /* The signal information here is obsolete. 502 /* The signal information here is obsolete.
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 837469a96598..623e2ffb5d2b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1095,8 +1095,12 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
1095 if (!capable(CAP_AUDIT_CONTROL)) 1095 if (!capable(CAP_AUDIT_CONTROL))
1096 return -EPERM; 1096 return -EPERM;
1097 1097
1098 if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) 1098 rcu_read_lock();
1099 if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
1100 rcu_read_unlock();
1099 return -EPERM; 1101 return -EPERM;
1102 }
1103 rcu_read_unlock();
1100 1104
1101 if (count >= PAGE_SIZE) 1105 if (count >= PAGE_SIZE)
1102 count = PAGE_SIZE - 1; 1106 count = PAGE_SIZE - 1;
@@ -1265,6 +1269,72 @@ static const struct file_operations proc_pid_sched_operations = {
1265 1269
1266#endif 1270#endif
1267 1271
1272static ssize_t comm_write(struct file *file, const char __user *buf,
1273 size_t count, loff_t *offset)
1274{
1275 struct inode *inode = file->f_path.dentry->d_inode;
1276 struct task_struct *p;
1277 char buffer[TASK_COMM_LEN];
1278
1279 memset(buffer, 0, sizeof(buffer));
1280 if (count > sizeof(buffer) - 1)
1281 count = sizeof(buffer) - 1;
1282 if (copy_from_user(buffer, buf, count))
1283 return -EFAULT;
1284
1285 p = get_proc_task(inode);
1286 if (!p)
1287 return -ESRCH;
1288
1289 if (same_thread_group(current, p))
1290 set_task_comm(p, buffer);
1291 else
1292 count = -EINVAL;
1293
1294 put_task_struct(p);
1295
1296 return count;
1297}
1298
1299static int comm_show(struct seq_file *m, void *v)
1300{
1301 struct inode *inode = m->private;
1302 struct task_struct *p;
1303
1304 p = get_proc_task(inode);
1305 if (!p)
1306 return -ESRCH;
1307
1308 task_lock(p);
1309 seq_printf(m, "%s\n", p->comm);
1310 task_unlock(p);
1311
1312 put_task_struct(p);
1313
1314 return 0;
1315}
1316
1317static int comm_open(struct inode *inode, struct file *filp)
1318{
1319 int ret;
1320
1321 ret = single_open(filp, comm_show, NULL);
1322 if (!ret) {
1323 struct seq_file *m = filp->private_data;
1324
1325 m->private = inode;
1326 }
1327 return ret;
1328}
1329
1330static const struct file_operations proc_pid_set_comm_operations = {
1331 .open = comm_open,
1332 .read = seq_read,
1333 .write = comm_write,
1334 .llseek = seq_lseek,
1335 .release = single_release,
1336};
1337
1268/* 1338/*
1269 * We added or removed a vma mapping the executable. The vmas are only mapped 1339 * 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. 1340 * during exec and are not mapped with the mmap system call.
@@ -1353,7 +1423,6 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
1353 goto out; 1423 goto out;
1354 1424
1355 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path); 1425 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
1356 nd->last_type = LAST_BIND;
1357out: 1426out:
1358 return ERR_PTR(error); 1427 return ERR_PTR(error);
1359} 1428}
@@ -2200,7 +2269,7 @@ static const struct inode_operations proc_attr_dir_inode_operations = {
2200 2269
2201#endif 2270#endif
2202 2271
2203#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 2272#ifdef CONFIG_ELF_CORE
2204static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf, 2273static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf,
2205 size_t count, loff_t *ppos) 2274 size_t count, loff_t *ppos)
2206{ 2275{
@@ -2304,16 +2373,30 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
2304{ 2373{
2305 struct pid_namespace *ns = dentry->d_sb->s_fs_info; 2374 struct pid_namespace *ns = dentry->d_sb->s_fs_info;
2306 pid_t tgid = task_tgid_nr_ns(current, ns); 2375 pid_t tgid = task_tgid_nr_ns(current, ns);
2307 char tmp[PROC_NUMBUF]; 2376 char *name = ERR_PTR(-ENOENT);
2308 if (!tgid) 2377 if (tgid) {
2309 return ERR_PTR(-ENOENT); 2378 name = __getname();
2310 sprintf(tmp, "%d", task_tgid_nr_ns(current, ns)); 2379 if (!name)
2311 return ERR_PTR(vfs_follow_link(nd,tmp)); 2380 name = ERR_PTR(-ENOMEM);
2381 else
2382 sprintf(name, "%d", tgid);
2383 }
2384 nd_set_link(nd, name);
2385 return NULL;
2386}
2387
2388static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
2389 void *cookie)
2390{
2391 char *s = nd_get_link(nd);
2392 if (!IS_ERR(s))
2393 __putname(s);
2312} 2394}
2313 2395
2314static const struct inode_operations proc_self_inode_operations = { 2396static const struct inode_operations proc_self_inode_operations = {
2315 .readlink = proc_self_readlink, 2397 .readlink = proc_self_readlink,
2316 .follow_link = proc_self_follow_link, 2398 .follow_link = proc_self_follow_link,
2399 .put_link = proc_self_put_link,
2317}; 2400};
2318 2401
2319/* 2402/*
@@ -2504,6 +2587,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2504#ifdef CONFIG_SCHED_DEBUG 2587#ifdef CONFIG_SCHED_DEBUG
2505 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), 2588 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2506#endif 2589#endif
2590 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2507#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2591#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2508 INF("syscall", S_IRUSR, proc_pid_syscall), 2592 INF("syscall", S_IRUSR, proc_pid_syscall),
2509#endif 2593#endif
@@ -2556,7 +2640,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2556#ifdef CONFIG_FAULT_INJECTION 2640#ifdef CONFIG_FAULT_INJECTION
2557 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), 2641 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
2558#endif 2642#endif
2559#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 2643#ifdef CONFIG_ELF_CORE
2560 REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), 2644 REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
2561#endif 2645#endif
2562#ifdef CONFIG_TASK_IO_ACCOUNTING 2646#ifdef CONFIG_TASK_IO_ACCOUNTING
@@ -2597,8 +2681,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
2597 name.len = snprintf(buf, sizeof(buf), "%d", pid); 2681 name.len = snprintf(buf, sizeof(buf), "%d", pid);
2598 dentry = d_hash_and_lookup(mnt->mnt_root, &name); 2682 dentry = d_hash_and_lookup(mnt->mnt_root, &name);
2599 if (dentry) { 2683 if (dentry) {
2600 if (!(current->flags & PF_EXITING)) 2684 shrink_dcache_parent(dentry);
2601 shrink_dcache_parent(dentry);
2602 d_drop(dentry); 2685 d_drop(dentry);
2603 dput(dentry); 2686 dput(dentry);
2604 } 2687 }
@@ -2839,6 +2922,7 @@ static const struct pid_entry tid_base_stuff[] = {
2839#ifdef CONFIG_SCHED_DEBUG 2922#ifdef CONFIG_SCHED_DEBUG
2840 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), 2923 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2841#endif 2924#endif
2925 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2842#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2926#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2843 INF("syscall", S_IRUSR, proc_pid_syscall), 2927 INF("syscall", S_IRUSR, proc_pid_syscall),
2844#endif 2928#endif
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index fa678abc9db1..480cb1065eec 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -429,7 +429,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
429 unsigned int ino; 429 unsigned int ino;
430 430
431 ino = de->low_ino; 431 ino = de->low_ino;
432 de_get(de); 432 pde_get(de);
433 spin_unlock(&proc_subdir_lock); 433 spin_unlock(&proc_subdir_lock);
434 error = -EINVAL; 434 error = -EINVAL;
435 inode = proc_get_inode(dir->i_sb, ino, de); 435 inode = proc_get_inode(dir->i_sb, ino, de);
@@ -445,7 +445,7 @@ out_unlock:
445 return NULL; 445 return NULL;
446 } 446 }
447 if (de) 447 if (de)
448 de_put(de); 448 pde_put(de);
449 return ERR_PTR(error); 449 return ERR_PTR(error);
450} 450}
451 451
@@ -509,17 +509,17 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
509 struct proc_dir_entry *next; 509 struct proc_dir_entry *next;
510 510
511 /* filldir passes info to user space */ 511 /* filldir passes info to user space */
512 de_get(de); 512 pde_get(de);
513 spin_unlock(&proc_subdir_lock); 513 spin_unlock(&proc_subdir_lock);
514 if (filldir(dirent, de->name, de->namelen, filp->f_pos, 514 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
515 de->low_ino, de->mode >> 12) < 0) { 515 de->low_ino, de->mode >> 12) < 0) {
516 de_put(de); 516 pde_put(de);
517 goto out; 517 goto out;
518 } 518 }
519 spin_lock(&proc_subdir_lock); 519 spin_lock(&proc_subdir_lock);
520 filp->f_pos++; 520 filp->f_pos++;
521 next = de->next; 521 next = de->next;
522 de_put(de); 522 pde_put(de);
523 de = next; 523 de = next;
524 } while (de); 524 } while (de);
525 spin_unlock(&proc_subdir_lock); 525 spin_unlock(&proc_subdir_lock);
@@ -763,7 +763,7 @@ out:
763 return NULL; 763 return NULL;
764} 764}
765 765
766void free_proc_entry(struct proc_dir_entry *de) 766static void free_proc_entry(struct proc_dir_entry *de)
767{ 767{
768 unsigned int ino = de->low_ino; 768 unsigned int ino = de->low_ino;
769 769
@@ -777,6 +777,12 @@ void free_proc_entry(struct proc_dir_entry *de)
777 kfree(de); 777 kfree(de);
778} 778}
779 779
780void pde_put(struct proc_dir_entry *pde)
781{
782 if (atomic_dec_and_test(&pde->count))
783 free_proc_entry(pde);
784}
785
780/* 786/*
781 * Remove a /proc entry and free it if it's not currently in use. 787 * Remove a /proc entry and free it if it's not currently in use.
782 */ 788 */
@@ -845,6 +851,5 @@ continue_removing:
845 WARN(de->subdir, KERN_WARNING "%s: removing non-empty directory " 851 WARN(de->subdir, KERN_WARNING "%s: removing non-empty directory "
846 "'%s/%s', leaking at least '%s'\n", __func__, 852 "'%s/%s', leaking at least '%s'\n", __func__,
847 de->parent->name, de->name, de->subdir->name); 853 de->parent->name, de->name, de->subdir->name);
848 if (atomic_dec_and_test(&de->count)) 854 pde_put(de);
849 free_proc_entry(de);
850} 855}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index d78ade305541..445a02bcaab3 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -24,29 +24,6 @@
24 24
25#include "internal.h" 25#include "internal.h"
26 26
27struct proc_dir_entry *de_get(struct proc_dir_entry *de)
28{
29 atomic_inc(&de->count);
30 return de;
31}
32
33/*
34 * Decrements the use count and checks for deferred deletion.
35 */
36void de_put(struct proc_dir_entry *de)
37{
38 if (!atomic_read(&de->count)) {
39 printk("de_put: entry %s already free!\n", de->name);
40 return;
41 }
42
43 if (atomic_dec_and_test(&de->count))
44 free_proc_entry(de);
45}
46
47/*
48 * Decrement the use count of the proc_dir_entry.
49 */
50static void proc_delete_inode(struct inode *inode) 27static void proc_delete_inode(struct inode *inode)
51{ 28{
52 struct proc_dir_entry *de; 29 struct proc_dir_entry *de;
@@ -59,7 +36,7 @@ static void proc_delete_inode(struct inode *inode)
59 /* Let go of any associated proc directory entry */ 36 /* Let go of any associated proc directory entry */
60 de = PROC_I(inode)->pde; 37 de = PROC_I(inode)->pde;
61 if (de) 38 if (de)
62 de_put(de); 39 pde_put(de);
63 if (PROC_I(inode)->sysctl) 40 if (PROC_I(inode)->sysctl)
64 sysctl_head_put(PROC_I(inode)->sysctl); 41 sysctl_head_put(PROC_I(inode)->sysctl);
65 clear_inode(inode); 42 clear_inode(inode);
@@ -480,7 +457,7 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
480 } 457 }
481 unlock_new_inode(inode); 458 unlock_new_inode(inode);
482 } else 459 } else
483 de_put(de); 460 pde_put(de);
484 return inode; 461 return inode;
485} 462}
486 463
@@ -495,7 +472,7 @@ int proc_fill_super(struct super_block *s)
495 s->s_op = &proc_sops; 472 s->s_op = &proc_sops;
496 s->s_time_gran = 1; 473 s->s_time_gran = 1;
497 474
498 de_get(&proc_root); 475 pde_get(&proc_root);
499 root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); 476 root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
500 if (!root_inode) 477 if (!root_inode)
501 goto out_no_root; 478 goto out_no_root;
@@ -509,6 +486,6 @@ int proc_fill_super(struct super_block *s)
509out_no_root: 486out_no_root:
510 printk("proc_read_super: get root inode failed\n"); 487 printk("proc_read_super: get root inode failed\n");
511 iput(root_inode); 488 iput(root_inode);
512 de_put(&proc_root); 489 pde_put(&proc_root);
513 return -ENOMEM; 490 return -ENOMEM;
514} 491}
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 753ca37002c8..1f24a3eddd12 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -61,8 +61,6 @@ extern const struct file_operations proc_pagemap_operations;
61extern const struct file_operations proc_net_operations; 61extern const struct file_operations proc_net_operations;
62extern const struct inode_operations proc_net_inode_operations; 62extern const struct inode_operations proc_net_inode_operations;
63 63
64void free_proc_entry(struct proc_dir_entry *de);
65
66void proc_init_inodecache(void); 64void proc_init_inodecache(void);
67 65
68static inline struct pid *proc_pid(struct inode *inode) 66static inline struct pid *proc_pid(struct inode *inode)
@@ -101,8 +99,12 @@ unsigned long task_vsize(struct mm_struct *);
101int task_statm(struct mm_struct *, int *, int *, int *, int *); 99int task_statm(struct mm_struct *, int *, int *, int *, int *);
102void task_mem(struct seq_file *, struct mm_struct *); 100void task_mem(struct seq_file *, struct mm_struct *);
103 101
104struct proc_dir_entry *de_get(struct proc_dir_entry *de); 102static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
105void de_put(struct proc_dir_entry *de); 103{
104 atomic_inc(&pde->count);
105 return pde;
106}
107void pde_put(struct proc_dir_entry *pde);
106 108
107extern struct vfsmount *proc_mnt; 109extern struct vfsmount *proc_mnt;
108int proc_fill_super(struct super_block *); 110int proc_fill_super(struct super_block *);
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 5033ce0d254b..180cf5a0bd67 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -8,6 +8,7 @@
8#include <linux/proc_fs.h> 8#include <linux/proc_fs.h>
9#include <linux/seq_file.h> 9#include <linux/seq_file.h>
10#include <linux/hugetlb.h> 10#include <linux/hugetlb.h>
11#include <linux/kernel-page-flags.h>
11#include <asm/uaccess.h> 12#include <asm/uaccess.h>
12#include "internal.h" 13#include "internal.h"
13 14
@@ -71,52 +72,12 @@ static const struct file_operations proc_kpagecount_operations = {
71 * physical page flags. 72 * physical page flags.
72 */ 73 */
73 74
74/* These macros are used to decouple internal flags from exported ones */
75
76#define KPF_LOCKED 0
77#define KPF_ERROR 1
78#define KPF_REFERENCED 2
79#define KPF_UPTODATE 3
80#define KPF_DIRTY 4
81#define KPF_LRU 5
82#define KPF_ACTIVE 6
83#define KPF_SLAB 7
84#define KPF_WRITEBACK 8
85#define KPF_RECLAIM 9
86#define KPF_BUDDY 10
87
88/* 11-20: new additions in 2.6.31 */
89#define KPF_MMAP 11
90#define KPF_ANON 12
91#define KPF_SWAPCACHE 13
92#define KPF_SWAPBACKED 14
93#define KPF_COMPOUND_HEAD 15
94#define KPF_COMPOUND_TAIL 16
95#define KPF_HUGE 17
96#define KPF_UNEVICTABLE 18
97#define KPF_HWPOISON 19
98#define KPF_NOPAGE 20
99
100#define KPF_KSM 21
101
102/* kernel hacking assistances
103 * WARNING: subject to change, never rely on them!
104 */
105#define KPF_RESERVED 32
106#define KPF_MLOCKED 33
107#define KPF_MAPPEDTODISK 34
108#define KPF_PRIVATE 35
109#define KPF_PRIVATE_2 36
110#define KPF_OWNER_PRIVATE 37
111#define KPF_ARCH 38
112#define KPF_UNCACHED 39
113
114static inline u64 kpf_copy_bit(u64 kflags, int ubit, int kbit) 75static inline u64 kpf_copy_bit(u64 kflags, int ubit, int kbit)
115{ 76{
116 return ((kflags >> kbit) & 1) << ubit; 77 return ((kflags >> kbit) & 1) << ubit;
117} 78}
118 79
119static u64 get_uflags(struct page *page) 80u64 stable_page_flags(struct page *page)
120{ 81{
121 u64 k; 82 u64 k;
122 u64 u; 83 u64 u;
@@ -219,7 +180,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
219 else 180 else
220 ppage = NULL; 181 ppage = NULL;
221 182
222 if (put_user(get_uflags(ppage), out)) { 183 if (put_user(stable_page_flags(ppage), out)) {
223 ret = -EFAULT; 184 ret = -EFAULT;
224 break; 185 break;
225 } 186 }
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 7ba79a54948c..f8650dce74fb 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -7,44 +7,49 @@
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>
13#include <linux/of.h>
14#include <linux/module.h>
12#include <asm/prom.h> 15#include <asm/prom.h>
13#include <asm/uaccess.h> 16#include <asm/uaccess.h>
14#include "internal.h" 17#include "internal.h"
15 18
16#ifndef HAVE_ARCH_DEVTREE_FIXUPS
17static inline void set_node_proc_entry(struct device_node *np, 19static inline void set_node_proc_entry(struct device_node *np,
18 struct proc_dir_entry *de) 20 struct proc_dir_entry *de)
19{ 21{
20} 22#ifdef HAVE_ARCH_DEVTREE_FIXUPS
23 np->pde = de;
21#endif 24#endif
25}
22 26
23static struct proc_dir_entry *proc_device_tree; 27static struct proc_dir_entry *proc_device_tree;
24 28
25/* 29/*
26 * Supply data on a read from /proc/device-tree/node/property. 30 * Supply data on a read from /proc/device-tree/node/property.
27 */ 31 */
28static int property_read_proc(char *page, char **start, off_t off, 32static int property_proc_show(struct seq_file *m, void *v)
29 int count, int *eof, void *data)
30{ 33{
31 struct property *pp = data; 34 struct property *pp = m->private;
32 int n;
33 35
34 if (off >= pp->length) { 36 seq_write(m, pp->value, pp->length);
35 *eof = 1; 37 return 0;
36 return 0;
37 }
38 n = pp->length - off;
39 if (n > count)
40 n = count;
41 else
42 *eof = 1;
43 memcpy(page, (char *)pp->value + off, n);
44 *start = page;
45 return n;
46} 38}
47 39
40static int property_proc_open(struct inode *inode, struct file *file)
41{
42 return single_open(file, property_proc_show, PDE(inode)->data);
43}
44
45static const struct file_operations property_proc_fops = {
46 .owner = THIS_MODULE,
47 .open = property_proc_open,
48 .read = seq_read,
49 .llseek = seq_lseek,
50 .release = single_release,
51};
52
48/* 53/*
49 * For a node with a name like "gc@10", we make symlinks called "gc" 54 * For a node with a name like "gc@10", we make symlinks called "gc"
50 * and "@10" to it. 55 * and "@10" to it.
@@ -63,10 +68,9 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp,
63 * Unfortunately proc_register puts each new entry 68 * Unfortunately proc_register puts each new entry
64 * at the beginning of the list. So we rearrange them. 69 * at the beginning of the list. So we rearrange them.
65 */ 70 */
66 ent = create_proc_read_entry(name, 71 ent = proc_create_data(name,
67 strncmp(name, "security-", 9) 72 strncmp(name, "security-", 9) ? S_IRUGO : S_IRUSR,
68 ? S_IRUGO : S_IRUSR, de, 73 de, &property_proc_fops, pp);
69 property_read_proc, pp);
70 if (ent == NULL) 74 if (ent == NULL)
71 return NULL; 75 return NULL;
72 76
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..f277c4a111cb 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -361,12 +361,11 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
361 if (!pte_present(ptent)) 361 if (!pte_present(ptent))
362 continue; 362 continue;
363 363
364 mss->resident += PAGE_SIZE;
365
366 page = vm_normal_page(vma, addr, ptent); 364 page = vm_normal_page(vma, addr, ptent);
367 if (!page) 365 if (!page)
368 continue; 366 continue;
369 367
368 mss->resident += PAGE_SIZE;
370 /* Accumulate the size in pages that have been accessed. */ 369 /* Accumulate the size in pages that have been accessed. */
371 if (pte_young(ptent) || PageReferenced(page)) 370 if (pte_young(ptent) || PageReferenced(page))
372 mss->referenced += PAGE_SIZE; 371 mss->referenced += PAGE_SIZE;
@@ -650,6 +649,50 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
650 return err; 649 return err;
651} 650}
652 651
652static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset)
653{
654 u64 pme = 0;
655 if (pte_present(pte))
656 pme = PM_PFRAME(pte_pfn(pte) + offset)
657 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
658 return pme;
659}
660
661static int pagemap_hugetlb_range(pte_t *pte, unsigned long addr,
662 unsigned long end, struct mm_walk *walk)
663{
664 struct vm_area_struct *vma;
665 struct pagemapread *pm = walk->private;
666 struct hstate *hs = NULL;
667 int err = 0;
668
669 vma = find_vma(walk->mm, addr);
670 if (vma)
671 hs = hstate_vma(vma);
672 for (; addr != end; addr += PAGE_SIZE) {
673 u64 pfn = PM_NOT_PRESENT;
674
675 if (vma && (addr >= vma->vm_end)) {
676 vma = find_vma(walk->mm, addr);
677 if (vma)
678 hs = hstate_vma(vma);
679 }
680
681 if (vma && (vma->vm_start <= addr) && is_vm_hugetlb_page(vma)) {
682 /* calculate pfn of the "raw" page in the hugepage. */
683 int offset = (addr & ~huge_page_mask(hs)) >> PAGE_SHIFT;
684 pfn = huge_pte_to_pagemap_entry(*pte, offset);
685 }
686 err = add_to_pagemap(addr, pfn, pm);
687 if (err)
688 return err;
689 }
690
691 cond_resched();
692
693 return err;
694}
695
653/* 696/*
654 * /proc/pid/pagemap - an array mapping virtual pages to pfns 697 * /proc/pid/pagemap - an array mapping virtual pages to pfns
655 * 698 *
@@ -742,6 +785,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
742 785
743 pagemap_walk.pmd_entry = pagemap_pte_range; 786 pagemap_walk.pmd_entry = pagemap_pte_range;
744 pagemap_walk.pte_hole = pagemap_pte_hole; 787 pagemap_walk.pte_hole = pagemap_pte_hole;
788 pagemap_walk.hugetlb_entry = pagemap_hugetlb_range;
745 pagemap_walk.mm = mm; 789 pagemap_walk.mm = mm;
746 pagemap_walk.private = &pm; 790 pagemap_walk.private = &pm;
747 791
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}