Commit 9f61de87 authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

proc_parse: make smaps parsing helpers globally available

The is_vma_range_fmt and parse_vmflags will be required for detection of
availability of PR_SET_THP_DISABLE prctl
Acked-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent c8717da4
...@@ -105,4 +105,7 @@ extern int parse_threads(int pid, struct pid **_t, int *_n); ...@@ -105,4 +105,7 @@ extern int parse_threads(int pid, struct pid **_t, int *_n);
int parse_children(pid_t pid, pid_t **_c, int *_n); int parse_children(pid_t pid, pid_t **_c, int *_n);
extern bool is_vma_range_fmt(char *line);
extern void parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf);
#endif /* __CR_PROC_PARSE_H__ */ #endif /* __CR_PROC_PARSE_H__ */
...@@ -77,7 +77,7 @@ static char *buf = __buf.buf; ...@@ -77,7 +77,7 @@ static char *buf = __buf.buf;
#define AIO_FNAME "/[aio]" #define AIO_FNAME "/[aio]"
/* check the @line starts with "%lx-%lx" format */ /* check the @line starts with "%lx-%lx" format */
static bool is_vma_range_fmt(char *line) static bool __is_vma_range_fmt(char *line)
{ {
#define ____is_vma_addr_char(__c) \ #define ____is_vma_addr_char(__c) \
(((__c) <= '9' && (__c) >= '0') || \ (((__c) <= '9' && (__c) >= '0') || \
...@@ -99,55 +99,54 @@ static bool is_vma_range_fmt(char *line) ...@@ -99,55 +99,54 @@ static bool is_vma_range_fmt(char *line)
#undef ____is_vma_addr_char #undef ____is_vma_addr_char
} }
static int parse_vmflags(char *buf, struct vma_area *vma_area) bool is_vma_range_fmt(char *line)
{
return __is_vma_range_fmt(line);
}
static void __parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf)
{ {
char *tok; char *tok;
if (!buf[0]) if (!buf[0])
return 0; return;
tok = strtok(buf, " \n"); tok = strtok(buf, " \n");
if (!tok) if (!tok)
return 0; return;
#define _vmflag_match(_t, _s) (_t[0] == _s[0] && _t[1] == _s[1]) #define _vmflag_match(_t, _s) (_t[0] == _s[0] && _t[1] == _s[1])
do { do {
/* mmap() block */ /* mmap() block */
if (_vmflag_match(tok, "gd")) if (_vmflag_match(tok, "gd"))
vma_area->e->flags |= MAP_GROWSDOWN; *flags |= MAP_GROWSDOWN;
else if (_vmflag_match(tok, "lo")) else if (_vmflag_match(tok, "lo"))
vma_area->e->flags |= MAP_LOCKED; *flags |= MAP_LOCKED;
else if (_vmflag_match(tok, "nr")) else if (_vmflag_match(tok, "nr"))
vma_area->e->flags |= MAP_NORESERVE; *flags |= MAP_NORESERVE;
else if (_vmflag_match(tok, "ht")) else if (_vmflag_match(tok, "ht"))
vma_area->e->flags |= MAP_HUGETLB; *flags |= MAP_HUGETLB;
/* madvise() block */ /* madvise() block */
if (_vmflag_match(tok, "sr")) if (_vmflag_match(tok, "sr"))
vma_area->e->madv |= (1ul << MADV_SEQUENTIAL); *madv |= (1ul << MADV_SEQUENTIAL);
else if (_vmflag_match(tok, "rr")) else if (_vmflag_match(tok, "rr"))
vma_area->e->madv |= (1ul << MADV_RANDOM); *madv |= (1ul << MADV_RANDOM);
else if (_vmflag_match(tok, "dc")) else if (_vmflag_match(tok, "dc"))
vma_area->e->madv |= (1ul << MADV_DONTFORK); *madv |= (1ul << MADV_DONTFORK);
else if (_vmflag_match(tok, "dd")) else if (_vmflag_match(tok, "dd"))
vma_area->e->madv |= (1ul << MADV_DONTDUMP); *madv |= (1ul << MADV_DONTDUMP);
else if (_vmflag_match(tok, "mg")) else if (_vmflag_match(tok, "mg"))
vma_area->e->madv |= (1ul << MADV_MERGEABLE); *madv |= (1ul << MADV_MERGEABLE);
else if (_vmflag_match(tok, "hg")) else if (_vmflag_match(tok, "hg"))
vma_area->e->madv |= (1ul << MADV_HUGEPAGE); *madv |= (1ul << MADV_HUGEPAGE);
else if (_vmflag_match(tok, "nh")) else if (_vmflag_match(tok, "nh"))
vma_area->e->madv |= (1ul << MADV_NOHUGEPAGE); *madv |= (1ul << MADV_NOHUGEPAGE);
/* vmsplice doesn't work for VM_IO and VM_PFNMAP mappings. */ /* vmsplice doesn't work for VM_IO and VM_PFNMAP mappings. */
if (_vmflag_match(tok, "io") || _vmflag_match(tok, "pf")) { if (_vmflag_match(tok, "io") || _vmflag_match(tok, "pf"))
/* *io_pf = 1;
* VVAR area mapped by the kernel as
* VM_IO | VM_PFNMAP| VM_DONTEXPAND | VM_DONTDUMP
*/
if (!vma_area_is(vma_area, VMA_AREA_VVAR))
vma_area->e->status |= VMA_UNSUPP;
}
/* /*
* Anything else is just ignored. * Anything else is just ignored.
...@@ -155,11 +154,29 @@ static int parse_vmflags(char *buf, struct vma_area *vma_area) ...@@ -155,11 +154,29 @@ static int parse_vmflags(char *buf, struct vma_area *vma_area)
} while ((tok = strtok(NULL, " \n"))); } while ((tok = strtok(NULL, " \n")));
#undef _vmflag_match #undef _vmflag_match
}
void parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf)
{
__parse_vmflags(buf, flags, madv, io_pf);
}
static void parse_vma_vmflags(char *buf, struct vma_area *vma_area)
{
int io_pf = 0;
__parse_vmflags(buf, &vma_area->e->flags, &vma_area->e->madv, &io_pf);
/*
* vmsplice doesn't work for VM_IO and VM_PFNMAP mappings, the
* only exception is VVAR area that mapped by the kernel as
* VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP
*/
if (io_pf && !vma_area_is(vma_area, VMA_AREA_VVAR))
vma_area->e->status |= VMA_UNSUPP;
if (vma_area->e->madv) if (vma_area->e->madv)
vma_area->e->has_madv = true; vma_area->e->has_madv = true;
return 0;
} }
static inline int is_anon_shmem_map(dev_t dev) static inline int is_anon_shmem_map(dev_t dev)
...@@ -722,7 +739,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, ...@@ -722,7 +739,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list,
goto err; goto err;
eof = (str == NULL); eof = (str == NULL);
if (!eof && !is_vma_range_fmt(str)) { if (!eof && !__is_vma_range_fmt(str)) {
if (!strncmp(str, "Nonlinear", 9)) { if (!strncmp(str, "Nonlinear", 9)) {
BUG_ON(!vma_area); BUG_ON(!vma_area);
pr_err("Nonlinear mapping found %016"PRIx64"-%016"PRIx64"\n", pr_err("Nonlinear mapping found %016"PRIx64"-%016"PRIx64"\n",
...@@ -735,8 +752,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, ...@@ -735,8 +752,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list,
goto err; goto err;
} else if (!strncmp(str, "VmFlags: ", 9)) { } else if (!strncmp(str, "VmFlags: ", 9)) {
BUG_ON(!vma_area); BUG_ON(!vma_area);
if (parse_vmflags(&str[9], vma_area)) parse_vma_vmflags(&str[9], vma_area);
goto err;
continue; continue;
} else } else
continue; continue;
...@@ -2491,7 +2507,7 @@ int collect_controllers(struct list_head *cgroups, unsigned int *n_cgroups) ...@@ -2491,7 +2507,7 @@ int collect_controllers(struct list_head *cgroups, unsigned int *n_cgroups)
nc->controllers[nc->n_controllers-1] = n; nc->controllers[nc->n_controllers-1] = n;
} }
skip: skip:
if (!off) if (!off)
break; break;
...@@ -2598,4 +2614,3 @@ err: ...@@ -2598,4 +2614,3 @@ err:
xfree(ch); xfree(ch);
return -1; return -1;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment