diff --git a/defs.h b/defs.h index 82d51e5..bcf8d6b 100755 --- a/defs.h +++ b/defs.h @@ -1184,6 +1184,8 @@ struct offset_table { /* stash of commonly-used offsets */ long page_buffers; long page_lru; long page_pte; + long page_mapcount; + long page_private; long swap_info_struct_swap_file; long swap_info_struct_swap_vfsmnt; long swap_info_struct_flags; diff --git a/memory.c b/memory.c index 9e8e7d0..15e2b0f 100755 --- a/memory.c +++ b/memory.c @@ -374,6 +374,12 @@ vm_init(void) MEMBER_OFFSET_INIT(page_buffers, "page", "buffers"); MEMBER_OFFSET_INIT(page_lru, "page", "lru"); MEMBER_OFFSET_INIT(page_pte, "page", "pte"); + MEMBER_OFFSET_INIT(page_mapcount, "page", "_mapcount"); + if (INVALID_MEMBER(page_mapcount)) + ANON_MEMBER_OFFSET_INIT(page_mapcount, "page", "_mapcount"); + MEMBER_OFFSET_INIT(page_private, "page", "private"); + if (INVALID_MEMBER(page_private)) + ANON_MEMBER_OFFSET_INIT(page_private, "page", "private"); MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd"); @@ -4418,21 +4424,25 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi) ulong tmp, reserved, shared, slabs; ulong PG_reserved_flag; long buffers; - ulong inode, offset, flags, mapping, index; - int count; + ulong inode, offset, flags, mapping, index, private; + int count, mapcount; int print_hdr, pg_spec, phys_spec, done; int v22; + int v26; char hdr[BUFSIZE]; char buf0[BUFSIZE]; char buf1[BUFSIZE]; char buf2[BUFSIZE]; char buf3[BUFSIZE]; char buf4[BUFSIZE]; + char buf5[BUFSIZE]; char *page_cache; char *pcache; ulong section, section_nr, nr_mem_sections, section_size; v22 = VALID_MEMBER(page_inode); /* page.inode vs. page.mapping */ + v26 = VALID_MEMBER(page_mapcount) && VALID_MEMBER(page_private); + /* page._mapcount & page.private both exist in 2.6.9 kernel and later */ if (v22) { sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n", @@ -4445,6 +4455,17 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi) space(MINSPACE), mkstring(buf4, 8, CENTER|LJUST, "OFFSET"), space(MINSPACE-1)); + } else if (v26) { + sprintf(hdr, "%s%s%s%s%s%s%sCNT MCNT %s 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"), + mkstring(buf5, VADDR_PRLEN, CENTER|RJUST, "PRIVATE")); } else { sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n", mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), @@ -4519,6 +4540,8 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi) page_cache = GETBUF(SIZE(page) * PGMM_CACHED); done = FALSE; total_pages = 0; + mapcount = 0; + private = 0; nr_mem_sections = NR_MEM_SECTIONS(); @@ -4611,6 +4634,10 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi) if (SIZE(page_flags) == 4) flags &= 0xffffffff; count = INT(pcache + OFFSET(page_count)); + if (v26) { + mapcount = INT(pcache + OFFSET(page_mapcount)); + private = ULONG(pcache + OFFSET(page_private)); + } switch (mi->flags) { @@ -4694,6 +4721,64 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi) offset, count, space(MINSPACE)); + } else if (v26) { + 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) + fprintf(fp, "%s%s%s%s%s%s%s %2s %4s %s ", + mkstring(buf0, VADDR_PRLEN, + LJUST|LONG_HEX, MKSTR(pp)), + space(MINSPACE), + mkstring(buf1, MAX(PADDR_PRLEN, + strlen("PHYSICAL")), + RJUST|LONGLONG_HEX, MKSTR(&phys)), + space(MINSPACE), + mkstring(buf3, VADDR_PRLEN, + CENTER|RJUST, " "), + space(MINSPACE), + mkstring(buf4, 8, CENTER|RJUST, " "), + " ", + " ", + mkstring(buf5, VADDR_PRLEN, + RJUST|LONG_HEX, " ")); + else if (!page_mapping) + fprintf(fp, "%s%s%s%s%s%s%s %2d %4d %s ", + mkstring(buf0, VADDR_PRLEN, + LJUST|LONG_HEX, MKSTR(pp)), + space(MINSPACE), + mkstring(buf1, MAX(PADDR_PRLEN, + strlen("PHYSICAL")), + RJUST|LONGLONG_HEX, MKSTR(&phys)), + space(MINSPACE), + mkstring(buf3, VADDR_PRLEN, + CENTER|RJUST, "-------"), + space(MINSPACE), + mkstring(buf4, 8, CENTER|RJUST, "-----"), + count, + mapcount, + mkstring(buf5, VADDR_PRLEN, + RJUST|LONG_HEX, MKSTR(private))); + else + fprintf(fp, "%s%s%s%s%s%s%8lx %2d %4d %s ", + mkstring(buf0, VADDR_PRLEN, + LJUST|LONG_HEX, MKSTR(pp)), + space(MINSPACE), + mkstring(buf1, MAX(PADDR_PRLEN, + strlen("PHYSICAL")), + RJUST|LONGLONG_HEX, MKSTR(&phys)), + space(MINSPACE), + mkstring(buf2, VADDR_PRLEN, + RJUST|LONG_HEX, MKSTR(mapping)), + space(MINSPACE), + index, + count, + mapcount, + mkstring(buf5, VADDR_PRLEN, + RJUST|LONG_HEX, MKSTR(private))); } else { if ((vt->flags & V_MEM_MAP)) { if (!machdep->verify_paddr(phys)) @@ -4902,11 +4987,12 @@ dump_mem_map(struct meminfo *mi) ulong tmp, reserved, shared, slabs; ulong PG_reserved_flag; long buffers; - ulong inode, offset, flags, mapping, index; + ulong inode, offset, flags, mapping, index, private; ulong node_size; - int count; + int count, mapcount; int print_hdr, pg_spec, phys_spec, done; int v22; + int v26; struct node_table *nt; char hdr[BUFSIZE]; char buf0[BUFSIZE]; @@ -4914,6 +5000,7 @@ dump_mem_map(struct meminfo *mi) char buf2[BUFSIZE]; char buf3[BUFSIZE]; char buf4[BUFSIZE]; + char buf5[BUFSIZE]; char *page_cache; char *pcache; @@ -4923,6 +5010,8 @@ dump_mem_map(struct meminfo *mi) } v22 = VALID_MEMBER(page_inode); /* page.inode vs. page.mapping */ + v26 = VALID_MEMBER(page_mapcount) && VALID_MEMBER(page_private); + /* page._mapcount & page.private both exist in 2.6.9 kernel and later */ if (v22) { sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n", @@ -4935,6 +5024,17 @@ dump_mem_map(struct meminfo *mi) space(MINSPACE), mkstring(buf4, 8, CENTER|LJUST, "OFFSET"), space(MINSPACE-1)); + } else if (v26) { + sprintf(hdr, "%s%s%s%s%s%s%sCNT MCNT %s 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"), + mkstring(buf5, VADDR_PRLEN, CENTER|RJUST, "PRIVATE")); } else { sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n", mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), @@ -5009,6 +5109,8 @@ dump_mem_map(struct meminfo *mi) page_cache = GETBUF(SIZE(page) * PGMM_CACHED); done = FALSE; total_pages = 0; + mapcount = 0; + private = 0; for (n = 0; n < vt->numnodes; n++) { if (print_hdr) { @@ -5062,6 +5164,10 @@ dump_mem_map(struct meminfo *mi) if (SIZE(page_flags) == 4) flags &= 0xffffffff; count = INT(pcache + OFFSET(page_count)); + if (v26) { + mapcount = INT(pcache + OFFSET(page_mapcount)); + private = ULONG(pcache + OFFSET(page_private)); + } switch (mi->flags) { @@ -5146,6 +5252,64 @@ dump_mem_map(struct meminfo *mi) offset, count, space(MINSPACE)); + } else if (v26) { + 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) + fprintf(fp, "%s%s%s%s%s%s%s %2s %4s %s ", + mkstring(buf0, VADDR_PRLEN, + LJUST|LONG_HEX, MKSTR(pp)), + space(MINSPACE), + mkstring(buf1, MAX(PADDR_PRLEN, + strlen("PHYSICAL")), + RJUST|LONGLONG_HEX, MKSTR(&phys)), + space(MINSPACE), + mkstring(buf3, VADDR_PRLEN, + CENTER|RJUST, " "), + space(MINSPACE), + mkstring(buf4, 8, CENTER|RJUST, " "), + " ", + " ", + mkstring(buf5, VADDR_PRLEN, + RJUST|LONG_HEX, " ")); + else if (!page_mapping) + fprintf(fp, "%s%s%s%s%s%s%s %2d %4d %s ", + mkstring(buf0, VADDR_PRLEN, + LJUST|LONG_HEX, MKSTR(pp)), + space(MINSPACE), + mkstring(buf1, MAX(PADDR_PRLEN, + strlen("PHYSICAL")), + RJUST|LONGLONG_HEX, MKSTR(&phys)), + space(MINSPACE), + mkstring(buf3, VADDR_PRLEN, + CENTER|RJUST, "-------"), + space(MINSPACE), + mkstring(buf4, 8, CENTER|RJUST, "-----"), + count, + mapcount, + mkstring(buf5, VADDR_PRLEN, + RJUST|LONG_HEX, MKSTR(private))); + else + fprintf(fp, "%s%s%s%s%s%s%8lx %2d %4d %s ", + mkstring(buf0, VADDR_PRLEN, + LJUST|LONG_HEX, MKSTR(pp)), + space(MINSPACE), + mkstring(buf1, MAX(PADDR_PRLEN, + strlen("PHYSICAL")), + RJUST|LONGLONG_HEX, MKSTR(&phys)), + space(MINSPACE), + mkstring(buf2, VADDR_PRLEN, + RJUST|LONG_HEX, MKSTR(mapping)), + space(MINSPACE), + index, + count, + mapcount, + mkstring(buf5, VADDR_PRLEN, + RJUST|LONG_HEX, MKSTR(private))); } else { if ((vt->flags & V_MEM_MAP)) { if (!machdep->verify_paddr(phys))