FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Crash Utility

 
 
LinkBack Thread Tools
 
Old 01-05-2012, 05:37 AM
Qiao Nuohan
 
Default display MCNT and PRIVATE when using kmem -p

Hello Dave,

I was using ‘kmem ?p’ to get status of memory. And I could only get
"PAGE PHYSICAL MAPPING INDEX CNT FLAGS" in 2.6.x kernel and later, which
makes me feel the lack of information. So I think of displaying
‘page._mapcount’ and ‘page.private’, when using ‘kmem -p’.

When adding these two items, I found ‘page._count’ is declared to be
atomic_t whose definition is:

typedef struct {

volatile int counter;

} atomic_t;

However, current crash codes use UINT to get the value of ‘page._count’.

The first patch (0001-kmem_p_6.0.2.patch) is used to change UINT to INT,
and the second one (0002-kmem_p_6.0.2.patch) will add the items talked
above. Both patches are based on crash 6.0.2.

BTW, I have tested these two patches on RHEL6.2_x86_64, RHEL6.2_i386,
RHEL5.8_x86_64 and RHEL5.8_i386.

--
Regards
Qiao Nuohan


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
",
@@ -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
",
+ 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
",
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
",
@@ -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
",
+ 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
",
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))
diff --git a/memory.c b/memory.c
index 95eefc9..9e8e7d0 100755
--- a/memory.c
+++ b/memory.c
@@ -4419,7 +4419,7 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
ulong PG_reserved_flag;
long buffers;
ulong inode, offset, flags, mapping, index;
- uint count;
+ int count;
int print_hdr, pg_spec, phys_spec, done;
int v22;
char hdr[BUFSIZE];
@@ -4610,7 +4610,7 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
flags = ULONG(pcache + OFFSET(page_flags));
if (SIZE(page_flags) == 4)
flags &= 0xffffffff;
- count = UINT(pcache + OFFSET(page_count));
+ count = INT(pcache + OFFSET(page_count));

switch (mi->flags)
{
@@ -4904,7 +4904,7 @@ dump_mem_map(struct meminfo *mi)
long buffers;
ulong inode, offset, flags, mapping, index;
ulong node_size;
- uint count;
+ int count;
int print_hdr, pg_spec, phys_spec, done;
int v22;
struct node_table *nt;
@@ -5061,7 +5061,7 @@ dump_mem_map(struct meminfo *mi)
flags = ULONG(pcache + OFFSET(page_flags));
if (SIZE(page_flags) == 4)
flags &= 0xffffffff;
- count = UINT(pcache + OFFSET(page_count));
+ count = INT(pcache + OFFSET(page_count));

switch (mi->flags)
{
--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 
Old 02-28-2012, 04:54 AM
qiaonuohan
 
Default display MCNT and PRIVATE when using kmem -p

At 2012-1-10 21:54, Dave Anderson wrote:



----- Original Message -----

Hello Dave,

Glad to hear the capability is desirable. I will start to implement this
soon.




What if I change struct sub-command to this:

1. it can refer to anonymous members (e.g., page._mapcount)
2. it can refer to submembers(e.g., page._count.counter)


One other suggestion -- I believe it should not be necessary to
support the "page._count.counter" format, because you can get
the data by using the container name. Taking the "_count.counter"
example:

crash> p ((struct page *)0xffffea0000000200)._count.counter
$10 = 0
crash> p ((struct page *)0xffffea0000000200)._count
$11 = {
counter = 0
}
crash>

So using "page._count" should suffice.

Thanks,
Dave

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility



Hello Dave,

Sorry for reacting late. I have started to realize these item we talked
before. But, considering your mail about "page._count.counter" format, I
need to explain my opinion to you. Trying to support the
"page._count.counter" format is used to help implementing the formatted
output like:


crash> struct page.flags,_count.counter -.. < PAGE_list.txt
1024 0
1024 1
1024 1
1024 1

Compared with "p ((struct page *)0xffffea0000000200)._count.counter",
which can only display only one data each time, the former style can be
more helpful when parsing the output.


The reason why I want the "page._count.counter" format is I want to
offer an efficient way to collect a lot of data. Then I'd like you to
give some comments. Thanks.


--
--
Regards
Qiao Nuohan

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 

Thread Tools




All times are GMT. The time now is 03:12 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org