All of lore.kernel.org
 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:36 UTC|newest]

Thread overview: 44+ 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:22 ` Wu Fengguang
2009-04-14  4:36 ` Wu Fengguang [this message]
2009-04-14  4:37 ` KOSAKI Motohiro
2009-04-14  4:37   ` KOSAKI Motohiro
2009-04-14  6:41   ` Wu Fengguang
2009-04-14  6:41     ` Wu Fengguang
2009-04-14  6:54     ` KOSAKI Motohiro
2009-04-14  6:54       ` KOSAKI Motohiro
2009-04-14  7:11       ` Andi Kleen
2009-04-14  7:11         ` Andi Kleen
2009-04-14  7:17         ` KOSAKI Motohiro
2009-04-14  7:17           ` KOSAKI Motohiro
2009-04-15 13:18         ` Wu Fengguang
2009-04-15 13:18           ` Wu Fengguang
2009-04-15 13:57           ` Andi Kleen
2009-04-15 13:57             ` Andi Kleen
2009-04-16  2:41             ` Wu Fengguang
2009-04-16  2:41               ` Wu Fengguang
2009-04-16  3:54               ` Andi Kleen
2009-04-16  3:54                 ` Andi Kleen
2009-04-16  4:43                 ` Wu Fengguang
2009-04-16  4:43                   ` Wu Fengguang
2009-04-16  2:26           ` KOSAKI Motohiro
2009-04-16  2:26             ` KOSAKI Motohiro
2009-04-16  3:49             ` Wu Fengguang
2009-04-16  3:49               ` Wu Fengguang
2009-04-16  6:30               ` 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  2:26               ` Wu Fengguang
2009-04-23  7:48               ` Andi Kleen
2009-04-23  7:48                 ` Andi Kleen
2009-04-23  8:10                 ` Wu Fengguang
2009-04-23  8:10                   ` Wu Fengguang
2009-04-23  8:54                   ` Andi Kleen
2009-04-23  8:54                     ` Andi Kleen
2009-04-23 11:21                     ` Wu Fengguang
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:22         ` Wu Fengguang
2009-04-14  7:42         ` KOSAKI Motohiro
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.