aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@openvz.org>2012-12-17 19:03:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-17 20:15:22 -0500
commit834f82e2aa9a8ede94b17b656329f850c1471514 (patch)
treedbd2a721c3b6b4c7d3cd5826a9ceb867158a1941
parent7b9a7ec565505699f503b4fcf61500dceb36e744 (diff)
procfs: add VmFlags field in smaps output
During c/r sessions we've found that there is no way at the moment to fetch some VMA associated flags, such as mlock() and madvise(). This leads us to a problem -- we don't know if we should call for mlock() and/or madvise() after restore on the vma area we're bringing back to life. This patch intorduces a new field into "smaps" output called VmFlags, where all set flags associated with the particular VMA is shown as two letter mnemonics. [ Strictly speaking for c/r we only need mlock/madvise bits but it has been said that providing just a few flags looks somehow inconsistent. So all flags are here now. ] This feature is made available on CONFIG_CHECKPOINT_RESTORE=n kernels, as other applications may start to use these fields. The data is encoded in a somewhat awkward two letters mnemonic form, to encourage userspace to be prepared for fields being added or removed in the future. [a.p.zijlstra@chello.nl: props to use for_each_set_bit] [sfr@canb.auug.org.au: props to use array instead of struct] [akpm@linux-foundation.org: overall redesign and simplification] [akpm@linux-foundation.org: remove unneeded braces per sfr, avoid using bloaty for_each_set_bit()] Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/filesystems/proc.txt40
-rw-r--r--fs/proc/task_mmu.c53
2 files changed, 91 insertions, 2 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 3844d21d6ca3..74cb394e6888 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -142,7 +142,7 @@ Table 1-1: Process specific entries in /proc
142 pagemap Page table 142 pagemap Page table
143 stack Report full stack trace, enable via CONFIG_STACKTRACE 143 stack Report full stack trace, enable via CONFIG_STACKTRACE
144 smaps a extension based on maps, showing the memory consumption of 144 smaps a extension based on maps, showing the memory consumption of
145 each mapping 145 each mapping and flags associated with it
146.............................................................................. 146..............................................................................
147 147
148For example, to get the status information of a process, all you have to do is 148For example, to get the status information of a process, all you have to do is
@@ -415,8 +415,9 @@ Swap: 0 kB
415KernelPageSize: 4 kB 415KernelPageSize: 4 kB
416MMUPageSize: 4 kB 416MMUPageSize: 4 kB
417Locked: 374 kB 417Locked: 374 kB
418VmFlags: rd ex mr mw me de
418 419
419The first of these lines shows the same information as is displayed for the 420the first of these lines shows the same information as is displayed for the
420mapping in /proc/PID/maps. The remaining lines show the size of the mapping 421mapping in /proc/PID/maps. The remaining lines show the size of the mapping
421(size), the amount of the mapping that is currently resident in RAM (RSS), the 422(size), the amount of the mapping that is currently resident in RAM (RSS), the
422process' proportional share of this mapping (PSS), the number of clean and 423process' proportional share of this mapping (PSS), the number of clean and
@@ -430,6 +431,41 @@ and a page is modified, the file page is replaced by a private anonymous copy.
430"Swap" shows how much would-be-anonymous memory is also used, but out on 431"Swap" shows how much would-be-anonymous memory is also used, but out on
431swap. 432swap.
432 433
434"VmFlags" field deserves a separate description. This member represents the kernel
435flags associated with the particular virtual memory area in two letter encoded
436manner. The codes are the following:
437 rd - readable
438 wr - writeable
439 ex - executable
440 sh - shared
441 mr - may read
442 mw - may write
443 me - may execute
444 ms - may share
445 gd - stack segment growns down
446 pf - pure PFN range
447 dw - disabled write to the mapped file
448 lo - pages are locked in memory
449 io - memory mapped I/O area
450 sr - sequential read advise provided
451 rr - random read advise provided
452 dc - do not copy area on fork
453 de - do not expand area on remapping
454 ac - area is accountable
455 nr - swap space is not reserved for the area
456 ht - area uses huge tlb pages
457 nl - non-linear mapping
458 ar - architecture specific flag
459 dd - do not include area into core dump
460 mm - mixed map area
461 hg - huge page advise flag
462 nh - no-huge page advise flag
463 mg - mergable advise flag
464
465Note that there is no guarantee that every flag and associated mnemonic will
466be present in all further kernel releases. Things get changed, the flags may
467be vanished or the reverse -- new added.
468
433This file is only present if the CONFIG_MMU kernel configuration option is 469This file is only present if the CONFIG_MMU kernel configuration option is
434enabled. 470enabled.
435 471
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 48775628abbf..448455b7fd91 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -526,6 +526,57 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
526 return 0; 526 return 0;
527} 527}
528 528
529static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
530{
531 /*
532 * Don't forget to update Documentation/ on changes.
533 */
534 static const char mnemonics[BITS_PER_LONG][2] = {
535 /*
536 * In case if we meet a flag we don't know about.
537 */
538 [0 ... (BITS_PER_LONG-1)] = "??",
539
540 [ilog2(VM_READ)] = "rd",
541 [ilog2(VM_WRITE)] = "wr",
542 [ilog2(VM_EXEC)] = "ex",
543 [ilog2(VM_SHARED)] = "sh",
544 [ilog2(VM_MAYREAD)] = "mr",
545 [ilog2(VM_MAYWRITE)] = "mw",
546 [ilog2(VM_MAYEXEC)] = "me",
547 [ilog2(VM_MAYSHARE)] = "ms",
548 [ilog2(VM_GROWSDOWN)] = "gd",
549 [ilog2(VM_PFNMAP)] = "pf",
550 [ilog2(VM_DENYWRITE)] = "dw",
551 [ilog2(VM_LOCKED)] = "lo",
552 [ilog2(VM_IO)] = "io",
553 [ilog2(VM_SEQ_READ)] = "sr",
554 [ilog2(VM_RAND_READ)] = "rr",
555 [ilog2(VM_DONTCOPY)] = "dc",
556 [ilog2(VM_DONTEXPAND)] = "de",
557 [ilog2(VM_ACCOUNT)] = "ac",
558 [ilog2(VM_NORESERVE)] = "nr",
559 [ilog2(VM_HUGETLB)] = "ht",
560 [ilog2(VM_NONLINEAR)] = "nl",
561 [ilog2(VM_ARCH_1)] = "ar",
562 [ilog2(VM_DONTDUMP)] = "dd",
563 [ilog2(VM_MIXEDMAP)] = "mm",
564 [ilog2(VM_HUGEPAGE)] = "hg",
565 [ilog2(VM_NOHUGEPAGE)] = "nh",
566 [ilog2(VM_MERGEABLE)] = "mg",
567 };
568 size_t i;
569
570 seq_puts(m, "VmFlags: ");
571 for (i = 0; i < BITS_PER_LONG; i++) {
572 if (vma->vm_flags & (1UL << i)) {
573 seq_printf(m, "%c%c ",
574 mnemonics[i][0], mnemonics[i][1]);
575 }
576 }
577 seq_putc(m, '\n');
578}
579
529static int show_smap(struct seq_file *m, void *v, int is_pid) 580static int show_smap(struct seq_file *m, void *v, int is_pid)
530{ 581{
531 struct proc_maps_private *priv = m->private; 582 struct proc_maps_private *priv = m->private;
@@ -581,6 +632,8 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
581 seq_printf(m, "Nonlinear: %8lu kB\n", 632 seq_printf(m, "Nonlinear: %8lu kB\n",
582 mss.nonlinear >> 10); 633 mss.nonlinear >> 10);
583 634
635 show_smap_vma_flags(m, vma);
636
584 if (m->count < m->size) /* vma is copied successfully */ 637 if (m->count < m->size) /* vma is copied successfully */
585 m->version = (vma != get_gate_vma(task->mm)) 638 m->version = (vma != get_gate_vma(task->mm))
586 ? vma->vm_start : 0; 639 ? vma->vm_start : 0;