Introducing VmFlags field into smaps output
Subsystems (3)
cover Introducing VmFlags field into smaps output
Hi guys, 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(), thus the patches in this series intorduce new field into "smaps" output called VmFlags where all flags associated with the particular VMA is shown in two letter mnemonic.
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.
Please review. Comments and complains are quite welcome!
Thanks,
Cyrill
RFC 1/2 procfs: Add VmFlags field in smaps output
When we do restore VMA area after checkpoint we would like to know if the area was locked or say it had mergeable attribute, but at moment the kernel does not provide such information, thus we can't figure out if we should call mlock/madvise on VMA restore.
This patch adds new VmFlags field to smaps output with vma->vm_flags encoded.
--- fs/proc/task_mmu.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
fs/proc/task_mmu.c +32 -0
@@ -480,6 +480,36 @@ static int smaps_pte_range(pmd_t *pmd, ureturn 0 ; } +static void show_smap_vma_flags (struct seq_file *m,struct vm_area_struct *vma) +{ +/* +* Don't forget to update Documentation/ on changes. +*/ +#define __VM_FLAG (_f) (!!(vma->vm_flags & (_f))) +seq_printf (m,"VmFlags: " +"RD:%d WR:%d EX:%d SH:%d MR:%d " +"MW:%d ME:%d MS:%d GD:%d PF:%d " +"DW:%d LO:%d IO:%d SR:%d RR:%d " +"DC:%d DE:%d AC:%d NR:%d HT:%d " +"NL:%d AR:%d DD:%d MM:%d HG:%d " +"NH:%d MG:%d\n" , +__VM_FLAG (VM_READ ),__VM_FLAG (VM_WRITE ), +__VM_FLAG (VM_EXEC ),__VM_FLAG (VM_SHARED ), +__VM_FLAG (VM_MAYREAD ),__VM_FLAG (VM_MAYWRITE ), +__VM_FLAG (VM_MAYEXEC ),__VM_FLAG (VM_MAYSHARE ), +__VM_FLAG (VM_GROWSDOWN ),__VM_FLAG (VM_PFNMAP ), +__VM_FLAG (VM_DENYWRITE ),__VM_FLAG (VM_LOCKED ), +__VM_FLAG (VM_IO ),__VM_FLAG (VM_SEQ_READ ), +__VM_FLAG (VM_RAND_READ ),__VM_FLAG (VM_DONTCOPY ), +__VM_FLAG (VM_DONTEXPAND ),__VM_FLAG (VM_ACCOUNT ), +__VM_FLAG (VM_NORESERVE ),__VM_FLAG (VM_HUGETLB ), +__VM_FLAG (VM_NONLINEAR ),__VM_FLAG (VM_ARCH_1 ), +__VM_FLAG (VM_DONTDUMP ),__VM_FLAG (VM_MIXEDMAP ), +__VM_FLAG (VM_HUGEPAGE ),__VM_FLAG (VM_NOHUGEPAGE ), +__VM_FLAG (VM_MERGEABLE )); +#undef __VM_FLAG +} +static int show_smap (struct seq_file *m,void *v,int is_pid) {struct proc_maps_private *priv = m->private;
@@ -535,6 +565,8 @@ static int show_smap(struct seq_file *m,seq_printf (m,"Nonlinear: %8lu kB\n" , mss.nonlinear >>10 ); +show_smap_vma_flags (m, vma); +if (m->count < m->size)/* vma is copied successfully */ m->version = (vma !=get_gate_vma (task->mm)) ? vma->vm_start :0 ;
RFC 2/2 procfs: Documantation -- Add VmFlags field description
In reply to Cyrill Gorcunov--- Documentation/filesystems/proc.txt | 38 ++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-)
Documentation/filesystems/proc.txt +37 -1
@@ -142,7 +142,7 @@ Table 1-1: Process specific entries in / pagemap Page table stack Report full stack trace, enable via CONFIG_STACKTRACE smaps a extension based on maps, showing the memory consumption of - each mapping + each mapping and flags associated with it .............................................................................. For example, to get the status information of a process, all you have to do is
@@ -415,6 +415,7 @@ Swap: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 374 kB +VmFlags: RD:1 WR:0 EX:1 SH:0 MR:1 MW:1 ME:1 MS:0 GD:0 PF:0 DW:1 LO:0 IO:0 SR:0 RR:0 DC:0 DE:0 AC:0 NR:0 HT:0 NL:0 AR:0 DD:0 MM:0 HG:0 NH:0 MG:0 The first of these lines shows the same information as is displayed for the mapping in /proc/PID/maps. The remaining lines show the size of the mapping
@@ -430,6 +431,41 @@ and a page is modified, the file page is "Swap" shows how much would-be-anonymous memory is also used, but out on swap. +"VmFlags" field deserves a separate description. This member represents the kernel +flags associated with the particular virtual memory area in two letter encoded +manner. The codes are the following: + RD - readable + WR - writeable + EX - executable + SH - shared + MR - may read + MW - may write + ME - may execute + MS - may share + GD - stack segment growns down + PF - pure PFN range + DW - disabled write to the mapped file + LO - pages are locked in memory + IO - memory mapped I/O area + SR - sequential read advise provided + RR - random read advise provided + DC - do not copy area on fork + DE - do not expand area on remapping + AC - area is accountable + NR - swap space is not reserved for the area + HT - area uses huge tlb pages + NL - non-linear mapping + AR - architecture specific flag + DD - do not include area into core dump + MM - mixed map area + HG - huge page advise flag + NH - no-huge page advise flag + MG - mergable advise flag + +Note that there is no guarantee that every flag and associated mnemonic will +be present in all further kernel releases. Things get changed, the flags may +be vanished or the reverse -- new added. + This file is only present if the CONFIG_MMU kernel configuration option is enabled.
Andrew Morton
maintainerQuoted 11 lines · On Mon, 22 Oct 2012 23:14:52 +0400 Cyrill Gorcunov <[email protected]> wrote:
Hi guys, during c/r sessions we've found that there is no way at the moment to fetch some VMA associated flags, such as
mlock()andmadvise(), thus the patches in this series intorduce new field into "smaps" output called VmFlags where all flags associated with the particular VMA is shown in two letter mnemonic.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.
Please review. Comments and complains are quite welcome!
Sigh, it's still a pretty nasty-looking interface. Better ideas are welcomed.
I joined the patches into one, massaged the changelog a bit and added a couple more paragraphs explaining why we're doing this to ourselves.
From: Cyrill Gorcunov <[email protected]>
Subject: 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(), thus the patches in this series intorduce new field into "smaps" output called VmFlags where all flags associated with the particular VMA is shown in two letter mnemonic.
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.
When we restore a VMA after checkpoint we would like to know if the area was locked or say it had mergeable attribute, but at moment the kernel does not provide such information, thus we can't figure out if we should call mlock/madvise on VMA restore.
This patch adds new VmFlags field to smaps output with vma->vm_flags encoded.
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 name:value form, to encourage userspace to be prepared for fields being added or removed in the future.
---
Documentation/filesystems/proc.txt | 38 ++++++++++++++++++++++++++- fs/proc/task_mmu.c | 32 ++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-)
fs/proc/task_mmu.c renamed from fs/proc/task_mmu.c~procfs-add-vmflags-field-in-smaps-output +32 -0
@@ -526,6 +526,36 @@ static int smaps_pte_range(pmd_t *pmd, ureturn 0 ; } +static void show_smap_vma_flags (struct seq_file *m,struct vm_area_struct *vma) +{ +/* +* Don't forget to update Documentation/ on changes. +*/ +#define __VM_FLAG (_f) (!!(vma->vm_flags & (_f))) +seq_printf (m,"VmFlags: " +"RD:%d WR:%d EX:%d SH:%d MR:%d " +"MW:%d ME:%d MS:%d GD:%d PF:%d " +"DW:%d LO:%d IO:%d SR:%d RR:%d " +"DC:%d DE:%d AC:%d NR:%d HT:%d " +"NL:%d AR:%d DD:%d MM:%d HG:%d " +"NH:%d MG:%d\n" , +__VM_FLAG (VM_READ ),__VM_FLAG (VM_WRITE ), +__VM_FLAG (VM_EXEC ),__VM_FLAG (VM_SHARED ), +__VM_FLAG (VM_MAYREAD ),__VM_FLAG (VM_MAYWRITE ), +__VM_FLAG (VM_MAYEXEC ),__VM_FLAG (VM_MAYSHARE ), +__VM_FLAG (VM_GROWSDOWN ),__VM_FLAG (VM_PFNMAP ), +__VM_FLAG (VM_DENYWRITE ),__VM_FLAG (VM_LOCKED ), +__VM_FLAG (VM_IO ),__VM_FLAG (VM_SEQ_READ ), +__VM_FLAG (VM_RAND_READ ),__VM_FLAG (VM_DONTCOPY ), +__VM_FLAG (VM_DONTEXPAND ),__VM_FLAG (VM_ACCOUNT ), +__VM_FLAG (VM_NORESERVE ),__VM_FLAG (VM_HUGETLB ), +__VM_FLAG (VM_NONLINEAR ),__VM_FLAG (VM_ARCH_1 ), +__VM_FLAG (VM_DONTDUMP ),__VM_FLAG (VM_MIXEDMAP ), +__VM_FLAG (VM_HUGEPAGE ),__VM_FLAG (VM_NOHUGEPAGE ), +__VM_FLAG (VM_MERGEABLE )); +#undef __VM_FLAG +} +static int show_smap (struct seq_file *m,void *v,int is_pid) {struct proc_maps_private *priv = m->private;
@@ -581,6 +611,8 @@ static int show_smap(struct seq_file *m,seq_printf (m,"Nonlinear: %8lu kB\n" , mss.nonlinear >>10 ); +show_smap_vma_flags (m, vma); +if (m->count < m->size)/* vma is copied successfully */ m->version = (vma !=get_gate_vma (task->mm)) ? vma->vm_start :0 ;
Documentation/filesystems/proc.txt renamed from Documentation/filesystems/proc.txt~procfs-add-vmflags-field-in-smaps-output +37 -1
@@ -142,7 +142,7 @@ Table 1-1: Process specific entries in / pagemap Page table stack Report full stack trace, enable via CONFIG_STACKTRACE smaps a extension based on maps, showing the memory consumption of - each mapping + each mapping and flags associated with it .............................................................................. For example, to get the status information of a process, all you have to do is
@@ -415,6 +415,7 @@ Swap: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 374 kB +VmFlags: RD:1 WR:0 EX:1 SH:0 MR:1 MW:1 ME:1 MS:0 GD:0 PF:0 DW:1 LO:0 IO:0 SR:0 RR:0 DC:0 DE:0 AC:0 NR:0 HT:0 NL:0 AR:0 DD:0 MM:0 HG:0 NH:0 MG:0 The first of these lines shows the same information as is displayed for the mapping in /proc/PID/maps. The remaining lines show the size of the mapping
@@ -430,6 +431,41 @@ and a page is modified, the file page is "Swap" shows how much would-be-anonymous memory is also used, but out on swap. +"VmFlags" field deserves a separate description. This member represents the kernel +flags associated with the particular virtual memory area in two letter encoded +manner. The codes are the following: + RD - readable + WR - writeable + EX - executable + SH - shared + MR - may read + MW - may write + ME - may execute + MS - may share + GD - stack segment growns down + PF - pure PFN range + DW - disabled write to the mapped file + LO - pages are locked in memory + IO - memory mapped I/O area + SR - sequential read advise provided + RR - random read advise provided + DC - do not copy area on fork + DE - do not expand area on remapping + AC - area is accountable + NR - swap space is not reserved for the area + HT - area uses huge tlb pages + NL - non-linear mapping + AR - architecture specific flag + DD - do not include area into core dump + MM - mixed map area + HG - huge page advise flag + NH - no-huge page advise flag + MG - mergable advise flag + +Note that there is no guarantee that every flag and associated mnemonic will +be present in all further kernel releases. Things get changed, the flags may +be vanished or the reverse -- new added. + This file is only present if the CONFIG_MMU kernel configuration option is enabled.
_
Quoted 9 lines · Andrew Morton
Quoted 6 lines · On Mon, 22 Oct 2012 23:14:52 +0400 Cyrill Gorcunov <[email protected]> wrote:
Hi guys, during c/r sessions we've found that there is no way at the moment to fetch some VMA associated flags, such as
mlock()andmadvise(), thus the patches in this series intorduce new field into "smaps" output called VmFlags where all flags associated with the particular VMA is shown in two letter mnemonic.
Quoted 8 lines
Quoted 5 lines
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.
Please review. Comments and complains are quite welcome!
Sigh, it's still a pretty nasty-looking interface. Better ideas are welcomed.
Well, one usable thing could be (I guess) to print only flags set. Since usually not that many flags are set on vma. This would shrink output at least.
Quoted 2 lines
I joined the patches into one, massaged the changelog a bit and added a couple more paragraphs explaining why we're doing this to ourselves.
Thanks!
Quoted 9 lines · Andrew Morton
Quoted 6 lines · On Mon, 22 Oct 2012 23:14:52 +0400 Cyrill Gorcunov <[email protected]> wrote:
Hi guys, during c/r sessions we've found that there is no way at the moment to fetch some VMA associated flags, such as
mlock()andmadvise(), thus the patches in this series intorduce new field into "smaps" output called VmFlags where all flags associated with the particular VMA is shown in two letter mnemonic.
Quoted 8 lines
Quoted 5 lines
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.
Please review. Comments and complains are quite welcome!
Sigh, it's still a pretty nasty-looking interface. Better ideas are welcomed.
Maybe just a string of two-letter short names like
VmFlags: rd wr sh sr
?
I.e. in a way flags line looks in cpuinfo file.
Quoted 2 lines
I joined the patches into one, massaged the changelog a bit and added a couple more paragraphs explaining why we're doing this to ourselves.
Quoted 19 lines · Pavel Emelyanov
Quoted 9 lines · Andrew Morton
Quoted 6 lines · On Mon, 22 Oct 2012 23:14:52 +0400 Cyrill Gorcunov <[email protected]> wrote:
Hi guys, during c/r sessions we've found that there is no way at the moment to fetch some VMA associated flags, such as
mlock()andmadvise(), thus the patches in this series intorduce new field into "smaps" output called VmFlags where all flags associated with the particular VMA is shown in two letter mnemonic.Quoted 8 lines
Quoted 5 lines
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.
Please review. Comments and complains are quite welcome!
Sigh, it's still a pretty nasty-looking interface. Better ideas are welcomed.
Quoted 7 lines
Maybe just a string of two-letter short names like
VmFlags: rd wr sh sr
?
I.e. in a way flags line looks in cpuinfo file.
Yup, I think this will be shorter and more agreeable.
Quoted 22 lines · Cyrill Gorcunov
Quoted 21 lines · Pavel Emelyanov
Quoted 9 lines · Andrew Morton
Quoted 6 lines · On Mon, 22 Oct 2012 23:14:52 +0400 Cyrill Gorcunov <[email protected]> wrote:
Hi guys, during c/r sessions we've found that there is no way at the moment to fetch some VMA associated flags, such as
mlock()andmadvise(), thus the patches in this series intorduce new field into "smaps" output called VmFlags where all flags associated with the particular VMA is shown in two letter mnemonic.Quoted 8 lines
Quoted 5 lines
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.
Please review. Comments and complains are quite welcome!
Sigh, it's still a pretty nasty-looking interface. Better ideas are welcomed.
Maybe just a string of two-letter short names like
Quoted 7 lines
Quoted 5 lines
VmFlags: rd wr sh sr
?
I.e. in a way flags line looks in cpuinfo file.
Yup, I think this will be shorter and more agreeable.
What about something like below instead?
---
From: Cyrill Gorcunov <[email protected]>
Subject: procfs: add VmFlags field in smaps output v2
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.
---
Documentation/filesystems/proc.txt | 40 ++++++++++++++++++++++++++++-- fs/proc/task_mmu.c | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +38 -2
@@ -142,7 +142,7 @@ Table 1-1: Process specific entries in / pagemap Page table stack Report full stack trace, enable via CONFIG_STACKTRACE smaps a extension based on maps, showing the memory consumption of - each mapping + each mapping and flags associated with it .............................................................................. For example, to get the status information of a process, all you have to do is
@@ -415,8 +415,9 @@ Swap: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 374 kB +VmFlags: rd ex mr mw me de -The first of these lines shows the same information as is displayed for the +the first of these lines shows the same information as is displayed for the mapping in /proc/PID/maps. The remaining lines show the size of the mapping (size), the amount of the mapping that is currently resident in RAM (RSS), the process' proportional share of this mapping (PSS), the number of clean and
@@ -430,6 +431,41 @@ and a page is modified, the file page is "Swap" shows how much would-be-anonymous memory is also used, but out on swap. +"VmFlags" field deserves a separate description. This member represents the kernel +flags associated with the particular virtual memory area in two letter encoded +manner. The codes are the following: + rd - readable + wr - writeable + ex - executable + sh - shared + mr - may read + mw - may write + me - may execute + ms - may share + gd - stack segment growns down + pf - pure PFN range + dw - disabled write to the mapped file + lo - pages are locked in memory + io - memory mapped I/O area + sr - sequential read advise provided + rr - random read advise provided + dc - do not copy area on fork + de - do not expand area on remapping + ac - area is accountable + nr - swap space is not reserved for the area + ht - area uses huge tlb pages + nl - non-linear mapping + ar - architecture specific flag + dd - do not include area into core dump + mm - mixed map area + hg - huge page advise flag + nh - no-huge page advise flag + mg - mergable advise flag + +Note that there is no guarantee that every flag and associated mnemonic will +be present in all further kernel releases. Things get changed, the flags may +be vanished or the reverse -- new added. + This file is only present if the CONFIG_MMU kernel configuration option is enabled.
fs/proc/task_mmu.c +49 -0
61 lines not on this page · raw message
Andrew Morton
maintainerQuoted 4 lines · On Tue, 23 Oct 2012 01:34:49 +0400 Cyrill Gorcunov <[email protected]> wrote:
...
+VmFlags: rd ex mr mw me de
ho hum OK, let's do that.
Quoted 36 lines
fs/proc/task_mmu.c +36
-0+static void show_smap_vma_flags (struct seq_file *m,struct vm_area_struct *vma) +{ +/* +* Don't forget to update Documentation/ on changes. +*/ + +#define __seq_show_vmflag (_f, _s) \ + do { \ + if (vma->vm_flags & (_f)) \ + seq_puts(m, _s); \ + } while (0) + +seq_puts (m,"VmFlags: " ); + +__seq_show_vmflag (VM_READ ,"rd " ); +__seq_show_vmflag (VM_WRITE ,"wr " ); +__seq_show_vmflag (VM_EXEC ,"ex " ); +__seq_show_vmflag (VM_SHARED ,"sh " ); +__seq_show_vmflag (VM_MAYREAD ,"mr " ); +__seq_show_vmflag (VM_MAYWRITE ,"mw " ); +__seq_show_vmflag (VM_MAYEXEC ,"me " ); +__seq_show_vmflag (VM_MAYSHARE ,"ms " ); +__seq_show_vmflag (VM_GROWSDOWN ,"gd " ); +__seq_show_vmflag (VM_PFNMAP ,"pf " ); +__seq_show_vmflag (VM_DENYWRITE ,"dw " ); +__seq_show_vmflag (VM_LOCKED ,"lo " ); +__seq_show_vmflag (VM_IO ,"io " ); +__seq_show_vmflag (VM_SEQ_READ ,"sr " ); +__seq_show_vmflag (VM_RAND_READ ,"rr " ); +__seq_show_vmflag (VM_DONTCOPY ,"dc " ); +__seq_show_vmflag (VM_DONTEXPAND ,"de " ); +__seq_show_vmflag (VM_ACCOUNT ,"ac " ); +__seq_show_vmflag (VM_NORESERVE ,"nr " ); +__seq_show_vmflag (VM_HUGETLB ,"ht " ); +__seq_show_vmflag (VM_NONLINEAR ,"nl " ); +__seq_show_vmflag (VM_ARCH_1 ,"ar " );
fs/proc/task_mmu.c static int smaps_pte_range(pmd_t *pmd, u · line 528
Quoted 10 lines
fs/proc/task_mmu.c +10
-0+__seq_show_vmflag (VM_DONTDUMP ,"dd " ); +__seq_show_vmflag (VM_MIXEDMAP ,"mm " ); +__seq_show_vmflag (VM_HUGEPAGE ,"hg " ); +__seq_show_vmflag (VM_NOHUGEPAGE ,"nh " ); +__seq_show_vmflag (VM_MERGEABLE ,"mg " ); + +seq_putc (m,'\n' ); + +#undef __seq_show_vmflag +}
This code would be much denser if we did the old
static const char foo[] = "rdwrexshmrmw...";
unsigned i;
for (i = 0; i < BITS_PER_LONG; i++) {
if (flags & (1 << i))
seq_printf("%c%c ", foo[i * 2], foo[i * 2 + 1]);
}trick. But then we'd have to remember to fix foo[] each time we alter the flags, so maybe let's not do that.
On Mon, Oct 22, 2012 at 02:51:58PM -0700, Andrew Morton wrote:
...
Quoted 10 lines
Quoted 10 lines
fs/proc/task_mmu.c +10
-0+__seq_show_vmflag (VM_DONTEXPAND ,"de " ); +__seq_show_vmflag (VM_ACCOUNT ,"ac " ); +__seq_show_vmflag (VM_NORESERVE ,"nr " ); +__seq_show_vmflag (VM_HUGETLB ,"ht " ); +__seq_show_vmflag (VM_NONLINEAR ,"nl " ); +__seq_show_vmflag (VM_ARCH_1 ,"ar " ); +__seq_show_vmflag (VM_DONTDUMP ,"dd " ); +__seq_show_vmflag (VM_MIXEDMAP ,"mm " ); +__seq_show_vmflag (VM_HUGEPAGE ,"hg " ); +__seq_show_vmflag (VM_NOHUGEPAGE ,"nh " );
...
Quoted 11 lines
This code would be much denser if we did the old
static const char foo[] = "rdwrexshmrmw..."; unsigned i; for (i = 0; i < BITS_PER_LONG; i++) { if (flags & (1 << i)) seq_printf("%c%c ", foo[i * 2], foo[i * 2 + 1]); }
Quoted 2 lines
trick. But then we'd have to remember to fix foo[] each time we alter the flags, so maybe let's not do that.
Yup, but not only that, this kind of trick hides associativity between VM_ constant and mnemonic, so on changes one would have to figure out which position some flag has in this foo[] array, so I vote for not use it :-)
Andrew Morton
maintainerQuoted 24 lines · On Tue, 23 Oct 2012 10:13:41 +0400 Cyrill Gorcunov <[email protected]> wrote:
On Mon, Oct 22, 2012 at 02:51:58PM -0700, Andrew Morton wrote:
...Quoted 10 lines
Quoted 10 lines
fs/proc/task_mmu.c +10
-0+__seq_show_vmflag (VM_DONTEXPAND ,"de " ); +__seq_show_vmflag (VM_ACCOUNT ,"ac " ); +__seq_show_vmflag (VM_NORESERVE ,"nr " ); +__seq_show_vmflag (VM_HUGETLB ,"ht " ); +__seq_show_vmflag (VM_NONLINEAR ,"nl " ); +__seq_show_vmflag (VM_ARCH_1 ,"ar " ); +__seq_show_vmflag (VM_DONTDUMP ,"dd " ); +__seq_show_vmflag (VM_MIXEDMAP ,"mm " ); +__seq_show_vmflag (VM_HUGEPAGE ,"hg " ); +__seq_show_vmflag (VM_NOHUGEPAGE ,"nh " );...
Quoted 11 lines
This code would be much denser if we did the old
static const char foo[] = "rdwrexshmrmw..."; unsigned i; for (i = 0; i < BITS_PER_LONG; i++) { if (flags & (1 << i)) seq_printf("%c%c ", foo[i * 2], foo[i * 2 + 1]); }
Quoted 7 lines
Quoted 2 lines
trick. But then we'd have to remember to fix foo[] each time we alter the flags, so maybe let's not do that.
Yup, but not only that, this kind of trick hides associativity between
VM_constant and mnemonic, so on changes one would have to figure out which position some flag has in this foo[] array, so I vote for not use it :-)
Well you could do
struct {
char x[2];
} y[] = {
[CLOG2(VM_DONTEXPAND)] = { 'd', 'e' },
[CLOG2(VM_ACCOUNT)] = { 'a', 'c' },
[CLOG2(VM_NORESERVE)] = { 'n', 'r' },
}; ...
for (i = 0; i < BITS_PER_LONG; i++) {
if (flags & (1 << i))
seq_printf("%c%c ", y[i][0], y[i][1]);
}where CLOG2() is extracted from the guts of ilog2().
I'll stop now :)
On Mon, Oct 22, 2012 at 11:30:25PM -0700, Andrew Morton wrote:
...
Quoted 22 lines
Quoted 4 lines
Yup, but not only that, this kind of trick hides associativity between
VM_constant and mnemonic, so on changes one would have to figure out which position some flag has in this foo[] array, so I vote for not use it :-)Well you could do
struct { char x[2]; } y[] = { [CLOG2(VM_DONTEXPAND)] = { 'd', 'e' }, [CLOG2(VM_ACCOUNT)] = { 'a', 'c' }, [CLOG2(VM_NORESERVE)] = { 'n', 'r' }, };... for (i = 0; i < BITS_PER_LONG; i++) { if (flags & (1 << i)) seq_printf("%c%c ", y[i][0], y[i][1]); }
Quoted 3 lines
where
CLOG2()is extracted from the guts ofilog2().I'll stop now :)
Yup, this one will be a wy better. Letme try it out :)
Quoted 24 lines · Cyrill Gorcunov
On Mon, Oct 22, 2012 at 11:30:25PM -0700, Andrew Morton wrote:
...Quoted 22 lines
Quoted 4 lines
Yup, but not only that, this kind of trick hides associativity between
VM_constant and mnemonic, so on changes one would have to figure out which position some flag has in this foo[] array, so I vote for not use it :-)Well you could do
struct { char x[2]; } y[] = { [CLOG2(VM_DONTEXPAND)] = { 'd', 'e' }, [CLOG2(VM_ACCOUNT)] = { 'a', 'c' }, [CLOG2(VM_NORESERVE)] = { 'n', 'r' }, };... for (i = 0; i < BITS_PER_LONG; i++) { if (flags & (1 << i)) seq_printf("%c%c ", y[i][0], y[i][1]); }
Quoted 5 lines
Quoted 3 lines
where
CLOG2()is extracted from the guts ofilog2().I'll stop now :)
Yup, this one will be a wy better. Letme try it out :)
ilog2 works well enough here as well.
---
From: Cyrill Gorcunov <[email protected]>
Subject: procfs: add VmFlags field in smaps output v3
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.
---
Documentation/filesystems/proc.txt | 40 +++++++++++++++++++++++++++- fs/proc/task_mmu.c | 52 +++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +38 -2
@@ -142,7 +142,7 @@ Table 1-1: Process specific entries in / pagemap Page table stack Report full stack trace, enable via CONFIG_STACKTRACE smaps a extension based on maps, showing the memory consumption of - each mapping + each mapping and flags associated with it .............................................................................. For example, to get the status information of a process, all you have to do is
@@ -415,8 +415,9 @@ Swap: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 374 kB +VmFlags: rd ex mr mw me de -The first of these lines shows the same information as is displayed for the +the first of these lines shows the same information as is displayed for the mapping in /proc/PID/maps. The remaining lines show the size of the mapping (size), the amount of the mapping that is currently resident in RAM (RSS), the process' proportional share of this mapping (PSS), the number of clean and
@@ -430,6 +431,41 @@ and a page is modified, the file page is "Swap" shows how much would-be-anonymous memory is also used, but out on swap. +"VmFlags" field deserves a separate description. This member represents the kernel +flags associated with the particular virtual memory area in two letter encoded +manner. The codes are the following: + rd - readable + wr - writeable + ex - executable + sh - shared + mr - may read + mw - may write + me - may execute + ms - may share + gd - stack segment growns down + pf - pure PFN range + dw - disabled write to the mapped file + lo - pages are locked in memory + io - memory mapped I/O area + sr - sequential read advise provided + rr - random read advise provided + dc - do not copy area on fork + de - do not expand area on remapping + ac - area is accountable + nr - swap space is not reserved for the area + ht - area uses huge tlb pages + nl - non-linear mapping + ar - architecture specific flag + dd - do not include area into core dump + mm - mixed map area + hg - huge page advise flag + nh - no-huge page advise flag + mg - mergable advise flag + +Note that there is no guarantee that every flag and associated mnemonic will +be present in all further kernel releases. Things get changed, the flags may +be vanished or the reverse -- new added. + This file is only present if the CONFIG_MMU kernel configuration option is enabled.
fs/proc/task_mmu.c +52 -0
64 lines not on this page · raw message
Andrew Morton
maintainerQuoted 51 lines · On Tue, 23 Oct 2012 11:15:49 +0400 Cyrill Gorcunov <[email protected]> wrote:
Quoted 24 lines · Cyrill Gorcunov
On Mon, Oct 22, 2012 at 11:30:25PM -0700, Andrew Morton wrote:
...Quoted 22 lines
Quoted 4 lines
Yup, but not only that, this kind of trick hides associativity between
VM_constant and mnemonic, so on changes one would have to figure out which position some flag has in this foo[] array, so I vote for not use it :-)Well you could do
struct { char x[2]; } y[] = { [CLOG2(VM_DONTEXPAND)] = { 'd', 'e' }, [CLOG2(VM_ACCOUNT)] = { 'a', 'c' }, [CLOG2(VM_NORESERVE)] = { 'n', 'r' }, };... for (i = 0; i < BITS_PER_LONG; i++) { if (flags & (1 << i)) seq_printf("%c%c ", y[i][0], y[i][1]); }Quoted 5 lines
Quoted 3 lines
where
CLOG2()is extracted from the guts ofilog2().I'll stop now :)
Yup, this one will be a wy better. Letme try it out :)
ilog2 works well enough here as well.
---
From: Cyrill Gorcunov <[email protected]>
Subject: procfs: add VmFlags field in smaps output v3During c/r sessions we've found that there is no way at the moment to fetch some VMA associated flags, such as
mlock()andmadvise().This leads us to a problem -- we don't know if we should call for
mlock()and/ormadvise()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. ]
Quoted 7 lines
This feature is made available on
CONFIG_CHECKPOINT_RESTORE=nkernels, 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.
Wow. This version generates 1k less kernel bloat than v2! Gee, and I only sent that email as a late-night joke ;)
fs/proc/task_mmu.o with neither patch:
text data bss dec hex filename
14849 112 5312 20273 4f31 fs/proc/task_mmu.o
fs/proc/task_mmu.o with the v2 patch:
16074 112 5776 21962 55ca fs/proc/task_mmu.o
fs/proc/task_mmu.o with the v3 patch:
15446 112 5368 20926 51be fs/proc/task_mmu.o
fs/proc/task_mmu.o with the v3 patch and the below fix:
15123 112 5352 20587 506b fs/proc/task_mmu.o
So the delta has gone from 1700 bytes down to 300. Seems that it pays to be anal about these things ;)
Don't forget the `static'! Without it, the compiler will need to construct the array as a temporary on the stack each time the function is called - it's just terrible. (There's no reason why the compiler can't insert the static for us as an optimisation, and I think later gcc's may have got smarter about this).
Was there a reason why you added the ".l = " to the initialiser? My gcc is happy without it.
Also... what happens if there's an unrecognised bit set in `flags'? Memory corruption or code skew could cause this. We emit a couple of NULs into the procfs output, which I guess is an OK response to such a condition.
From: Andrew Morton <[email protected]>
Subject: procfs-add-vmflags-field-in-smaps-output-v3-fix
make mnemonics[] static, remove unneeded init code, tidy whitespace
---
fs/proc/task_mmu.c | 58 ++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 30 deletions(-)
diff -puN Documentation/filesystems/proc.txt~procfs-add-vmflags-field-in-smaps-output-v3-fix Documentation/filesystems/proc.txt
fs/proc/task_mmu.c renamed from fs/proc/task_mmu.c~procfs-add-vmflags-field-in-smaps-output-v3-fix +28 -30
@@ -531,39 +531,37 @@ static void show_smap_vma_flags(struct s/* * Don't forget to update Documentation/ on changes. */ - -const struct { +static const struct {const char l[2 ]; } mnemonics[BITS_PER_LONG ] = { - [ilog2 (VM_READ )] = { .l = {'r' ,'d' } }, - [ilog2 (VM_WRITE )] = { .l = {'w' ,'r' } }, - [ilog2 (VM_EXEC )] = { .l = {'e' ,'x' } }, - [ilog2 (VM_SHARED )] = { .l = {'s' ,'h' } }, - [ilog2 (VM_MAYREAD )] = { .l = {'m' ,'r' } }, - [ilog2 (VM_MAYWRITE )] = { .l = {'m' ,'w' } }, - [ilog2 (VM_MAYEXEC )] = { .l = {'m' ,'e' } }, - [ilog2 (VM_MAYSHARE )] = { .l = {'m' ,'s' } }, - [ilog2 (VM_GROWSDOWN )] = { .l = {'g' ,'d' } }, - [ilog2 (VM_PFNMAP )] = { .l = {'p' ,'f' } }, - [ilog2 (VM_DENYWRITE )] = { .l = {'d' ,'w' } }, - [ilog2 (VM_LOCKED )] = { .l = {'l' ,'o' } }, - [ilog2 (VM_IO )] = { .l = {'i' ,'o' } }, - [ilog2 (VM_SEQ_READ )] = { .l = {'s' ,'r' } }, - [ilog2 (VM_RAND_READ )] = { .l = {'r' ,'r' } }, - [ilog2 (VM_DONTCOPY )] = { .l = {'d' ,'c' } }, - [ilog2 (VM_DONTEXPAND )] = { .l = {'d' ,'e' } }, - [ilog2 (VM_ACCOUNT )] = { .l = {'a' ,'c' } }, - [ilog2 (VM_NORESERVE )] = { .l = {'n' ,'r' } }, - [ilog2 (VM_HUGETLB )] = { .l = {'h' ,'t' } }, - [ilog2 (VM_NONLINEAR )] = { .l = {'n' ,'l' } }, - [ilog2 (VM_ARCH_1 )] = { .l = {'a' ,'r' } }, - [ilog2 (VM_DONTDUMP )] = { .l = {'d' ,'d' } }, - [ilog2 (VM_MIXEDMAP )] = { .l = {'m' ,'m' } }, - [ilog2 (VM_HUGEPAGE )] = { .l = {'h' ,'g' } }, - [ilog2 (VM_NOHUGEPAGE )] = { .l = {'n' ,'h' } }, - [ilog2 (VM_MERGEABLE )] = { .l = {'m' ,'g' } }, + [ilog2 (VM_READ )] = { {'r' ,'d' } }, + [ilog2 (VM_WRITE )] = { {'w' ,'r' } }, + [ilog2 (VM_EXEC )] = { {'e' ,'x' } }, + [ilog2 (VM_SHARED )] = { {'s' ,'h' } }, + [ilog2 (VM_MAYREAD )] = { {'m' ,'r' } }, + [ilog2 (VM_MAYWRITE )] = { {'m' ,'w' } }, + [ilog2 (VM_MAYEXEC )] = { {'m' ,'e' } }, + [ilog2 (VM_MAYSHARE )] = { {'m' ,'s' } }, + [ilog2 (VM_GROWSDOWN )] = { {'g' ,'d' } }, + [ilog2 (VM_PFNMAP )] = { {'p' ,'f' } }, + [ilog2 (VM_DENYWRITE )] = { {'d' ,'w' } }, + [ilog2 (VM_LOCKED )] = { {'l' ,'o' } }, + [ilog2 (VM_IO )] = { {'i' ,'o' } }, + [ilog2 (VM_SEQ_READ )] = { {'s' ,'r' } }, + [ilog2 (VM_RAND_READ )] = { {'r' ,'r' } }, + [ilog2 (VM_DONTCOPY )] = { {'d' ,'c' } }, + [ilog2 (VM_DONTEXPAND )] = { {'d' ,'e' } }, + [ilog2 (VM_ACCOUNT )] = { {'a' ,'c' } }, + [ilog2 (VM_NORESERVE )] = { {'n' ,'r' } }, + [ilog2 (VM_HUGETLB )] = { {'h' ,'t' } }, + [ilog2 (VM_NONLINEAR )] = { {'n' ,'l' } }, + [ilog2 (VM_ARCH_1 )] = { {'a' ,'r' } }, + [ilog2 (VM_DONTDUMP )] = { {'d' ,'d' } }, + [ilog2 (VM_MIXEDMAP )] = { {'m' ,'m' } }, + [ilog2 (VM_HUGEPAGE )] = { {'h' ,'g' } }, + [ilog2 (VM_NOHUGEPAGE )] = { {'n' ,'h' } }, + [ilog2 (VM_MERGEABLE )] = { {'m' ,'g' } }, }; -size_t i;seq_puts (m,"VmFlags: " );
_
Quoted 8 lines · Andrew Morton
Quoted 5 lines
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.
Wow. This version generates 1k less kernel bloat than v2! Gee, and I only sent that email as a late-night joke ;)
Cool!
Quoted 7 lines
fs/proc/task_mmu.owith neither patch:
text data bss dec hex filename
14849 112 5312 20273 4f31fs/proc/task_mmu.o
fs/proc/task_mmu.owith the v2 patch:
16074 112 5776 21962 55cafs/proc/task_mmu.o
Quoted 8 lines
fs/proc/task_mmu.owith the v3 patch:
15446 112 5368 20926 51befs/proc/task_mmu.o
fs/proc/task_mmu.owith the v3 patch and the below fix:
15123 112 5352 20587 506bfs/proc/task_mmu.oSo the delta has gone from 1700 bytes down to 300. Seems that it pays to be anal about these things ;)
LOL ;-)
Quoted 1 line
Don't forget the `static'! Without it, the compiler will need to
Yeah, for some reason missed it, thanks!
Quoted 7 lines
construct the array as a temporary on the stack each time the function is called - it's just terrible. (There's no reason why the compiler can't insert the static for us as an optimisation, and I think later gcc's may have got smarter about this).
Was there a reason why you added the ".l = " to the initialiser? My gcc is happy without it.
Mine either, just as habbit I would say, thanks.
Quoted 4 lines
Also... what happens if there's an unrecognised bit set in `flags'? Memory corruption or code skew could cause this. We emit a couple of NULs into the procfs output, which I guess is an OK response to such a condition.
That's indeed will produce some nil character on the screen. I guess we need some designited init here, say
[0 ... (BITS_PER_LONG-1)] = { {'-', '-'} },
...
[ilog2(VM_READ)] = { {'r', 'd'} },
...
and so on, i'll update on topQuoted 5 lines
From: Andrew Morton <[email protected]>
Subject: procfs-add-vmflags-field-in-smaps-output-v3-fixmake mnemonics[] static, remove unneeded init code, tidy whitespace
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines
Also... what happens if there's an unrecognised bit set in `flags'? Memory corruption or code skew could cause this. We emit a couple of NULs into the procfs output, which I guess is an OK response to such a condition.
Quoted 9 lines
That's indeed will produce some nil character on the screen. I guess we need some designited init here, say
[0 ... (BITS_PER_LONG-1)] = { {'-', '-'} }, ... [ilog2(VM_READ)] = { {'r', 'd'} }, ... and so on, i'll update on top
Andrew, could you please fold it on top of your procfs-add-vmflags-field-in-smaps-output-v3-fix ?
(If this is inconvenient -- just give me a word and I'll
squash everything in one new patch instead).
---
From: Cyrill Gorcunov <[email protected]>
Subject: procfs-add-vmflags-field-in-smaps-output-v3-fix-on-top
Use designated init to assign "??" mnemonic on unknown flags.
--- fs/proc/task_mmu.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/proc/task_mmu.c +5 -0
@@ -488,6 +488,11 @@ static void show_smap_vma_flags(struct sstatic const struct {const char l[2 ]; } mnemonics[BITS_PER_LONG ] = { +/* +* In case if we meet a flag we don't know about. +*/ + [0 ... (BITS_PER_LONG -1 )] = { {'?' ,'?' } }, + [ilog2 (VM_READ )] = { {'r' ,'d' } }, [ilog2 (VM_WRITE )] = { {'w' ,'r' } }, [ilog2 (VM_EXEC )] = { {'e' ,'x' } },
Quoted 1 line · Cyrill Gorcunov
[ilog2(VM_WRITE)] = { {'w', 'r'} },since we're being awfully positive about crazy late night ideas, how about something like:
#define MNEM(_VM, _mn) [ilog2(_VM)] = {(const char [2]){_mn}}
MNEM(VM_WRITE, "wr"),
Quoted 10 lines · On Wed, 24 Oct 2012 00:32:54 +0200 Peter Zijlstra <[email protected]>…
Quoted 1 line · Cyrill Gorcunov
[ilog2(VM_WRITE)] = { {'w', 'r'} },since we're being awfully positive about crazy late night ideas, how about something like:
#define
MNEM(_VM, _mn)[ilog2(_VM)] = {(const char [2]){_mn}}MNEM(VM_WRITE, "wr"),
The C standard and gcc allow you to initialise the 2 character array with a (>=2 character) string literal with no casting, so
#define MNEM(_VM, _mn) [ilog2(_VM)] = {_mn}
should work.
[ and the the earlier version,
[ilog2(VM_READ)] = { "rd" },
etc, does work. ]
Signature · 2 lines
Cheers, Stephen Rothwell [email protected]
Quoted 9 lines · Peter Zijlstra
Quoted 1 line · Cyrill Gorcunov
[ilog2(VM_WRITE)] = { {'w', 'r'} },since we're being awfully positive about crazy late night ideas, how about something like:
#define
MNEM(_VM, _mn)[ilog2(_VM)] = {(const char [2]){_mn}}MNEM(VM_WRITE, "wr"),
I see no reason why should not we :) I'll update.