linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Wu Fengguang <fengguang.wu@intel.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Andi Kleen <andi@firstfloor.org>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-mm@kvack.org
Subject: Re: [RFC][PATCH] proc: export more page flags in /proc/kpageflags
Date: Tue, 14 Apr 2009 12:36:11 +0800	[thread overview]
Message-ID: <20090414043611.GA4385@localhost> (raw)
In-Reply-To: <20090414042231.GA4341@localhost>

[-- Attachment #1: Type: text/plain, Size: 5586 bytes --]

On Tue, Apr 14, 2009 at 12:22:31PM +0800, Wu Fengguang wrote:
> Export the following page flags in /proc/kpageflags,
> just in case they will be useful to someone:
> 
> - PG_swapcache
> - PG_swapbacked
> - PG_mappedtodisk
> - PG_reserved
> - PG_private
> - PG_private_2
> - PG_owner_priv_1
> 
> - PG_head
> - PG_tail
> - PG_compound
> 
> - PG_unevictable
> - PG_mlocked
> 
> - PG_poison
> 
> Also add the following two pseudo page flags:
> 
> - PG_MMAP:   whether the page is memory mapped
> - PG_NOPAGE: whether the page is present
> 
> This increases the total number of exported page flags to 25.

And here are two simple tools utilizing the exported page flags:

# ./page-types         
   flags        page-count       MB  symbolic-flags             long-symbolic-flags
0x000000            472521     1845  _________________________
0x000020                 1        0  _____l___________________  lru
0x000028              2516        9  ___U_l___________________  uptodate,lru
0x00002c              5209       20  __RU_l___________________  referenced,uptodate,lru
0x000068               234        0  ___U_lA__________________  uptodate,lru,active
0x00006c               981        3  __RU_lA__________________  referenced,uptodate,lru,active
0x000228                49        0  ___U_l___x_______________  uptodate,lru,reclaim
0x000400               547        2  __________B______________  buddy
0x000804                 1        0  __R________m_____________  referenced,mmap
0x000828              1073        4  ___U_l_____m_____________  uptodate,lru,mmap
0x00082c               318        1  __RU_l_____m_____________  referenced,uptodate,lru,mmap
0x000868               235        0  ___U_lA____m_____________  uptodate,lru,active,mmap
0x00086c               822        3  __RU_lA____m_____________  referenced,uptodate,lru,active,mmap
0x000880              1510        5  _______S___m_____________  slab,mmap
0x0008c0                49        0  ______AS___m_____________  active,slab,mmap
0x002078                 1        0  ___UDlA______b___________  uptodate,dirty,lru,active,swapbacked
0x00207c                17        0  __RUDlA______b___________  referenced,uptodate,dirty,lru,active,swapbacked
0x002808                10        0  ___U_______m_b___________  uptodate,mmap,swapbacked
0x002868              3296       12  ___U_lA____m_b___________  uptodate,lru,active,mmap,swapbacked
0x00286c                25        0  __RU_lA____m_b___________  referenced,uptodate,lru,active,mmap,swapbacked
0x002878                 2        0  ___UDlA____m_b___________  uptodate,dirty,lru,active,mmap,swapbacked
0x008000             19247       75  _______________r_________  reserved
0x080000                15        0  ___________________H_____  head
0x080014                 1        0  __R_D______________H_____  referenced,dirty,head
0x080880               915        3  _______S___m_______H_____  slab,mmap,head
0x0808c0                60        0  ______AS___m_______H_____  active,slab,mmap,head
0x100000              4309       16  ____________________T____  tail
0x100014                 4        0  __R_D_______________T____  referenced,dirty,tail
   total            513968     2007

To show the compound tail pages:
# ./page-areas 0x100000
    offset      len         KB
      3089        3       12KB
    487441        7       28KB
    487449        7       28KB
    487457        7       28KB
    487465        7       28KB
    487473        7       28KB
    487481        7       28KB
    487489        7       28KB
    487497        7       28KB
    487505        7       28KB
    487513        7       28KB
    487521        7       28KB
    487529        7       28KB
    487537        7       28KB
    487545        7       28KB
    487553        7       28KB
    487561        7       28KB
    487569        7       28KB
    487577        7       28KB
    487585        7       28KB
    487593        7       28KB
    487617        7       28KB
    487627        1        4KB
    487629        1        4KB
    487633        7       28KB
    487641        7       28KB
    487649        7       28KB
    487657        7       28KB
    487665        7       28KB
    487673        7       28KB
    487681        7       28KB
    487689        7       28KB
    487697        7       28KB
    487705        7       28KB
    487713        7       28KB
    487721        7       28KB
    487729        7       28KB
    487737        7       28KB
    487745        7       28KB
    487753        7       28KB
    487761        7       28KB
    487769        7       28KB
    487777        7       28KB
    487785        7       28KB
    487793        7       28KB
    487801        7       28KB
    487809        7       28KB
    487817        7       28KB
    487825        7       28KB
    487853        3       12KB
    487865        7       28KB
    487873        3       12KB
    487893        3       12KB
    487897        3       12KB
    487901        3       12KB
    487905        3       12KB
    487909        3       12KB
    487929        7       28KB
    487937        7       28KB
    487945        7       28KB
    493569        3       12KB
    493573        1        4KB
    493575        1        4KB
    493585        7       28KB
    493593        3       12KB
    493597        3       12KB
    493601        7       28KB
    493609        7       28KB
    493617        7       28KB
    493625        1        4KB
    493633        7       28KB
    493641        3       12KB
    493645        3       12KB
[snip]

Thanks,
Fengguang


[-- Attachment #2: page-types.c --]
[-- Type: text/x-csrc, Size: 1635 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/fcntl.h>

#include "pagemap.h"

int main(int argc, char *argv[])
{
	static char kpageflags_name[] = "/proc/kpageflags";
	unsigned long i;
	uint64_t flags;
	int fd;

	fd = open(kpageflags_name, O_RDONLY);
	if (fd < 0) {
		perror(kpageflags_name);
		exit(1);
	}

	nr_pages = read(fd, kpageflags, sizeof(kpageflags));
	if (nr_pages <= 0) {
		perror(kpageflags_name);
		exit(2);
	}
	if (nr_pages % KPF_BYTES != 0) {
		fprintf(stderr, "%s: partial read: %lu bytes\n",
				argv[0], nr_pages);
		exit(3);
	}
	nr_pages = nr_pages / KPF_BYTES;

	for (i = 0; i < nr_pages; i++) {
		flags = kpageflags[i];

		if (flags >= ARRAY_SIZE(page_count)) {
			static int warned = 0;

			if (!warned) {
				warned = 1;
				fprintf(stderr, "%s: flags overflow: 0x%lx >= 0x%lx\n",
					argv[0], flags, ARRAY_SIZE(page_count));
				fprintf(stderr, "Either the kernel is buggy(<=2.6.28), "
					"or I'm too old to recognize new flags.\n\n");
			}

			flags = ARRAY_SIZE(page_count) - 1;
		}
		page_count[flags]++;
	}

#if 0
	for (i = 0; i < ARRAY_SIZE(page_flag_names); i++) {
		printf("%s ", page_flag_names[i]);
	}
#endif

	printf("   flags\tpage-count       MB  symbolic-flags             long-symbolic-flags\n");
	for (i = 0; i < ARRAY_SIZE(page_count); i++) {
		if (page_count[i])
			printf("0x%06lx\t%10lu %8lu  %s  %s\n",
				i,
				page_count[i],
				pages2mb(page_count[i]),
				page_flag_name(i),
				page_flag_longname(i));
	}

	printf("   total\t%10lu %8lu\n",
			nr_pages, pages2mb(nr_pages));

	return 0;
}

[-- Attachment #3: pagemap.h --]
[-- Type: text/x-chdr, Size: 2824 bytes --]


#define KPF_BYTES	8

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

/* copied from kpageflags_read() */

enum { 
        KPF_LOCKED,             /*  0 */
        KPF_ERROR,              /*  1 */
        KPF_REFERENCED,         /*  2 */
        KPF_UPTODATE,           /*  3 */
        KPF_DIRTY,              /*  4 */
        KPF_LRU,                /*  5 */
        KPF_ACTIVE,             /*  6 */
        KPF_SLAB,               /*  7 */
        KPF_WRITEBACK,          /*  8 */
        KPF_RECLAIM,            /*  9 */
        KPF_BUDDY,              /* 10 */
        KPF_MMAP,               /* 11 */
        KPF_SWAPCACHE,          /* 12 */
        KPF_SWAPBACKED,         /* 13 */
        KPF_MAPPEDTODISK,       /* 14 */
        KPF_RESERVED,           /* 15 */
        KPF_PRIVATE,            /* 16 */
        KPF_PRIVATE2,           /* 17 */
        KPF_OWNER_PRIVATE,      /* 18 */
        KPF_COMPOUND_HEAD,      /* 19 */
        KPF_COMPOUND_TAIL,      /* 20 */
        KPF_UNEVICTABLE,        /* 21 */
        KPF_MLOCKED,            /* 22 */
        KPF_POISON,             /* 23 */
        KPF_NOPAGE,             /* 24 */
        KPF_NUM
};

static char *page_flag_names[] = {
	[KPF_LOCKED]		= "L:locked",
	[KPF_ERROR]		= "E:error",
	[KPF_REFERENCED]	= "R:referenced",
	[KPF_UPTODATE]		= "U:uptodate",
	[KPF_DIRTY]		= "D:dirty",
	[KPF_LRU]		= "l:lru",
	[KPF_ACTIVE]		= "A:active",
	[KPF_SLAB]		= "S:slab",
	[KPF_WRITEBACK]		= "W:writeback",
	[KPF_RECLAIM]		= "x:reclaim",
	[KPF_BUDDY]		= "B:buddy",
	[KPF_RESERVED]		= "r:reserved",
	[KPF_SWAPCACHE]		= "c:swapcache",
	[KPF_SWAPBACKED]	= "b:swapbacked",
	[KPF_MAPPEDTODISK]	= "d:mappedtodisk",
	[KPF_PRIVATE]		= "P:private",
	[KPF_PRIVATE2]		= "p:private_2",
	[KPF_OWNER_PRIVATE]	= "O:owner_private",
	[KPF_COMPOUND_HEAD]	= "H:head",
	[KPF_COMPOUND_TAIL]	= "T:tail",
	[KPF_UNEVICTABLE]	= "u:unevictable",
	[KPF_MLOCKED]		= "M:mlocked",
	[KPF_MMAP]		= "m:mmap",
	[KPF_POISON]		= "X:poison",
	[KPF_NOPAGE]		= "n:nopage",
};

static unsigned long page_count[(1 << KPF_NUM)];
static unsigned long nr_pages;
static uint64_t kpageflags[KPF_BYTES * (16<<20)]; /* 64GB */

char *page_flag_name(uint64_t flags)
{
	int i;
	static char buf[64];

	for (i = 0; i < ARRAY_SIZE(page_flag_names); i++)
		buf[i] = (flags & (1 << i)) ? page_flag_names[i][0] : '_';

	return buf;
}

char *page_flag_longname(uint64_t flags)
{
	int i, n;
	static char buf[1024];

	for (i = 0, n = 0; i < ARRAY_SIZE(page_flag_names); i++)
		if (flags & (1<<i))
		       n += snprintf(buf + n, sizeof(buf) - n, "%s,",
				       page_flag_names[i] + 2);
	if (n)
		n--;
	buf[n] = '\0';

	return buf;
}

static unsigned long pages2kb(unsigned long pages)
{
	return (pages * getpagesize()) >> 10;
}

static unsigned long pages2mb(unsigned long pages)
{
	return (pages * getpagesize()) >> 20;
}


[-- Attachment #4: Makefile --]
[-- Type: text/plain, Size: 169 bytes --]

BINS = page-types page-areas

all: $(BINS)

page-types: page-types.c pagemap.h
	gcc -g -o $@ $<

page-areas: page-areas.c pagemap.h
	gcc -g -o $@ $<

clean:
	rm $(BINS)

[-- Attachment #5: page-areas.c --]
[-- Type: text/x-csrc, Size: 1443 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/fcntl.h>

#include "pagemap.h"

static void add_index(unsigned long index)
{
	static unsigned long offset, len;

	if (index == offset + len)
		len++;
	else {
		if (len)
			printf("%10lu %8lu %8luKB\n", offset, len, pages2kb(len));
		offset = index;
		len = 1;
	}
}

static void usage(const char *prog)
{
	printf("Usage: %s page_flags\n", prog);
}

int main(int argc, char *argv[])
{
	static char kpageflags_name[] = "/proc/kpageflags";
	unsigned long match_flags, match_exact;
	unsigned long i;
	char *p;
	int fd;

	if (argc < 2) {
		usage(argv[0]);
		exit(1);
	}

	match_exact = 0;
	p = argv[1];
	if (p[0] == '=') {
		match_exact = 1;
		p++;
	}
	match_flags = strtol(p, 0, 16);

	fd = open(kpageflags_name, O_RDONLY);
	if (fd < 0) {
		perror(kpageflags_name);
		exit(1);
	}

	nr_pages = read(fd, kpageflags, sizeof(kpageflags));
	if (nr_pages <= 0) {
		perror(kpageflags_name);
		exit(2);
	}
	if (nr_pages % KPF_BYTES != 0) {
		fprintf(stderr, "%s: partial read: %lu bytes\n",
				argv[0], nr_pages);
		exit(3);
	}
	nr_pages = nr_pages / KPF_BYTES;

	printf("    offset      len         KB\n");
	for (i = 0; i < nr_pages; i++) {
		if (!match_exact && ((kpageflags[i] & match_flags) == match_flags) ||
		    (match_exact && kpageflags[i] == match_flags))
			add_index(i);
	}
	add_index(0);

	return 0;
}

  reply	other threads:[~2009-04-14  4:35 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-14  4:22 [RFC][PATCH] proc: export more page flags in /proc/kpageflags Wu Fengguang
2009-04-14  4:36 ` Wu Fengguang [this message]
2009-04-14  4:37 ` KOSAKI Motohiro
2009-04-14  6:41   ` Wu Fengguang
2009-04-14  6:54     ` KOSAKI Motohiro
2009-04-14  7:11       ` Andi Kleen
2009-04-14  7:17         ` KOSAKI Motohiro
2009-04-15 13:18         ` Wu Fengguang
2009-04-15 13:57           ` Andi Kleen
2009-04-16  2:41             ` Wu Fengguang
2009-04-16  3:54               ` Andi Kleen
2009-04-16  4:43                 ` Wu Fengguang
2009-04-16  2:26           ` KOSAKI Motohiro
2009-04-16  3:49             ` Wu Fengguang
2009-04-16  6:30               ` Wu Fengguang
2009-04-23  2:26             ` [RFC][PATCH] proc: export more page flags in /proc/kpageflags (take 3) Wu Fengguang
2009-04-23  7:48               ` Andi Kleen
2009-04-23  8:10                 ` Wu Fengguang
2009-04-23  8:54                   ` Andi Kleen
2009-04-23 11:21                     ` Wu Fengguang
2009-04-25  1:59               ` Wu Fengguang
2009-04-14  7:22       ` [RFC][PATCH] proc: export more page flags in /proc/kpageflags Wu Fengguang
2009-04-14  7:42         ` KOSAKI Motohiro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090414043611.GA4385@localhost \
    --to=fengguang.wu@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).