----- 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@xxxxxxxxxx> 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@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility