[Crash-utility] [PATCH] kmem: introduce -m option
Dave Anderson
anderson at redhat.com
Fri Apr 24 19:46:45 UTC 2015
----- Original Message -----
> 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 at 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 at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
>
More information about the Crash-utility
mailing list