The dump_mem_map() function displays basic data about each entry in
the
mem_map[] array, or if an address is specified, just the mem_map[] entry
for that address. This patch introduces the -m option to be used with
'kmem -p' exclusively. When used with -p, a comma-separated list of one or
more struct page members may be specified to generate a custom, formatted
display. For example:
crash> kmem -p -m mapping,index,_mapcount.counter,_count.counter
ffffea0000000000 0x0 0 0 0
ffffea0000000040 0x0 0 -1 1
ffffea0000000080 0x0 0 -1 1
ffffea00000000c0 0x0 0 -1 1
ffffea0000000100 0x0 0 -1 1
ffffea0000000140 0x0 0 -1 1
ffffea0000000180 0x0 0 -1 1
ffffea00000001c0 0x0 0 -1 1
ffffea0000000200 0x0 0 -1 1
ffffea0000000240 0x0 0 -1 1
...
Signed-off-by: Aaron Tomlin <atomlin(a)redhat.com>
Hi Aaron,
I've been waiting patiently for this patch to arrive, and it is
a good start, but this may take a couple go-arounds.
First off, it's almost impossible for me to effectively review this
patch because it does all the work inside of the already utterly-confusing
dump_mem_map_sparsemem() and dump_mem_map() functions. I'll take the blame
for their current condition, because over the years I have patched and
re-patched, and taken in other folk's patches, many times -- all to
the detriment of understandability/maintainability. So please
understand that I am reviewing my own code as much as yours.
So here are my initial suggestions.
The -m optarg string received in cmd_kmem() should immediately be error-checked
and then handled in one place instead of duplicating the functionality in both
dump_mem_map_SPARSEMEM() and dump_mem_map() functions.
And the same thing goes w/respect to the duplication of effort when making
the calls to fill_struct_member_data().
When you posted your first patch a few weeks ago, I had tinkered with a proof-of-concept
of this option, which led to my creation of the fill_struct_member_data(). Here's
what
I did:
First, in cmd_kmem(), the option string was immediately vetted like so:
case 'm':
collect_page_member_data(optarg);
break;
Second, in collect_page_member_data(), I created an array of struct_member_data
structures:
static void
collect_page_member_data(char *optlist)
{
int i;
int members;
char *opt_string;
char *memberlist[MAXARGS];
struct struct_member_data *page_member_cache, *pmd;
if ((count_chars(optlist, ',')+1) > MAXARGS)
error(FATAL, "too many members in comma-separated list\n");
opt_string = STRDUPBUF(optlist);
replace_string(opt_string, ",", ' ');
if (!(members = parse_line(opt_string, memberlist)))
error(FATAL, "invalid page struct member list format: %s\n",
optlist);
page_member_cache = (struct struct_member_data *)
GETBUF(sizeof(struct struct_member_data) * members);
for (i = 0, pmd = page_member_cache; i < members; i++, pmd++) {
pmd->structure = "page";
pmd->member = memberlist[i];
if (!fill_struct_member_data(pmd))
error(FATAL, "invalid %s struct member: %s\n",
pmd->structure, pmd->member);
if (CRASHDEBUG(1)) {
fprintf(fp, " structure: %s\n", pmd->structure);
fprintf(fp, " member: %s\n", pmd->member);
fprintf(fp, " type: %ld\n", pmd->type);
fprintf(fp, " unsigned_type: %ld\n", pmd->unsigned_type);
fprintf(fp, " length: %ld\n", pmd->length);
fprintf(fp, " offset: %ld\n", pmd->offset);
fprintf(fp, " bitpos: %ld\n", pmd->bitpos);
fprintf(fp, " bitsize: %ld\n", pmd->bitsize);
}
}
}
However, that's as far as I took it. What would also need to be done is for
cmd_kmem()
to pass the meminfo pointer in to collect_page_member_data(), and have it store both
the "members" count and the "page_member_cache" pointer into new
members in the meminfo
structure.
Then, like your meminfo->include, dump_mem_map_SPARSEMEM() and dump_mem_map() can key
on the existence of a non-zero meminfo "members" counter to perform the new
functionality.
But the biggest change I'd like you to make it to move the new display functionality
completely out of dump_mem_map_SPARSEMEM() and dump_mem_map(), and put it in a
new common function. Let's not make those two functions any uglier than they
already are.
So taking dump_mem_map_SPARSEMEM() for example, it should simply require the addition
of a few lines to each function, i.e., something like this:
for (section_nr = 0; section_nr < nr_mem_sections ; section_nr++) {
... [ cut ] ...
for (i = 0; i < section_size;
i++, pp += SIZE(page), phys += PAGESIZE()) {
... [ cut ] ...
if (!done && (pg_spec || phys_spec))
continue;
+ if (mi->members_count) {
+ bufferindex += do_your_function(pp, pcache, mi,
outputbuffer+bufferindex);
+ goto display_members;
+ }
... [ cut ] ...
+ display_members:
if (bufferindex > buffersize) {
fprintf(fp, "%s", outputbuffer);
bufferindex = 0;
}
You would still need to prevent the old header from being displayed similar to what
you have done in your patch, but something like the above should be possible.
Then I could just review the actual functionality of your patch. There are a few
issues there I'd like to discuss, but how about we get my initial bitch-fest out
of the way first.
Agreed?
Dave
---
help.c | 19 +-
memory.c | 1074
++++++++++++++++++++++++++++++++++++--------------------------
2 files changed, 649 insertions(+), 444 deletions(-)
diff --git a/help.c b/help.c
index b2f4d21..76b640a 100644
--- a/help.c
+++ b/help.c
@@ -5530,7 +5530,7 @@ char *help_kmem[] = {
"kmem",
"kernel memory",
"[-f|-F|-p|-c|-C|-i|-s|-S|-v|-V|-n|-z|-o|-h] [slab] [[-P] address]\n"
-" [-g [flags]] [-I slab[,slab]]",
+" [-g [flags]] [-I slab[,slab]] [-m member[,member]]",
" This command displays information about the use of kernel memory.\n",
" -f displays the contents of the system free memory headers.",
" also verifies that the page count equals nr_free_pages.",
@@ -5565,6 +5565,9 @@ char *help_kmem[] = {
" all slab cache names and addresses are listed.",
" -I slab when used with -s or -S, one or more slab cache names in a",
" comma-separated list may be specified as slab caches to
ignore.",
+" -m member when used with -p, a comma-separated list of one or more",
+" struct page members may be specified to generate a custom",
+" formatted display.",
" -P declares that the following address argument is a physical
address.",
" address when used without any flag, the address can be a kernel
virtual,",
" or physical address; a search is made through the symbol
table,",
@@ -5717,6 +5720,20 @@ char *help_kmem[] = {
" f5c51440 22000 0 0 1 80 slab",
" ...",
" ",
+" Dump the mem_map[] array but select desired fields:\n",
+" %s> kmem -p -m mapping,index,_mapcount.counter",
+" ffffea0000000000 0x0 0 0",
+" ffffea0000000040 0x0 0 -1",
+" ffffea0000000080 0x0 0 -1",
+" ffffea00000000c0 0x0 0 -1",
+" ffffea0000000100 0x0 0 -1",
+" ffffea0000000140 0x0 0 -1",
+" ffffea0000000180 0x0 0 -1",
+" ffffea00000001c0 0x0 0 -1",
+" ffffea0000000200 0x0 0 -1",
+" ffffea0000000240 0x0 0 -1",
+" ...",
+" ",
" Use the commands above with a page pointer or a physical address
argument:\n",
" %s> kmem -f c40425b0",
" NODE ",
diff --git a/memory.c b/memory.c
index aacf929..d4114c2 100644
--- a/memory.c
+++ b/memory.c
@@ -55,6 +55,7 @@ struct meminfo { /* general purpose memory
information structure */
ulong found;
ulong retval;
char *ignore;
+ char *include;
int errors;
int calls;
int cpu;
@@ -4425,7 +4426,7 @@ cmd_kmem(void)
BZERO(&meminfo, sizeof(struct meminfo));
BZERO(&value[0], sizeof(ulonglong)*MAXARGS);
- while ((c = getopt(argcnt, args, "gI:sSFfpvczCinl:L:PVoh")) != EOF)
{
+ while ((c = getopt(argcnt, args, "gI:sSFfm:pvczCinl:L:PVoh")) !=
EOF) {
switch(c)
{
case 'V':
@@ -4480,6 +4481,10 @@ cmd_kmem(void)
pflag = 1;
break;
+ case 'm':
+ meminfo.include = optarg;
+ break;
+
case 'I':
meminfo.ignore = optarg;
break;
@@ -4948,7 +4953,7 @@ PG_slab_flag_init(void)
static void
dump_mem_map_SPARSEMEM(struct meminfo *mi)
{
- ulong i;
+ ulong i, j;
long total_pages;
int others, page_not_mapped, phys_not_mapped, page_mapping;
ulong pp, ppend;
@@ -4967,7 +4972,11 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
char buf4[BUFSIZE];
char *page_cache;
char *pcache;
- ulong section, section_nr, nr_mem_sections, section_size;
+ char *members = NULL;
+ char *memberlist[MAXARGS];
+ struct struct_member_data *member_data[MAXARGS];
+ int nr_members, populated;
+ ulong tmpvalue, section, section_nr, nr_mem_sections, section_size;
long buffersize;
char *outputbuffer;
int bufferindex;
@@ -4980,66 +4989,81 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
char style3[100];
char style4[100];
- sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- VADDR_PRLEN,
- space(MINSPACE),
- space(MINSPACE));
- sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
- VADDR_PRLEN,
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|RJUST, " "),
- " ");
- sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
- VADDR_PRLEN,
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "-------"),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|RJUST, "-----"));
- sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d ",
- VADDR_PRLEN,
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- VADDR_PRLEN,
- space(MINSPACE));
+ nr_members = mapping = index = 0;
+ reserved = shared = slabs = buffers = inode = offset = 0;
+ pg_spec = phys_spec = print_hdr = FALSE;
v22 = VALID_MEMBER(page_inode); /* page.inode vs. page.mapping */
- if (v22) {
- sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
- mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
- space(MINSPACE),
- mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- RJUST, "PHYSICAL"),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
- space(MINSPACE-1));
- } else {
- sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
- mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
- space(MINSPACE),
- mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- RJUST, "PHYSICAL"),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "MAPPING"),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
- }
+ if (!mi->include) {
+ sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ VADDR_PRLEN,
+ space(MINSPACE),
+ space(MINSPACE));
+ sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
+ VADDR_PRLEN,
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|RJUST, " "),
+ " ");
+ sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
+ VADDR_PRLEN,
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "-------"),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|RJUST, "-----"));
+ sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d ",
+ VADDR_PRLEN,
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ VADDR_PRLEN,
+ space(MINSPACE));
+
+ if (v22) {
+ sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
+ space(MINSPACE),
+ mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ RJUST, "PHYSICAL"),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
+ space(MINSPACE-1));
+ } else {
+ sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
+ space(MINSPACE),
+ mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ RJUST, "PHYSICAL"),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "MAPPING"),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
+ }
+ } else {
+ if (count_chars(mi->include, ',') > MAXARGS)
+ error(FATAL, "too many members in comma-separated list!\n");
- mapping = index = 0;
- reserved = shared = slabs = buffers = inode = offset = 0;
- pg_spec = phys_spec = print_hdr = FALSE;
+ if ((LASTCHAR(mi->include) == ',') || (LASTCHAR(mi->include) ==
'.'))
+ error(FATAL, "invalid format: %s\n", mi->include);
+
+ members = GETBUF(strlen(mi->include)+1);
+ strcpy(members, mi->include);
+ replace_string(members, ",", ' ');
+ nr_members = parse_line(members, memberlist);
+ populated = FALSE;
+
+ }
switch (mi->flags)
{
@@ -5065,7 +5089,8 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
error(FATAL, "dump_mem_map: no memtype specified\n");
break;
}
- print_hdr = TRUE;
+ if (!mi->include)
+ print_hdr = TRUE;
break;
case GET_ALL:
@@ -5092,7 +5117,8 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
break;
default:
- print_hdr = TRUE;
+ if (!mi->include)
+ print_hdr = TRUE;
break;
}
@@ -5188,187 +5214,251 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
if (!done && (pg_spec || phys_spec))
continue;
-
- flags = ULONG(pcache + OFFSET(page_flags));
- if (SIZE(page_flags) == 4)
- flags &= 0xffffffff;
- count = UINT(pcache + OFFSET(page_count));
- switch (mi->flags)
- {
- case GET_ALL:
- case GET_BUFFERS_PAGES:
- if (VALID_MEMBER(page_buffers)) {
- tmp = ULONG(pcache +
- OFFSET(page_buffers));
- if (tmp)
- buffers++;
- } else if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) {
- if ((flags >> v26_PG_private) & 1)
- buffers++;
- } else
- error(FATAL,
- "cannot determine whether pages have buffers\n");
+ if (mi->include) {
+ if (!populated) {
- if (mi->flags != GET_ALL)
- continue;
+ j = 0;
+ do {
+ if (!(member_data[j] = malloc(sizeof(struct struct_member_data)))) {
+ error(WARNING, "cannot malloc member_data space.\n");
+ nr_members = j += 1;
+ goto failed_member_data;
+ }
- /* FALLTHROUGH */
+ member_data[j]->structure = "page";
+ member_data[j]->member = memberlist[j];
+ if (!(fill_struct_member_data(member_data[j]))) {
+ error(WARNING, "Failed to populate member_data: "
+ "%s.%s does not exist.\n",
+ member_data[j]->structure, member_data[j]->member);
+ nr_members = j += 1;
+ goto failed_member_data;
+ }
- case GET_SLAB_PAGES:
- if (v22) {
- if ((flags >> v22_PG_Slab) & 1)
- slabs++;
- } else if (vt->PG_slab) {
- if ((flags >> vt->PG_slab) & 1)
- slabs++;
- } else {
- if ((flags >> v24_PG_slab) & 1)
- slabs++;
+ } while (++j < nr_members);
+ populated = TRUE;
}
- if (mi->flags != GET_ALL)
- continue;
- /* FALLTHROUGH */
- case GET_SHARED_PAGES:
- case GET_TOTALRAM_PAGES:
- if (vt->PG_reserved)
- PG_reserved_flag = vt->PG_reserved;
- else
- PG_reserved_flag = v22 ?
- 1 << v22_PG_reserved :
- 1 << v24_PG_reserved;
+ bufferindex += sprintf(outputbuffer + bufferindex,
+ "%lx\t", pp);
- if (flags & PG_reserved_flag) {
- reserved++;
- } else {
- if ((int)count >
- (vt->flags & PGCNT_ADJ ? 0 : 1))
- shared++;
- }
- continue;
- }
- page_mapping = VALID_MEMBER(page_mapping);
-
- if (v22) {
- inode = ULONG(pcache + OFFSET(page_inode));
- offset = ULONG(pcache + OFFSET(page_offset));
- } else if (page_mapping) {
- mapping = ULONG(pcache +
- OFFSET(page_mapping));
- index = ULONG(pcache + OFFSET(page_index));
- }
-
- page_not_mapped = phys_not_mapped = FALSE;
+ j = 0;
+ do {
+ switch (member_data[j]->type)
+ {
+ case TYPE_CODE_PTR:
+ readmem(pp + member_data[j]->offset, KVADDR, &tmpvalue,
+ member_data[j]->length, "tmpvalue", FAULT_ON_ERROR);
+ bufferindex += sprintf(outputbuffer + bufferindex, "0x%lx\t",
+ tmpvalue);
+ break;
+ case TYPE_CODE_INT:
+ readmem(pp + member_data[j]->offset, KVADDR, &tmpvalue,
+ member_data[j]->length, "tmpvalue", FAULT_ON_ERROR);
+ if (member_data[j]->unsigned_type ||
+ member_data[j]->length == sizeof(ulonglong))
+ bufferindex += sprintf(outputbuffer + bufferindex,
+ "%lu\t", tmpvalue);
+ else
+ bufferindex += sprintf(outputbuffer + bufferindex,
+ "%d\t", (int)tmpvalue);
+ break;
+ default:
+ error(WARNING, "invalid data structure reference %s.%s\n",
+ member_data[j]->structure, member_data[j]->member);
+ nr_members = j += 1;
+ goto failed_member_data;
+ break;
+ }
+ } while (++j < nr_members);
+
+ bufferindex += sprintf(outputbuffer+bufferindex, "\n");
- if (v22) {
- bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style1, pp, phys, inode,
- offset, count);
} else {
- if ((vt->flags & V_MEM_MAP)) {
- if (!machdep->verify_paddr(phys))
- phys_not_mapped = TRUE;
- if (!kvtop(NULL, pp, NULL, 0))
- page_not_mapped = TRUE;
+
+ flags = ULONG(pcache + OFFSET(page_flags));
+ if (SIZE(page_flags) == 4)
+ flags &= 0xffffffff;
+ count = UINT(pcache + OFFSET(page_count));
+
+ switch (mi->flags)
+ {
+ case GET_ALL:
+ case GET_BUFFERS_PAGES:
+ if (VALID_MEMBER(page_buffers)) {
+ tmp = ULONG(pcache +
+ OFFSET(page_buffers));
+ if (tmp)
+ buffers++;
+ } else if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) {
+ if ((flags >> v26_PG_private) & 1)
+ buffers++;
+ } else
+ error(FATAL,
+ "cannot determine whether pages have buffers\n");
+
+ if (mi->flags != GET_ALL)
+ continue;
+
+ /* FALLTHROUGH */
+
+ case GET_SLAB_PAGES:
+ if (v22) {
+ if ((flags >> v22_PG_Slab) & 1)
+ slabs++;
+ } else if (vt->PG_slab) {
+ if ((flags >> vt->PG_slab) & 1)
+ slabs++;
+ } else {
+ if ((flags >> v24_PG_slab) & 1)
+ slabs++;
+ }
+ if (mi->flags != GET_ALL)
+ continue;
+
+ /* FALLTHROUGH */
+
+ case GET_SHARED_PAGES:
+ case GET_TOTALRAM_PAGES:
+ if (vt->PG_reserved)
+ PG_reserved_flag = vt->PG_reserved;
+ else
+ PG_reserved_flag = v22 ?
+ 1 << v22_PG_reserved :
+ 1 << v24_PG_reserved;
+
+ if (flags & PG_reserved_flag) {
+ reserved++;
+ } else {
+ if ((int)count >
+ (vt->flags & PGCNT_ADJ ? 0 : 1))
+ shared++;
+ }
+ continue;
}
- if (page_not_mapped)
- bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style2, pp, phys);
- else if (!page_mapping)
- bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style3, pp, phys, count);
- else
+ page_mapping = VALID_MEMBER(page_mapping);
+
+ if (v22) {
+ inode = ULONG(pcache + OFFSET(page_inode));
+ offset = ULONG(pcache + OFFSET(page_offset));
+ } else if (page_mapping) {
+ mapping = ULONG(pcache +
+ OFFSET(page_mapping));
+ index = ULONG(pcache + OFFSET(page_index));
+ }
+
+ page_not_mapped = phys_not_mapped = FALSE;
+
+ if (v22) {
bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style4, pp, phys,
- mapping, index, count);
- }
-
- others = 0;
-
+ (char *)&style1, pp, phys, inode,
+ offset, count);
+ } else {
+ if ((vt->flags & V_MEM_MAP)) {
+ if (!machdep->verify_paddr(phys))
+ phys_not_mapped = TRUE;
+ if (!kvtop(NULL, pp, NULL, 0))
+ page_not_mapped = TRUE;
+ }
+ if (page_not_mapped)
+ bufferindex += sprintf(outputbuffer+bufferindex,
+ (char *)&style2, pp, phys);
+ else if (!page_mapping)
+ bufferindex += sprintf(outputbuffer+bufferindex,
+ (char *)&style3, pp, phys, count);
+ else
+ bufferindex += sprintf(outputbuffer+bufferindex,
+ (char *)&style4, pp, phys,
+ mapping, index, count);
+ }
+
+ others = 0;
+
#define sprintflag(X) sprintf(outputbuffer + bufferindex, X, others++ ? ","
: "")
- if (v22) {
- if ((flags >> v22_PG_DMA) & 1)
- bufferindex += sprintflag("%sDMA");
- if ((flags >> v22_PG_locked) & 1)
- bufferindex += sprintflag("%slocked");
- if ((flags >> v22_PG_error) & 1)
- bufferindex += sprintflag("%serror");
- if ((flags >> v22_PG_referenced) & 1)
- bufferindex += sprintflag("%sreferenced");
- if ((flags >> v22_PG_dirty) & 1)
- bufferindex += sprintflag("%sdirty");
- if ((flags >> v22_PG_uptodate) & 1)
- bufferindex += sprintflag("%suptodate");
- if ((flags >> v22_PG_free_after) & 1)
- bufferindex += sprintflag("%sfree_after");
- if ((flags >> v22_PG_decr_after) & 1)
- bufferindex += sprintflag("%sdecr_after");
- if ((flags >> v22_PG_swap_unlock_after) & 1)
- bufferindex += sprintflag("%sswap_unlock_after");
- if ((flags >> v22_PG_Slab) & 1)
- bufferindex += sprintflag("%sslab");
- if ((flags >> v22_PG_swap_cache) & 1)
- bufferindex += sprintflag("%sswap_cache");
- if ((flags >> v22_PG_skip) & 1)
- bufferindex += sprintflag("%sskip");
- if ((flags >> v22_PG_reserved) & 1)
- bufferindex += sprintflag("%sreserved");
- bufferindex += sprintf(outputbuffer+bufferindex, "\n");
- } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
- if (vt->flags & PAGEFLAGS)
- bufferindex += translate_page_flags(outputbuffer+bufferindex, flags);
- else
- bufferindex += sprintf(outputbuffer+bufferindex, "%lx\n", flags);
- } else {
-
- if ((flags >> v24_PG_locked) & 1)
- bufferindex += sprintflag("%slocked");
- if ((flags >> v24_PG_error) & 1)
- bufferindex += sprintflag("%serror");
- if ((flags >> v24_PG_referenced) & 1)
- bufferindex += sprintflag("%sreferenced");
- if ((flags >> v24_PG_uptodate) & 1)
- bufferindex += sprintflag("%suptodate");
- if ((flags >> v24_PG_dirty) & 1)
- bufferindex += sprintflag("%sdirty");
- if ((flags >> v24_PG_decr_after) & 1)
- bufferindex += sprintflag("%sdecr_after");
- if ((flags >> v24_PG_active) & 1)
- bufferindex += sprintflag("%sactive");
- if ((flags >> v24_PG_inactive_dirty) & 1)
- bufferindex += sprintflag("%sinactive_dirty");
- if ((flags >> v24_PG_slab) & 1)
- bufferindex += sprintflag("%sslab");
- if ((flags >> v24_PG_swap_cache) & 1)
- bufferindex += sprintflag("%sswap_cache");
- if ((flags >> v24_PG_skip) & 1)
- bufferindex += sprintflag("%sskip");
- if ((flags >> v24_PG_inactive_clean) & 1)
- bufferindex += sprintflag("%sinactive_clean");
- if ((flags >> v24_PG_highmem) & 1)
- bufferindex += sprintflag("%shighmem");
- if ((flags >> v24_PG_checked) & 1)
- bufferindex += sprintflag("%schecked");
- if ((flags >> v24_PG_bigpage) & 1)
- bufferindex += sprintflag("%sbigpage");
- if ((flags >> v24_PG_arch_1) & 1)
- bufferindex += sprintflag("%sarch_1");
- if ((flags >> v24_PG_reserved) & 1)
- bufferindex += sprintflag("%sreserved");
- if (phys_not_mapped)
- bufferindex += sprintflag("%s[NOT MAPPED]");
-
- bufferindex += sprintf(outputbuffer+bufferindex, "\n");
+ if (v22) {
+ if ((flags >> v22_PG_DMA) & 1)
+ bufferindex += sprintflag("%sDMA");
+ if ((flags >> v22_PG_locked) & 1)
+ bufferindex += sprintflag("%slocked");
+ if ((flags >> v22_PG_error) & 1)
+ bufferindex += sprintflag("%serror");
+ if ((flags >> v22_PG_referenced) & 1)
+ bufferindex += sprintflag("%sreferenced");
+ if ((flags >> v22_PG_dirty) & 1)
+ bufferindex += sprintflag("%sdirty");
+ if ((flags >> v22_PG_uptodate) & 1)
+ bufferindex += sprintflag("%suptodate");
+ if ((flags >> v22_PG_free_after) & 1)
+ bufferindex += sprintflag("%sfree_after");
+ if ((flags >> v22_PG_decr_after) & 1)
+ bufferindex += sprintflag("%sdecr_after");
+ if ((flags >> v22_PG_swap_unlock_after) & 1)
+ bufferindex += sprintflag("%sswap_unlock_after");
+ if ((flags >> v22_PG_Slab) & 1)
+ bufferindex += sprintflag("%sslab");
+ if ((flags >> v22_PG_swap_cache) & 1)
+ bufferindex += sprintflag("%sswap_cache");
+ if ((flags >> v22_PG_skip) & 1)
+ bufferindex += sprintflag("%sskip");
+ if ((flags >> v22_PG_reserved) & 1)
+ bufferindex += sprintflag("%sreserved");
+ bufferindex += sprintf(outputbuffer+bufferindex, "\n");
+ } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
+ if (vt->flags & PAGEFLAGS)
+ bufferindex += translate_page_flags(outputbuffer+bufferindex, flags);
+ else
+ bufferindex += sprintf(outputbuffer+bufferindex, "%lx\n", flags);
+ } else {
+
+ if ((flags >> v24_PG_locked) & 1)
+ bufferindex += sprintflag("%slocked");
+ if ((flags >> v24_PG_error) & 1)
+ bufferindex += sprintflag("%serror");
+ if ((flags >> v24_PG_referenced) & 1)
+ bufferindex += sprintflag("%sreferenced");
+ if ((flags >> v24_PG_uptodate) & 1)
+ bufferindex += sprintflag("%suptodate");
+ if ((flags >> v24_PG_dirty) & 1)
+ bufferindex += sprintflag("%sdirty");
+ if ((flags >> v24_PG_decr_after) & 1)
+ bufferindex += sprintflag("%sdecr_after");
+ if ((flags >> v24_PG_active) & 1)
+ bufferindex += sprintflag("%sactive");
+ if ((flags >> v24_PG_inactive_dirty) & 1)
+ bufferindex += sprintflag("%sinactive_dirty");
+ if ((flags >> v24_PG_slab) & 1)
+ bufferindex += sprintflag("%sslab");
+ if ((flags >> v24_PG_swap_cache) & 1)
+ bufferindex += sprintflag("%sswap_cache");
+ if ((flags >> v24_PG_skip) & 1)
+ bufferindex += sprintflag("%sskip");
+ if ((flags >> v24_PG_inactive_clean) & 1)
+ bufferindex += sprintflag("%sinactive_clean");
+ if ((flags >> v24_PG_highmem) & 1)
+ bufferindex += sprintflag("%shighmem");
+ if ((flags >> v24_PG_checked) & 1)
+ bufferindex += sprintflag("%schecked");
+ if ((flags >> v24_PG_bigpage) & 1)
+ bufferindex += sprintflag("%sbigpage");
+ if ((flags >> v24_PG_arch_1) & 1)
+ bufferindex += sprintflag("%sarch_1");
+ if ((flags >> v24_PG_reserved) & 1)
+ bufferindex += sprintflag("%sreserved");
+ if (phys_not_mapped)
+ bufferindex += sprintflag("%s[NOT MAPPED]");
+
+ bufferindex += sprintf(outputbuffer+bufferindex, "\n");
+ }
}
if (bufferindex > buffersize) {
fprintf(fp, "%s", outputbuffer);
bufferindex = 0;
}
-
+
if (done)
break;
}
@@ -5413,12 +5503,18 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
FREEBUF(outputbuffer);
FREEBUF(page_cache);
+failed_member_data:
+ if (mi->include) {
+ FREEBUF(members);
+ for (i = 0; i < nr_members; i++)
+ free(member_data[i]);
+ }
}
static void
dump_mem_map(struct meminfo *mi)
{
- long i, n;
+ ulong i, n, j;
long total_pages;
int others, page_not_mapped, phys_not_mapped, page_mapping;
ulong pp, ppend;
@@ -5439,6 +5535,11 @@ dump_mem_map(struct meminfo *mi)
char buf4[BUFSIZE];
char *page_cache;
char *pcache;
+ char *members = NULL;
+ char *memberlist[MAXARGS];
+ struct struct_member_data *member_data[MAXARGS];
+ int nr_members, populated;
+ ulong tmpvalue;
long buffersize;
char *outputbuffer;
int bufferindex;
@@ -5456,67 +5557,82 @@ dump_mem_map(struct meminfo *mi)
return;
}
- sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- VADDR_PRLEN,
- space(MINSPACE),
- space(MINSPACE));
- sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
- VADDR_PRLEN,
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|RJUST, " "),
- " ");
- sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
- VADDR_PRLEN,
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "-------"),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|RJUST, "-----"));
- sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d ",
- VADDR_PRLEN,
- space(MINSPACE),
- (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- space(MINSPACE),
- VADDR_PRLEN,
- space(MINSPACE));
+ nr_members = mapping = index = 0;
+ reserved = shared = slabs = buffers = inode = offset = 0;
+ pg_spec = phys_spec = print_hdr = FALSE;
v22 = VALID_MEMBER(page_inode); /* page.inode vs. page.mapping */
- if (v22) {
- sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
- mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
- space(MINSPACE),
- mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- RJUST, "PHYSICAL"),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
- space(MINSPACE-1));
- } else {
- sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
- mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
- space(MINSPACE),
- mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
- RJUST, "PHYSICAL"),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "MAPPING"),
- space(MINSPACE),
- mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
- }
+ if (!mi->include) {
+ sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ VADDR_PRLEN,
+ space(MINSPACE),
+ space(MINSPACE));
+ sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
+ VADDR_PRLEN,
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|RJUST, " "),
+ " ");
+ sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
+ VADDR_PRLEN,
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "-------"),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|RJUST, "-----"));
+ sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d ",
+ VADDR_PRLEN,
+ space(MINSPACE),
+ (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ space(MINSPACE),
+ VADDR_PRLEN,
+ space(MINSPACE));
+
+ if (v22) {
+ sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
+ space(MINSPACE),
+ mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ RJUST, "PHYSICAL"),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
+ space(MINSPACE-1));
+ } else {
+ sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"),
+ space(MINSPACE),
+ mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+ RJUST, "PHYSICAL"),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "MAPPING"),
+ space(MINSPACE),
+ mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
+ }
+ } else {
+ if (count_chars(mi->include, ',') > MAXARGS)
+ error(FATAL, "too many members in comma-separated list!\n");
+
+ if ((LASTCHAR(mi->include) == ',') || (LASTCHAR(mi->include) ==
'.'))
+ error(FATAL, "invalid format: %s\n", mi->include);
+
+ members = GETBUF(strlen(mi->include)+1);
+ strcpy(members, mi->include);
+ replace_string(members, ",", ' ');
+ nr_members = parse_line(members, memberlist);
+ populated = FALSE;
+
+ }
- mapping = index = 0;
- reserved = shared = slabs = buffers = inode = offset = 0;
- pg_spec = phys_spec = print_hdr = FALSE;
-
switch (mi->flags)
{
case ADDRESS_SPECIFIED:
@@ -5541,7 +5657,8 @@ dump_mem_map(struct meminfo *mi)
error(FATAL, "dump_mem_map: no memtype specified\n");
break;
}
- print_hdr = TRUE;
+ if (!mi->include)
+ print_hdr = TRUE;
break;
case GET_ALL:
@@ -5568,7 +5685,8 @@ dump_mem_map(struct meminfo *mi)
break;
default:
- print_hdr = TRUE;
+ if (!mi->include)
+ print_hdr = TRUE;
break;
}
@@ -5625,181 +5743,245 @@ dump_mem_map(struct meminfo *mi)
if (!done && (pg_spec || phys_spec))
continue;
-
- flags = ULONG(pcache + OFFSET(page_flags));
- if (SIZE(page_flags) == 4)
- flags &= 0xffffffff;
- count = UINT(pcache + OFFSET(page_count));
- switch (mi->flags)
- {
- case GET_ALL:
- case GET_BUFFERS_PAGES:
- if (VALID_MEMBER(page_buffers)) {
- tmp = ULONG(pcache +
- OFFSET(page_buffers));
- if (tmp)
- buffers++;
- } else if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) {
- if ((flags >> v26_PG_private) & 1)
- buffers++;
- } else
- error(FATAL,
- "cannot determine whether pages have buffers\n");
+ if (mi->include) {
+ if (!populated) {
- if (mi->flags != GET_ALL)
- continue;
+ j = 0;
+ do {
+ if (!(member_data[j] = malloc(sizeof(struct struct_member_data)))) {
+ error(WARNING, "cannot malloc member_data space.\n");
+ nr_members = j += 1;
+ goto failed_member_data;
+ }
- /* FALLTHROUGH */
+ member_data[j]->structure = "page";
+ member_data[j]->member = memberlist[j];
+ if (!(fill_struct_member_data(member_data[j]))) {
+ error(WARNING, "Failed to populate member_data: "
+ "%s.%s does not exist.\n",
+ member_data[j]->structure, member_data[j]->member);
+ nr_members = j += 1;
+ goto failed_member_data;
+ }
- case GET_SLAB_PAGES:
- if (v22) {
- if ((flags >> v22_PG_Slab) & 1)
- slabs++;
- } else if (vt->PG_slab) {
- if ((flags >> vt->PG_slab) & 1)
- slabs++;
- } else {
- if ((flags >> v24_PG_slab) & 1)
- slabs++;
+ } while (++j < nr_members);
+ populated = TRUE;
}
- if (mi->flags != GET_ALL)
- continue;
- /* FALLTHROUGH */
- case GET_SHARED_PAGES:
- case GET_TOTALRAM_PAGES:
- if (vt->PG_reserved)
- PG_reserved_flag = vt->PG_reserved;
- else
- PG_reserved_flag = v22 ?
- 1 << v22_PG_reserved :
- 1 << v24_PG_reserved;
+ bufferindex += sprintf(outputbuffer + bufferindex,
+ "%lx\t", pp);
- if (flags & PG_reserved_flag) {
- reserved++;
- } else {
- if ((int)count >
- (vt->flags & PGCNT_ADJ ? 0 : 1))
- shared++;
- }
- continue;
- }
-
- page_mapping = VALID_MEMBER(page_mapping);
-
- if (v22) {
- inode = ULONG(pcache + OFFSET(page_inode));
- offset = ULONG(pcache + OFFSET(page_offset));
- } else if (page_mapping) {
- mapping = ULONG(pcache +
- OFFSET(page_mapping));
- index = ULONG(pcache + OFFSET(page_index));
- }
-
- page_not_mapped = phys_not_mapped = FALSE;
+ j = 0;
+ do {
+ switch (member_data[j]->type)
+ {
+ case TYPE_CODE_PTR:
+ readmem(pp + member_data[j]->offset, KVADDR, &tmpvalue,
+ member_data[j]->length, "tmpvalue", FAULT_ON_ERROR);
+ bufferindex += sprintf(outputbuffer + bufferindex, "0x%lx\t",
+ tmpvalue);
+ break;
+ case TYPE_CODE_INT:
+ readmem(pp + member_data[j]->offset, KVADDR, &tmpvalue,
+ member_data[j]->length, "tmpvalue", FAULT_ON_ERROR);
+ if (member_data[j]->unsigned_type ||
+ member_data[j]->length == sizeof(ulonglong))
+ bufferindex += sprintf(outputbuffer + bufferindex,
+ "%lu\t", tmpvalue);
+ else
+ bufferindex += sprintf(outputbuffer + bufferindex,
+ "%d\t", (int)tmpvalue);
+ break;
+ default:
+ error(WARNING, "invalid data structure reference %s.%s\n",
+ member_data[j]->structure, member_data[j]->member);
+ nr_members = j += 1;
+ goto failed_member_data;
+ break;
+ }
+ } while (++j < nr_members);
+
+ bufferindex += sprintf(outputbuffer+bufferindex, "\n");
- if (v22) {
- bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style1, pp, phys, inode,
- offset, count);
} else {
- if ((vt->flags & V_MEM_MAP)) {
- if (!machdep->verify_paddr(phys))
- phys_not_mapped = TRUE;
- if (!kvtop(NULL, pp, NULL, 0))
- page_not_mapped = TRUE;
+
+ flags = ULONG(pcache + OFFSET(page_flags));
+ if (SIZE(page_flags) == 4)
+ flags &= 0xffffffff;
+ count = UINT(pcache + OFFSET(page_count));
+
+ switch (mi->flags)
+ {
+ case GET_ALL:
+ case GET_BUFFERS_PAGES:
+ if (VALID_MEMBER(page_buffers)) {
+ tmp = ULONG(pcache +
+ OFFSET(page_buffers));
+ if (tmp)
+ buffers++;
+ } else if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) {
+ if ((flags >> v26_PG_private) & 1)
+ buffers++;
+ } else
+ error(FATAL,
+ "cannot determine whether pages have buffers\n");
+
+ if (mi->flags != GET_ALL)
+ continue;
+
+ /* FALLTHROUGH */
+
+ case GET_SLAB_PAGES:
+ if (v22) {
+ if ((flags >> v22_PG_Slab) & 1)
+ slabs++;
+ } else if (vt->PG_slab) {
+ if ((flags >> vt->PG_slab) & 1)
+ slabs++;
+ } else {
+ if ((flags >> v24_PG_slab) & 1)
+ slabs++;
+ }
+ if (mi->flags != GET_ALL)
+ continue;
+
+ /* FALLTHROUGH */
+
+ case GET_SHARED_PAGES:
+ case GET_TOTALRAM_PAGES:
+ if (vt->PG_reserved)
+ PG_reserved_flag = vt->PG_reserved;
+ else
+ PG_reserved_flag = v22 ?
+ 1 << v22_PG_reserved :
+ 1 << v24_PG_reserved;
+
+ if (flags & PG_reserved_flag) {
+ reserved++;
+ } else {
+ if ((int)count >
+ (vt->flags & PGCNT_ADJ ? 0 : 1))
+ shared++;
+ }
+ continue;
}
- if (page_not_mapped)
- bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style2, pp, phys);
- else if (!page_mapping)
- bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style3, pp, phys, count);
- else
+
+ page_mapping = VALID_MEMBER(page_mapping);
+
+ if (v22) {
+ inode = ULONG(pcache + OFFSET(page_inode));
+ offset = ULONG(pcache + OFFSET(page_offset));
+ } else if (page_mapping) {
+ mapping = ULONG(pcache +
+ OFFSET(page_mapping));
+ index = ULONG(pcache + OFFSET(page_index));
+ }
+
+ page_not_mapped = phys_not_mapped = FALSE;
+
+ if (v22) {
bufferindex += sprintf(outputbuffer+bufferindex,
- (char *)&style4, pp, phys,
- mapping, index, count);
- }
-
- others = 0;
-
+ (char *)&style1, pp, phys, inode,
+ offset, count);
+ } else {
+ if ((vt->flags & V_MEM_MAP)) {
+ if (!machdep->verify_paddr(phys))
+ phys_not_mapped = TRUE;
+ if (!kvtop(NULL, pp, NULL, 0))
+ page_not_mapped = TRUE;
+ }
+ if (page_not_mapped)
+ bufferindex += sprintf(outputbuffer+bufferindex,
+ (char *)&style2, pp, phys);
+ else if (!page_mapping)
+ bufferindex += sprintf(outputbuffer+bufferindex,
+ (char *)&style3, pp, phys, count);
+ else
+ bufferindex += sprintf(outputbuffer+bufferindex,
+ (char *)&style4, pp, phys,
+ mapping, index, count);
+ }
+
+ others = 0;
+
#define sprintflag(X) sprintf(outputbuffer + bufferindex, X, others++ ? ","
: "")
- if (v22) {
- if ((flags >> v22_PG_DMA) & 1)
- bufferindex += sprintflag("%sDMA");
- if ((flags >> v22_PG_locked) & 1)
- bufferindex += sprintflag("%slocked");
- if ((flags >> v22_PG_error) & 1)
- bufferindex += sprintflag("%serror");
- if ((flags >> v22_PG_referenced) & 1)
- bufferindex += sprintflag("%sreferenced");
- if ((flags >> v22_PG_dirty) & 1)
- bufferindex += sprintflag("%sdirty");
- if ((flags >> v22_PG_uptodate) & 1)
- bufferindex += sprintflag("%suptodate");
- if ((flags >> v22_PG_free_after) & 1)
- bufferindex += sprintflag("%sfree_after");
- if ((flags >> v22_PG_decr_after) & 1)
- bufferindex += sprintflag("%sdecr_after");
- if ((flags >> v22_PG_swap_unlock_after) & 1)
- bufferindex += sprintflag("%sswap_unlock_after");
- if ((flags >> v22_PG_Slab) & 1)
- bufferindex += sprintflag("%sslab");
- if ((flags >> v22_PG_swap_cache) & 1)
- bufferindex += sprintflag("%sswap_cache");
- if ((flags >> v22_PG_skip) & 1)
- bufferindex += sprintflag("%sskip");
- if ((flags >> v22_PG_reserved) & 1)
- bufferindex += sprintflag("%sreserved");
- bufferindex += sprintf(outputbuffer+bufferindex, "\n");
- } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
- if (vt->flags & PAGEFLAGS)
- bufferindex += translate_page_flags(outputbuffer+bufferindex, flags);
- else
- bufferindex += sprintf(outputbuffer+bufferindex, "%lx\n", flags);
- } else {
-
- if ((flags >> v24_PG_locked) & 1)
- bufferindex += sprintflag("%slocked");
- if ((flags >> v24_PG_error) & 1)
- bufferindex += sprintflag("%serror");
- if ((flags >> v24_PG_referenced) & 1)
- bufferindex += sprintflag("%sreferenced");
- if ((flags >> v24_PG_uptodate) & 1)
- bufferindex += sprintflag("%suptodate");
- if ((flags >> v24_PG_dirty) & 1)
- bufferindex += sprintflag("%sdirty");
- if ((flags >> v24_PG_decr_after) & 1)
- bufferindex += sprintflag("%sdecr_after");
- if ((flags >> v24_PG_active) & 1)
- bufferindex += sprintflag("%sactive");
- if ((flags >> v24_PG_inactive_dirty) & 1)
- bufferindex += sprintflag("%sinactive_dirty");
- if ((flags >> v24_PG_slab) & 1)
- bufferindex += sprintflag("%sslab");
- if ((flags >> v24_PG_swap_cache) & 1)
- bufferindex += sprintflag("%sswap_cache");
- if ((flags >> v24_PG_skip) & 1)
- bufferindex += sprintflag("%sskip");
- if ((flags >> v24_PG_inactive_clean) & 1)
- bufferindex += sprintflag("%sinactive_clean");
- if ((flags >> v24_PG_highmem) & 1)
- bufferindex += sprintflag("%shighmem");
- if ((flags >> v24_PG_checked) & 1)
- bufferindex += sprintflag("%schecked");
- if ((flags >> v24_PG_bigpage) & 1)
- bufferindex += sprintflag("%sbigpage");
- if ((flags >> v24_PG_arch_1) & 1)
- bufferindex += sprintflag("%sarch_1");
- if ((flags >> v24_PG_reserved) & 1)
- bufferindex += sprintflag("%sreserved");
- if (phys_not_mapped)
- bufferindex += sprintflag("%s[NOT MAPPED]");
-
- bufferindex += sprintf(outputbuffer+bufferindex, "\n");
+ if (v22) {
+ if ((flags >> v22_PG_DMA) & 1)
+ bufferindex += sprintflag("%sDMA");
+ if ((flags >> v22_PG_locked) & 1)
+ bufferindex += sprintflag("%slocked");
+ if ((flags >> v22_PG_error) & 1)
+ bufferindex += sprintflag("%serror");
+ if ((flags >> v22_PG_referenced) & 1)
+ bufferindex += sprintflag("%sreferenced");
+ if ((flags >> v22_PG_dirty) & 1)
+ bufferindex += sprintflag("%sdirty");
+ if ((flags >> v22_PG_uptodate) & 1)
+ bufferindex += sprintflag("%suptodate");
+ if ((flags >> v22_PG_free_after) & 1)
+ bufferindex += sprintflag("%sfree_after");
+ if ((flags >> v22_PG_decr_after) & 1)
+ bufferindex += sprintflag("%sdecr_after");
+ if ((flags >> v22_PG_swap_unlock_after) & 1)
+ bufferindex += sprintflag("%sswap_unlock_after");
+ if ((flags >> v22_PG_Slab) & 1)
+ bufferindex += sprintflag("%sslab");
+ if ((flags >> v22_PG_swap_cache) & 1)
+ bufferindex += sprintflag("%sswap_cache");
+ if ((flags >> v22_PG_skip) & 1)
+ bufferindex += sprintflag("%sskip");
+ if ((flags >> v22_PG_reserved) & 1)
+ bufferindex += sprintflag("%sreserved");
+ bufferindex += sprintf(outputbuffer+bufferindex, "\n");
+ } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
+ if (vt->flags & PAGEFLAGS)
+ bufferindex += translate_page_flags(outputbuffer+bufferindex, flags);
+ else
+ bufferindex += sprintf(outputbuffer+bufferindex, "%lx\n", flags);
+ } else {
+
+ if ((flags >> v24_PG_locked) & 1)
+ bufferindex += sprintflag("%slocked");
+ if ((flags >> v24_PG_error) & 1)
+ bufferindex += sprintflag("%serror");
+ if ((flags >> v24_PG_referenced) & 1)
+ bufferindex += sprintflag("%sreferenced");
+ if ((flags >> v24_PG_uptodate) & 1)
+ bufferindex += sprintflag("%suptodate");
+ if ((flags >> v24_PG_dirty) & 1)
+ bufferindex += sprintflag("%sdirty");
+ if ((flags >> v24_PG_decr_after) & 1)
+ bufferindex += sprintflag("%sdecr_after");
+ if ((flags >> v24_PG_active) & 1)
+ bufferindex += sprintflag("%sactive");
+ if ((flags >> v24_PG_inactive_dirty) & 1)
+ bufferindex += sprintflag("%sinactive_dirty");
+ if ((flags >> v24_PG_slab) & 1)
+ bufferindex += sprintflag("%sslab");
+ if ((flags >> v24_PG_swap_cache) & 1)
+ bufferindex += sprintflag("%sswap_cache");
+ if ((flags >> v24_PG_skip) & 1)
+ bufferindex += sprintflag("%sskip");
+ if ((flags >> v24_PG_inactive_clean) & 1)
+ bufferindex += sprintflag("%sinactive_clean");
+ if ((flags >> v24_PG_highmem) & 1)
+ bufferindex += sprintflag("%shighmem");
+ if ((flags >> v24_PG_checked) & 1)
+ bufferindex += sprintflag("%schecked");
+ if ((flags >> v24_PG_bigpage) & 1)
+ bufferindex += sprintflag("%sbigpage");
+ if ((flags >> v24_PG_arch_1) & 1)
+ bufferindex += sprintflag("%sarch_1");
+ if ((flags >> v24_PG_reserved) & 1)
+ bufferindex += sprintflag("%sreserved");
+ if (phys_not_mapped)
+ bufferindex += sprintflag("%s[NOT MAPPED]");
+
+ bufferindex += sprintf(outputbuffer+bufferindex, "\n");
+ }
}
if (bufferindex > buffersize) {
@@ -5851,6 +6033,12 @@ dump_mem_map(struct meminfo *mi)
FREEBUF(outputbuffer);
FREEBUF(page_cache);
+failed_member_data:
+ if (mi->include) {
+ FREEBUF(members);
+ for (i = 0; i < nr_members; i++)
+ free(member_data[i]);
+ }
}
/*
--
1.9.3
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility