aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/array.c')
-rw-r--r--fs/proc/array.c115
1 files changed, 106 insertions, 9 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 725a650bbbb8..4badde179b18 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -82,6 +82,7 @@
82#include <linux/pid_namespace.h> 82#include <linux/pid_namespace.h>
83#include <linux/ptrace.h> 83#include <linux/ptrace.h>
84#include <linux/tracehook.h> 84#include <linux/tracehook.h>
85#include <linux/swapops.h>
85 86
86#include <asm/pgtable.h> 87#include <asm/pgtable.h>
87#include <asm/processor.h> 88#include <asm/processor.h>
@@ -321,6 +322,104 @@ static inline void task_context_switch_counts(struct seq_file *m,
321 p->nivcsw); 322 p->nivcsw);
322} 323}
323 324
325#ifdef CONFIG_MMU
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{
410}
411#endif /* CONFIG_MMU */
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
324int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, 423int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
325 struct pid *pid, struct task_struct *task) 424 struct pid *pid, struct task_struct *task)
326{ 425{
@@ -335,11 +434,13 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
335 } 434 }
336 task_sig(m, task); 435 task_sig(m, task);
337 task_cap(m, task); 436 task_cap(m, task);
437 task_cpus_allowed(m, task);
338 cpuset_task_status_allowed(m, task); 438 cpuset_task_status_allowed(m, task);
339#if defined(CONFIG_S390) 439#if defined(CONFIG_S390)
340 task_show_regs(m, task); 440 task_show_regs(m, task);
341#endif 441#endif
342 task_context_switch_counts(m, task); 442 task_context_switch_counts(m, task);
443 task_show_stack_usage(m, task);
343 return 0; 444 return 0;
344} 445}
345 446
@@ -405,20 +506,17 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
405 506
406 /* add up live thread stats at the group level */ 507 /* add up live thread stats at the group level */
407 if (whole) { 508 if (whole) {
408 struct task_cputime cputime;
409 struct task_struct *t = task; 509 struct task_struct *t = task;
410 do { 510 do {
411 min_flt += t->min_flt; 511 min_flt += t->min_flt;
412 maj_flt += t->maj_flt; 512 maj_flt += t->maj_flt;
413 gtime = cputime_add(gtime, task_gtime(t)); 513 gtime = cputime_add(gtime, t->gtime);
414 t = next_thread(t); 514 t = next_thread(t);
415 } while (t != task); 515 } while (t != task);
416 516
417 min_flt += sig->min_flt; 517 min_flt += sig->min_flt;
418 maj_flt += sig->maj_flt; 518 maj_flt += sig->maj_flt;
419 thread_group_cputime(task, &cputime); 519 thread_group_times(task, &utime, &stime);
420 utime = cputime.utime;
421 stime = cputime.stime;
422 gtime = cputime_add(gtime, sig->gtime); 520 gtime = cputime_add(gtime, sig->gtime);
423 } 521 }
424 522
@@ -434,9 +532,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
434 if (!whole) { 532 if (!whole) {
435 min_flt = task->min_flt; 533 min_flt = task->min_flt;
436 maj_flt = task->maj_flt; 534 maj_flt = task->maj_flt;
437 utime = task_utime(task); 535 task_times(task, &utime, &stime);
438 stime = task_stime(task); 536 gtime = task->gtime;
439 gtime = task_gtime(task);
440 } 537 }
441 538
442 /* scale priority and nice values from timeslices to -20..20 */ 539 /* scale priority and nice values from timeslices to -20..20 */
@@ -481,7 +578,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
481 rsslim, 578 rsslim,
482 mm ? mm->start_code : 0, 579 mm ? mm->start_code : 0,
483 mm ? mm->end_code : 0, 580 mm ? mm->end_code : 0,
484 (permitted && mm) ? mm->start_stack : 0, 581 (permitted && mm) ? task->stack_start : 0,
485 esp, 582 esp,
486 eip, 583 eip,
487 /* The signal information here is obsolete. 584 /* The signal information here is obsolete.