* [PATCH 0/7] export more page flags in /proc/kpageflags (take 5)
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Matt Mackall, KOSAKI Motohiro, Wu, Fengguang, Andi Kleen, linux-mm
Andrew,
This take:
- add page-types tool for querying the exported page flags.
- export all page flags unconditionally and faithfully, and offload
complicated filtering works to the user space tool.
This patchset:
Export 10 more flags to end users (and more for kernel developers):
11. KPF_MMAP (pseudo flag) memory mapped page
12. KPF_ANON (pseudo flag) memory mapped page (anonymous)
13. KPF_SWAPCACHE page is in swap cache
14. KPF_SWAPBACKED page is swap/RAM backed
15. KPF_COMPOUND_HEAD (*)
16. KPF_COMPOUND_TAIL (*)
17. KPF_HUGE hugeTLB pages
18. KPF_UNEVICTABLE page is in the unevictable LRU list
19. KPF_HWPOISON hardware detected corruption
20. KPF_NOPAGE (pseudo flag) no page frame at the address
(*) For compound pages, exporting _both_ head/tail info enables
users to tell where a compound page starts/ends, and its order.
Patches:
[PATCH 1/7] mm: introduce PageHuge() for testing huge/gigantic pages
[PATCH 2/7] slob: use PG_slab for identifying SLOB pages
[PATCH 3/7] proc: kpagecount/kpageflags code cleanup
[PATCH 4/7] proc: export more page flags in /proc/kpageflags
[PATCH 5/7] pagemap: document clarifications
[PATCH 6/7] pagemap: document 9 more exported page flags
[PATCH 7/7] pagemap: add page-types tool
Documentation/vm/Makefile | 2
Documentation/vm/page-types.c | 696 ++++++++++++++++++++++++++++++++
Documentation/vm/pagemap.txt | 72 +++
fs/proc/page.c | 163 +++++--
include/linux/mm.h | 24 +
include/linux/page-flags.h | 2
mm/hugetlb.c | 2
mm/page_alloc.c | 11
mm/slob.c | 6
9 files changed, 933 insertions(+), 45 deletions(-)
Thanks,
Fengguang
--
PS. a simple demo of page-types
# ./page-types -h
page-types [options]
-r|--raw Raw mode, for kernel developers
-a|--addr addr-spec Walk a range of pages
-b|--bits bits-spec Walk pages with specified bits
addr-spec:
N one page at offset N (unit: pages)
N+M pages range from N to N+M-1
N,M pages range from N to M-1
N, pages range from N to end
,M pages range from 0 to M
bits-spec:
bit1,bit2 (flags & (bit1|bit2)) != 0
bit1,bit2=bit1 (flags & (bit1|bit2)) == bit1
bit1,~bit2 (flags & (bit1|bit2)) == bit1
=bit1,bit2 flags == (bit1|bit2)
bit-names:
locked error referenced uptodate
dirty lru active slab
writeback reclaim buddy mmap
anonymous swapcache swapbacked compound_head
compound_tail huge unevictable hwpoison
nopage reserved(r) mlocked(r) mappedtodisk(r)
private(r) private_2(r) owner_private(r) arch(r)
uncached(r) readahead(o) slob_free(o) slub_frozen(o)
slub_debug(o)
(r) raw mode bits (o) overloaded bits
# ./page-types
flags page-count MB symbolic-flags long-symbolic-flags
0x0000000000000000 487369 1903 _________________________________
0x0000000000000014 5 0 __R_D____________________________ referenced,dirty
0x0000000000000020 1 0 _____l___________________________ lru
0x0000000000000024 34 0 __R__l___________________________ referenced,lru
0x0000000000000028 3838 14 ___U_l___________________________ uptodate,lru
0x0001000000000028 48 0 ___U_l_______________________I___ uptodate,lru,readahead
0x000000000000002c 6478 25 __RU_l___________________________ referenced,uptodate,lru
0x000100000000002c 47 0 __RU_l_______________________I___ referenced,uptodate,lru,readahead
0x0000000000000040 8344 32 ______A__________________________ active
0x0000000000000060 1 0 _____lA__________________________ lru,active
0x0000000000000068 348 1 ___U_lA__________________________ uptodate,lru,active
0x0001000000000068 12 0 ___U_lA______________________I___ uptodate,lru,active,readahead
0x000000000000006c 988 3 __RU_lA__________________________ referenced,uptodate,lru,active
0x000100000000006c 48 0 __RU_lA______________________I___ referenced,uptodate,lru,active,readahead
0x0000000000004078 1 0 ___UDlA_______b__________________ uptodate,dirty,lru,active,swapbacked
0x000000000000407c 34 0 __RUDlA_______b__________________ referenced,uptodate,dirty,lru,active,swapbacked
0x0000000000000400 503 1 __________B______________________ buddy
0x0000000000000804 1 0 __R________M_____________________ referenced,mmap
0x0000000000000828 1029 4 ___U_l_____M_____________________ uptodate,lru,mmap
0x0001000000000828 43 0 ___U_l_____M_________________I___ uptodate,lru,mmap,readahead
0x000000000000082c 382 1 __RU_l_____M_____________________ referenced,uptodate,lru,mmap
0x000100000000082c 12 0 __RU_l_____M_________________I___ referenced,uptodate,lru,mmap,readahead
0x0000000000000868 192 0 ___U_lA____M_____________________ uptodate,lru,active,mmap
0x0001000000000868 12 0 ___U_lA____M_________________I___ uptodate,lru,active,mmap,readahead
0x000000000000086c 800 3 __RU_lA____M_____________________ referenced,uptodate,lru,active,mmap
0x000100000000086c 31 0 __RU_lA____M_________________I___ referenced,uptodate,lru,active,mmap,readahead
0x0000000000004878 2 0 ___UDlA____M__b__________________ uptodate,dirty,lru,active,mmap,swapbacked
0x0000000000001000 492 1 ____________a____________________ anonymous
0x0000000000005808 4 0 ___U_______Ma_b__________________ uptodate,mmap,anonymous,swapbacked
0x0000000000005868 2839 11 ___U_lA____Ma_b__________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x000000000000586c 30 0 __RU_lA____Ma_b__________________ referenced,uptodate,lru,active,mmap,anonymous,swapbacked
total 513968 2007
# ./page-types -r
flags page-count MB symbolic-flags long-symbolic-flags
0x0000000000000000 468002 1828 _________________________________
0x0000000100000000 19102 74 _____________________r___________ reserved
0x0000000000008000 41 0 _______________H_________________ compound_head
0x0000000000010000 188 0 ________________T________________ compound_tail
0x0000000000008014 1 0 __R_D__________H_________________ referenced,dirty,compound_head
0x0000000000010014 4 0 __R_D___________T________________ referenced,dirty,compound_tail
0x0000000000000020 1 0 _____l___________________________ lru
0x0000000800000024 34 0 __R__l__________________P________ referenced,lru,private
0x0000000000000028 3794 14 ___U_l___________________________ uptodate,lru
0x0001000000000028 46 0 ___U_l_______________________I___ uptodate,lru,readahead
0x0000000400000028 44 0 ___U_l_________________d_________ uptodate,lru,mappedtodisk
0x0001000400000028 2 0 ___U_l_________________d_____I___ uptodate,lru,mappedtodisk,readahead
0x000000000000002c 6434 25 __RU_l___________________________ referenced,uptodate,lru
0x000100000000002c 47 0 __RU_l_______________________I___ referenced,uptodate,lru,readahead
0x000000040000002c 14 0 __RU_l_________________d_________ referenced,uptodate,lru,mappedtodisk
0x000000080000002c 30 0 __RU_l__________________P________ referenced,uptodate,lru,private
0x0000000800000040 8124 31 ______A_________________P________ active,private
0x0000000000000040 219 0 ______A__________________________ active
0x0000000800000060 1 0 _____lA_________________P________ lru,active,private
0x0000000000000068 322 1 ___U_lA__________________________ uptodate,lru,active
0x0001000000000068 12 0 ___U_lA______________________I___ uptodate,lru,active,readahead
0x0000000400000068 13 0 ___U_lA________________d_________ uptodate,lru,active,mappedtodisk
0x0000000800000068 12 0 ___U_lA_________________P________ uptodate,lru,active,private
0x000000000000006c 977 3 __RU_lA__________________________ referenced,uptodate,lru,active
0x000100000000006c 48 0 __RU_lA______________________I___ referenced,uptodate,lru,active,readahead
0x000000040000006c 5 0 __RU_lA________________d_________ referenced,uptodate,lru,active,mappedtodisk
0x000000080000006c 3 0 __RU_lA_________________P________ referenced,uptodate,lru,active,private
0x0000000c0000006c 3 0 __RU_lA________________dP________ referenced,uptodate,lru,active,mappedtodisk,private
0x0000000c00000068 1 0 ___U_lA________________dP________ uptodate,lru,active,mappedtodisk,private
0x0000000000004078 1 0 ___UDlA_______b__________________ uptodate,dirty,lru,active,swapbacked
0x000000000000407c 34 0 __RUDlA_______b__________________ referenced,uptodate,dirty,lru,active,swapbacked
0x0000000000000400 538 2 __________B______________________ buddy
0x0000000000000804 1 0 __R________M_____________________ referenced,mmap
0x0000000000000828 1029 4 ___U_l_____M_____________________ uptodate,lru,mmap
0x0001000000000828 43 0 ___U_l_____M_________________I___ uptodate,lru,mmap,readahead
0x000000000000082c 382 1 __RU_l_____M_____________________ referenced,uptodate,lru,mmap
0x000100000000082c 12 0 __RU_l_____M_________________I___ referenced,uptodate,lru,mmap,readahead
0x0000000000000868 192 0 ___U_lA____M_____________________ uptodate,lru,active,mmap
0x0001000000000868 12 0 ___U_lA____M_________________I___ uptodate,lru,active,mmap,readahead
0x000000000000086c 800 3 __RU_lA____M_____________________ referenced,uptodate,lru,active,mmap
0x000100000000086c 31 0 __RU_lA____M_________________I___ referenced,uptodate,lru,active,mmap,readahead
0x0000000000004878 2 0 ___UDlA____M__b__________________ uptodate,dirty,lru,active,mmap,swapbacked
0x0000000000001000 492 1 ____________a____________________ anonymous
0x0000000000005008 2 0 ___U________a_b__________________ uptodate,anonymous,swapbacked
0x0000000000005808 4 0 ___U_______Ma_b__________________ uptodate,mmap,anonymous,swapbacked
0x000000000000580c 1 0 __RU_______Ma_b__________________ referenced,uptodate,mmap,anonymous,swapbacked
0x0000000000005868 2839 11 ___U_lA____Ma_b__________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x000000000000586c 29 0 __RU_lA____Ma_b__________________ referenced,uptodate,lru,active,mmap,anonymous,swapbacked
total 513968 2007
# ./page-types --raw --list --no-summary --bits reserved
offset count flags
0 15 _____________________r___________
31 4 _____________________r___________
159 97 _____________________r___________
4096 2067 _____________________r___________
6752 2390 _____________________r___________
9355 3 _____________________r___________
9728 14526 _____________________r___________
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/7] export more page flags in /proc/kpageflags (take 5)
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Matt Mackall, KOSAKI Motohiro, Wu, Fengguang, Andi Kleen, linux-mm
Andrew,
This take:
- add page-types tool for querying the exported page flags.
- export all page flags unconditionally and faithfully, and offload
complicated filtering works to the user space tool.
This patchset:
Export 10 more flags to end users (and more for kernel developers):
11. KPF_MMAP (pseudo flag) memory mapped page
12. KPF_ANON (pseudo flag) memory mapped page (anonymous)
13. KPF_SWAPCACHE page is in swap cache
14. KPF_SWAPBACKED page is swap/RAM backed
15. KPF_COMPOUND_HEAD (*)
16. KPF_COMPOUND_TAIL (*)
17. KPF_HUGE hugeTLB pages
18. KPF_UNEVICTABLE page is in the unevictable LRU list
19. KPF_HWPOISON hardware detected corruption
20. KPF_NOPAGE (pseudo flag) no page frame at the address
(*) For compound pages, exporting _both_ head/tail info enables
users to tell where a compound page starts/ends, and its order.
Patches:
[PATCH 1/7] mm: introduce PageHuge() for testing huge/gigantic pages
[PATCH 2/7] slob: use PG_slab for identifying SLOB pages
[PATCH 3/7] proc: kpagecount/kpageflags code cleanup
[PATCH 4/7] proc: export more page flags in /proc/kpageflags
[PATCH 5/7] pagemap: document clarifications
[PATCH 6/7] pagemap: document 9 more exported page flags
[PATCH 7/7] pagemap: add page-types tool
Documentation/vm/Makefile | 2
Documentation/vm/page-types.c | 696 ++++++++++++++++++++++++++++++++
Documentation/vm/pagemap.txt | 72 +++
fs/proc/page.c | 163 +++++--
include/linux/mm.h | 24 +
include/linux/page-flags.h | 2
mm/hugetlb.c | 2
mm/page_alloc.c | 11
mm/slob.c | 6
9 files changed, 933 insertions(+), 45 deletions(-)
Thanks,
Fengguang
--
PS. a simple demo of page-types
# ./page-types -h
page-types [options]
-r|--raw Raw mode, for kernel developers
-a|--addr addr-spec Walk a range of pages
-b|--bits bits-spec Walk pages with specified bits
addr-spec:
N one page at offset N (unit: pages)
N+M pages range from N to N+M-1
N,M pages range from N to M-1
N, pages range from N to end
,M pages range from 0 to M
bits-spec:
bit1,bit2 (flags & (bit1|bit2)) != 0
bit1,bit2=bit1 (flags & (bit1|bit2)) == bit1
bit1,~bit2 (flags & (bit1|bit2)) == bit1
=bit1,bit2 flags == (bit1|bit2)
bit-names:
locked error referenced uptodate
dirty lru active slab
writeback reclaim buddy mmap
anonymous swapcache swapbacked compound_head
compound_tail huge unevictable hwpoison
nopage reserved(r) mlocked(r) mappedtodisk(r)
private(r) private_2(r) owner_private(r) arch(r)
uncached(r) readahead(o) slob_free(o) slub_frozen(o)
slub_debug(o)
(r) raw mode bits (o) overloaded bits
# ./page-types
flags page-count MB symbolic-flags long-symbolic-flags
0x0000000000000000 487369 1903 _________________________________
0x0000000000000014 5 0 __R_D____________________________ referenced,dirty
0x0000000000000020 1 0 _____l___________________________ lru
0x0000000000000024 34 0 __R__l___________________________ referenced,lru
0x0000000000000028 3838 14 ___U_l___________________________ uptodate,lru
0x0001000000000028 48 0 ___U_l_______________________I___ uptodate,lru,readahead
0x000000000000002c 6478 25 __RU_l___________________________ referenced,uptodate,lru
0x000100000000002c 47 0 __RU_l_______________________I___ referenced,uptodate,lru,readahead
0x0000000000000040 8344 32 ______A__________________________ active
0x0000000000000060 1 0 _____lA__________________________ lru,active
0x0000000000000068 348 1 ___U_lA__________________________ uptodate,lru,active
0x0001000000000068 12 0 ___U_lA______________________I___ uptodate,lru,active,readahead
0x000000000000006c 988 3 __RU_lA__________________________ referenced,uptodate,lru,active
0x000100000000006c 48 0 __RU_lA______________________I___ referenced,uptodate,lru,active,readahead
0x0000000000004078 1 0 ___UDlA_______b__________________ uptodate,dirty,lru,active,swapbacked
0x000000000000407c 34 0 __RUDlA_______b__________________ referenced,uptodate,dirty,lru,active,swapbacked
0x0000000000000400 503 1 __________B______________________ buddy
0x0000000000000804 1 0 __R________M_____________________ referenced,mmap
0x0000000000000828 1029 4 ___U_l_____M_____________________ uptodate,lru,mmap
0x0001000000000828 43 0 ___U_l_____M_________________I___ uptodate,lru,mmap,readahead
0x000000000000082c 382 1 __RU_l_____M_____________________ referenced,uptodate,lru,mmap
0x000100000000082c 12 0 __RU_l_____M_________________I___ referenced,uptodate,lru,mmap,readahead
0x0000000000000868 192 0 ___U_lA____M_____________________ uptodate,lru,active,mmap
0x0001000000000868 12 0 ___U_lA____M_________________I___ uptodate,lru,active,mmap,readahead
0x000000000000086c 800 3 __RU_lA____M_____________________ referenced,uptodate,lru,active,mmap
0x000100000000086c 31 0 __RU_lA____M_________________I___ referenced,uptodate,lru,active,mmap,readahead
0x0000000000004878 2 0 ___UDlA____M__b__________________ uptodate,dirty,lru,active,mmap,swapbacked
0x0000000000001000 492 1 ____________a____________________ anonymous
0x0000000000005808 4 0 ___U_______Ma_b__________________ uptodate,mmap,anonymous,swapbacked
0x0000000000005868 2839 11 ___U_lA____Ma_b__________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x000000000000586c 30 0 __RU_lA____Ma_b__________________ referenced,uptodate,lru,active,mmap,anonymous,swapbacked
total 513968 2007
# ./page-types -r
flags page-count MB symbolic-flags long-symbolic-flags
0x0000000000000000 468002 1828 _________________________________
0x0000000100000000 19102 74 _____________________r___________ reserved
0x0000000000008000 41 0 _______________H_________________ compound_head
0x0000000000010000 188 0 ________________T________________ compound_tail
0x0000000000008014 1 0 __R_D__________H_________________ referenced,dirty,compound_head
0x0000000000010014 4 0 __R_D___________T________________ referenced,dirty,compound_tail
0x0000000000000020 1 0 _____l___________________________ lru
0x0000000800000024 34 0 __R__l__________________P________ referenced,lru,private
0x0000000000000028 3794 14 ___U_l___________________________ uptodate,lru
0x0001000000000028 46 0 ___U_l_______________________I___ uptodate,lru,readahead
0x0000000400000028 44 0 ___U_l_________________d_________ uptodate,lru,mappedtodisk
0x0001000400000028 2 0 ___U_l_________________d_____I___ uptodate,lru,mappedtodisk,readahead
0x000000000000002c 6434 25 __RU_l___________________________ referenced,uptodate,lru
0x000100000000002c 47 0 __RU_l_______________________I___ referenced,uptodate,lru,readahead
0x000000040000002c 14 0 __RU_l_________________d_________ referenced,uptodate,lru,mappedtodisk
0x000000080000002c 30 0 __RU_l__________________P________ referenced,uptodate,lru,private
0x0000000800000040 8124 31 ______A_________________P________ active,private
0x0000000000000040 219 0 ______A__________________________ active
0x0000000800000060 1 0 _____lA_________________P________ lru,active,private
0x0000000000000068 322 1 ___U_lA__________________________ uptodate,lru,active
0x0001000000000068 12 0 ___U_lA______________________I___ uptodate,lru,active,readahead
0x0000000400000068 13 0 ___U_lA________________d_________ uptodate,lru,active,mappedtodisk
0x0000000800000068 12 0 ___U_lA_________________P________ uptodate,lru,active,private
0x000000000000006c 977 3 __RU_lA__________________________ referenced,uptodate,lru,active
0x000100000000006c 48 0 __RU_lA______________________I___ referenced,uptodate,lru,active,readahead
0x000000040000006c 5 0 __RU_lA________________d_________ referenced,uptodate,lru,active,mappedtodisk
0x000000080000006c 3 0 __RU_lA_________________P________ referenced,uptodate,lru,active,private
0x0000000c0000006c 3 0 __RU_lA________________dP________ referenced,uptodate,lru,active,mappedtodisk,private
0x0000000c00000068 1 0 ___U_lA________________dP________ uptodate,lru,active,mappedtodisk,private
0x0000000000004078 1 0 ___UDlA_______b__________________ uptodate,dirty,lru,active,swapbacked
0x000000000000407c 34 0 __RUDlA_______b__________________ referenced,uptodate,dirty,lru,active,swapbacked
0x0000000000000400 538 2 __________B______________________ buddy
0x0000000000000804 1 0 __R________M_____________________ referenced,mmap
0x0000000000000828 1029 4 ___U_l_____M_____________________ uptodate,lru,mmap
0x0001000000000828 43 0 ___U_l_____M_________________I___ uptodate,lru,mmap,readahead
0x000000000000082c 382 1 __RU_l_____M_____________________ referenced,uptodate,lru,mmap
0x000100000000082c 12 0 __RU_l_____M_________________I___ referenced,uptodate,lru,mmap,readahead
0x0000000000000868 192 0 ___U_lA____M_____________________ uptodate,lru,active,mmap
0x0001000000000868 12 0 ___U_lA____M_________________I___ uptodate,lru,active,mmap,readahead
0x000000000000086c 800 3 __RU_lA____M_____________________ referenced,uptodate,lru,active,mmap
0x000100000000086c 31 0 __RU_lA____M_________________I___ referenced,uptodate,lru,active,mmap,readahead
0x0000000000004878 2 0 ___UDlA____M__b__________________ uptodate,dirty,lru,active,mmap,swapbacked
0x0000000000001000 492 1 ____________a____________________ anonymous
0x0000000000005008 2 0 ___U________a_b__________________ uptodate,anonymous,swapbacked
0x0000000000005808 4 0 ___U_______Ma_b__________________ uptodate,mmap,anonymous,swapbacked
0x000000000000580c 1 0 __RU_______Ma_b__________________ referenced,uptodate,mmap,anonymous,swapbacked
0x0000000000005868 2839 11 ___U_lA____Ma_b__________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x000000000000586c 29 0 __RU_lA____Ma_b__________________ referenced,uptodate,lru,active,mmap,anonymous,swapbacked
total 513968 2007
# ./page-types --raw --list --no-summary --bits reserved
offset count flags
0 15 _____________________r___________
31 4 _____________________r___________
159 97 _____________________r___________
4096 2067 _____________________r___________
6752 2390 _____________________r___________
9355 3 _____________________r___________
9728 14526 _____________________r___________
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/7] mm: introduce PageHuge() for testing huge/gigantic pages
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 1:21 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: giga-page.patch --]
[-- Type: text/plain, Size: 2130 bytes --]
Introduce PageHuge(), which identifies huge/gigantic pages
by their dedicated compound destructor functions.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
include/linux/mm.h | 24 ++++++++++++++++++++++++
mm/hugetlb.c | 2 +-
mm/page_alloc.c | 11 ++++++++++-
3 files changed, 35 insertions(+), 2 deletions(-)
--- linux.orig/mm/page_alloc.c
+++ linux/mm/page_alloc.c
@@ -299,13 +299,22 @@ void prep_compound_page(struct page *pag
}
#ifdef CONFIG_HUGETLBFS
+/*
+ * This (duplicated) destructor function distinguishes gigantic pages from
+ * normal compound pages.
+ */
+void free_gigantic_page(struct page *page)
+{
+ __free_pages_ok(page, compound_order(page));
+}
+
void prep_compound_gigantic_page(struct page *page, unsigned long order)
{
int i;
int nr_pages = 1 << order;
struct page *p = page + 1;
- set_compound_page_dtor(page, free_compound_page);
+ set_compound_page_dtor(page, free_gigantic_page);
set_compound_order(page, order);
__SetPageHead(page);
for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
--- linux.orig/mm/hugetlb.c
+++ linux/mm/hugetlb.c
@@ -550,7 +550,7 @@ struct hstate *size_to_hstate(unsigned l
return NULL;
}
-static void free_huge_page(struct page *page)
+void free_huge_page(struct page *page)
{
/*
* Can't pass hstate in here because it is called from the
--- linux.orig/include/linux/mm.h
+++ linux/include/linux/mm.h
@@ -355,6 +355,30 @@ static inline void set_compound_order(st
page[1].lru.prev = (void *)order;
}
+#ifdef CONFIG_HUGETLBFS
+void free_huge_page(struct page *page);
+void free_gigantic_page(struct page *page);
+
+static inline int PageHuge(struct page *page)
+{
+ compound_page_dtor *dtor;
+
+ if (!PageCompound(page))
+ return 0;
+
+ page = compound_head(page);
+ dtor = get_compound_page_dtor(page);
+
+ return dtor == free_huge_page ||
+ dtor == free_gigantic_page;
+}
+#else
+static inline int PageHuge(struct page *page)
+{
+ return 0;
+}
+#endif
+
/*
* Multiple processes may "see" the same page. E.g. for untouched
* mappings of /dev/null, all processes see the same page full of
--
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/7] mm: introduce PageHuge() for testing huge/gigantic pages
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: giga-page.patch --]
[-- Type: text/plain, Size: 2355 bytes --]
Introduce PageHuge(), which identifies huge/gigantic pages
by their dedicated compound destructor functions.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
include/linux/mm.h | 24 ++++++++++++++++++++++++
mm/hugetlb.c | 2 +-
mm/page_alloc.c | 11 ++++++++++-
3 files changed, 35 insertions(+), 2 deletions(-)
--- linux.orig/mm/page_alloc.c
+++ linux/mm/page_alloc.c
@@ -299,13 +299,22 @@ void prep_compound_page(struct page *pag
}
#ifdef CONFIG_HUGETLBFS
+/*
+ * This (duplicated) destructor function distinguishes gigantic pages from
+ * normal compound pages.
+ */
+void free_gigantic_page(struct page *page)
+{
+ __free_pages_ok(page, compound_order(page));
+}
+
void prep_compound_gigantic_page(struct page *page, unsigned long order)
{
int i;
int nr_pages = 1 << order;
struct page *p = page + 1;
- set_compound_page_dtor(page, free_compound_page);
+ set_compound_page_dtor(page, free_gigantic_page);
set_compound_order(page, order);
__SetPageHead(page);
for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
--- linux.orig/mm/hugetlb.c
+++ linux/mm/hugetlb.c
@@ -550,7 +550,7 @@ struct hstate *size_to_hstate(unsigned l
return NULL;
}
-static void free_huge_page(struct page *page)
+void free_huge_page(struct page *page)
{
/*
* Can't pass hstate in here because it is called from the
--- linux.orig/include/linux/mm.h
+++ linux/include/linux/mm.h
@@ -355,6 +355,30 @@ static inline void set_compound_order(st
page[1].lru.prev = (void *)order;
}
+#ifdef CONFIG_HUGETLBFS
+void free_huge_page(struct page *page);
+void free_gigantic_page(struct page *page);
+
+static inline int PageHuge(struct page *page)
+{
+ compound_page_dtor *dtor;
+
+ if (!PageCompound(page))
+ return 0;
+
+ page = compound_head(page);
+ dtor = get_compound_page_dtor(page);
+
+ return dtor == free_huge_page ||
+ dtor == free_gigantic_page;
+}
+#else
+static inline int PageHuge(struct page *page)
+{
+ return 0;
+}
+#endif
+
/*
* Multiple processes may "see" the same page. E.g. for untouched
* mappings of /dev/null, all processes see the same page full of
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 2/7] slob: use PG_slab for identifying SLOB pages
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 1:21 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Matt Mackall, Wu Fengguang, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: mm-slob-page-flag.patch --]
[-- Type: text/plain, Size: 1394 bytes --]
For the sake of consistency.
Cc: Matt Mackall <mpm@selenic.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
include/linux/page-flags.h | 2 --
mm/slob.c | 6 +++---
2 files changed, 3 insertions(+), 5 deletions(-)
--- linux.orig/include/linux/page-flags.h
+++ linux/include/linux/page-flags.h
@@ -120,7 +120,6 @@ enum pageflags {
PG_savepinned = PG_dirty,
/* SLOB */
- PG_slob_page = PG_active,
PG_slob_free = PG_private,
/* SLUB */
@@ -203,7 +202,6 @@ PAGEFLAG(SavePinned, savepinned); /* X
PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
-__PAGEFLAG(SlobPage, slob_page)
__PAGEFLAG(SlobFree, slob_free)
__PAGEFLAG(SlubFrozen, slub_frozen)
--- linux.orig/mm/slob.c
+++ linux/mm/slob.c
@@ -132,17 +132,17 @@ static LIST_HEAD(free_slob_large);
*/
static inline int is_slob_page(struct slob_page *sp)
{
- return PageSlobPage((struct page *)sp);
+ return PageSlab((struct page *)sp);
}
static inline void set_slob_page(struct slob_page *sp)
{
- __SetPageSlobPage((struct page *)sp);
+ __SetPageSlab((struct page *)sp);
}
static inline void clear_slob_page(struct slob_page *sp)
{
- __ClearPageSlobPage((struct page *)sp);
+ __ClearPageSlab((struct page *)sp);
}
static inline struct slob_page *slob_page(const void *addr)
--
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 2/7] slob: use PG_slab for identifying SLOB pages
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Matt Mackall, Wu Fengguang, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: mm-slob-page-flag.patch --]
[-- Type: text/plain, Size: 1619 bytes --]
For the sake of consistency.
Cc: Matt Mackall <mpm@selenic.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
include/linux/page-flags.h | 2 --
mm/slob.c | 6 +++---
2 files changed, 3 insertions(+), 5 deletions(-)
--- linux.orig/include/linux/page-flags.h
+++ linux/include/linux/page-flags.h
@@ -120,7 +120,6 @@ enum pageflags {
PG_savepinned = PG_dirty,
/* SLOB */
- PG_slob_page = PG_active,
PG_slob_free = PG_private,
/* SLUB */
@@ -203,7 +202,6 @@ PAGEFLAG(SavePinned, savepinned); /* X
PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
-__PAGEFLAG(SlobPage, slob_page)
__PAGEFLAG(SlobFree, slob_free)
__PAGEFLAG(SlubFrozen, slub_frozen)
--- linux.orig/mm/slob.c
+++ linux/mm/slob.c
@@ -132,17 +132,17 @@ static LIST_HEAD(free_slob_large);
*/
static inline int is_slob_page(struct slob_page *sp)
{
- return PageSlobPage((struct page *)sp);
+ return PageSlab((struct page *)sp);
}
static inline void set_slob_page(struct slob_page *sp)
{
- __SetPageSlobPage((struct page *)sp);
+ __SetPageSlab((struct page *)sp);
}
static inline void clear_slob_page(struct slob_page *sp)
{
- __ClearPageSlobPage((struct page *)sp);
+ __ClearPageSlab((struct page *)sp);
}
static inline struct slob_page *slob_page(const void *addr)
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 3/7] proc: kpagecount/kpageflags code cleanup
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 1:21 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: kpageflags-fix-out.patch --]
[-- Type: text/plain, Size: 1455 bytes --]
Move increments of pfn/out to bottom of the loop.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
fs/proc/page.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
--- linux.orig/fs/proc/page.c
+++ linux/fs/proc/page.c
@@ -11,6 +11,7 @@
#define KPMSIZE sizeof(u64)
#define KPMMASK (KPMSIZE - 1)
+
/* /proc/kpagecount - an array exposing page counts
*
* Each entry is a u64 representing the corresponding
@@ -32,20 +33,22 @@ static ssize_t kpagecount_read(struct fi
return -EINVAL;
while (count > 0) {
- ppage = NULL;
if (pfn_valid(pfn))
ppage = pfn_to_page(pfn);
- pfn++;
+ else
+ ppage = NULL;
if (!ppage)
pcount = 0;
else
pcount = page_mapcount(ppage);
- if (put_user(pcount, out++)) {
+ if (put_user(pcount, out)) {
ret = -EFAULT;
break;
}
+ pfn++;
+ out++;
count -= KPMSIZE;
}
@@ -98,10 +101,10 @@ static ssize_t kpageflags_read(struct fi
return -EINVAL;
while (count > 0) {
- ppage = NULL;
if (pfn_valid(pfn))
ppage = pfn_to_page(pfn);
- pfn++;
+ else
+ ppage = NULL;
if (!ppage)
kflags = 0;
else
@@ -119,11 +122,13 @@ static ssize_t kpageflags_read(struct fi
kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
- if (put_user(uflags, out++)) {
+ if (put_user(uflags, out)) {
ret = -EFAULT;
break;
}
+ pfn++;
+ out++;
count -= KPMSIZE;
}
--
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 3/7] proc: kpagecount/kpageflags code cleanup
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: kpageflags-fix-out.patch --]
[-- Type: text/plain, Size: 1680 bytes --]
Move increments of pfn/out to bottom of the loop.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
fs/proc/page.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
--- linux.orig/fs/proc/page.c
+++ linux/fs/proc/page.c
@@ -11,6 +11,7 @@
#define KPMSIZE sizeof(u64)
#define KPMMASK (KPMSIZE - 1)
+
/* /proc/kpagecount - an array exposing page counts
*
* Each entry is a u64 representing the corresponding
@@ -32,20 +33,22 @@ static ssize_t kpagecount_read(struct fi
return -EINVAL;
while (count > 0) {
- ppage = NULL;
if (pfn_valid(pfn))
ppage = pfn_to_page(pfn);
- pfn++;
+ else
+ ppage = NULL;
if (!ppage)
pcount = 0;
else
pcount = page_mapcount(ppage);
- if (put_user(pcount, out++)) {
+ if (put_user(pcount, out)) {
ret = -EFAULT;
break;
}
+ pfn++;
+ out++;
count -= KPMSIZE;
}
@@ -98,10 +101,10 @@ static ssize_t kpageflags_read(struct fi
return -EINVAL;
while (count > 0) {
- ppage = NULL;
if (pfn_valid(pfn))
ppage = pfn_to_page(pfn);
- pfn++;
+ else
+ ppage = NULL;
if (!ppage)
kflags = 0;
else
@@ -119,11 +122,13 @@ static ssize_t kpageflags_read(struct fi
kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
- if (put_user(uflags, out++)) {
+ if (put_user(uflags, out)) {
ret = -EFAULT;
break;
}
+ pfn++;
+ out++;
count -= KPMSIZE;
}
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 1:21 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall, Alexey Dobriyan,
Wu Fengguang, linux-mm
[-- Attachment #1: kpageflags-extending.patch --]
[-- Type: text/plain, Size: 6191 bytes --]
Export all page flags faithfully in /proc/kpageflags.
11. KPF_MMAP (pseudo flag) memory mapped page
12. KPF_ANON (pseudo flag) memory mapped page (anonymous)
13. KPF_SWAPCACHE page is in swap cache
14. KPF_SWAPBACKED page is swap/RAM backed
15. KPF_COMPOUND_HEAD (*)
16. KPF_COMPOUND_TAIL (*)
17. KPF_HUGE hugeTLB pages
18. KPF_UNEVICTABLE page is in the unevictable LRU list
19. KPF_HWPOISON hardware detected corruption
20. KPF_NOPAGE (pseudo flag) no page frame at the address
32-39. more obscure flags for kernel developers
(*) For compound pages, exporting _both_ head/tail info enables
users to tell where a compound page starts/ends, and its order.
The acompanied page-types tool will handle the details like decoupling
overloaded flags and hiding obscure flags to normal users.
Thanks to KOSAKI and Andi for their valuable recommendations!
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
fs/proc/page.c | 150 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 120 insertions(+), 30 deletions(-)
--- linux.orig/fs/proc/page.c
+++ linux/fs/proc/page.c
@@ -71,19 +71,126 @@ static const struct file_operations proc
/* These macros are used to decouple internal flags from exported ones */
-#define KPF_LOCKED 0
-#define KPF_ERROR 1
-#define KPF_REFERENCED 2
-#define KPF_UPTODATE 3
-#define KPF_DIRTY 4
-#define KPF_LRU 5
-#define KPF_ACTIVE 6
-#define KPF_SLAB 7
-#define KPF_WRITEBACK 8
-#define KPF_RECLAIM 9
-#define KPF_BUDDY 10
+#define KPF_LOCKED 0
+#define KPF_ERROR 1
+#define KPF_REFERENCED 2
+#define KPF_UPTODATE 3
+#define KPF_DIRTY 4
+#define KPF_LRU 5
+#define KPF_ACTIVE 6
+#define KPF_SLAB 7
+#define KPF_WRITEBACK 8
+#define KPF_RECLAIM 9
+#define KPF_BUDDY 10
+
+/* 11-20: new additions in 2.6.31 */
+#define KPF_MMAP 11
+#define KPF_ANON 12
+#define KPF_SWAPCACHE 13
+#define KPF_SWAPBACKED 14
+#define KPF_COMPOUND_HEAD 15
+#define KPF_COMPOUND_TAIL 16
+#define KPF_HUGE 17
+#define KPF_UNEVICTABLE 18
+#define KPF_HWPOISON 19
+#define KPF_NOPAGE 20
+
+/* kernel hacking assistances
+ * WARNING: subject to change, never rely on them!
+ */
+#define KPF_RESERVED 32
+#define KPF_MLOCKED 33
+#define KPF_MAPPEDTODISK 34
+#define KPF_PRIVATE 35
+#define KPF_PRIVATE_2 36
+#define KPF_OWNER_PRIVATE 37
+#define KPF_ARCH 38
+#define KPF_UNCACHED 39
-#define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos)
+static inline u64 kpf_copy_bit(u64 kflags, int ubit, int kbit)
+{
+ return ((kflags >> kbit) & 1) << ubit;
+}
+
+static u64 get_uflags(struct page *page)
+{
+ u64 k;
+ u64 u;
+
+ /*
+ * pseudo flag: KPF_NOPAGE
+ * it differentiates a memory hole from a page with no flags
+ */
+ if (!page)
+ return 1 << KPF_NOPAGE;
+
+ k = page->flags;
+ u = 0;
+
+ /*
+ * pseudo flags for the well known (anonymous) memory mapped pages
+ */
+ if (!PageSlab(page) && page_mapped(page))
+ u |= 1 << KPF_MMAP;
+ if (PageAnon(page))
+ u |= 1 << KPF_ANON;
+
+ /*
+ * compound pages: export both head/tail info
+ * they together define a compound page's start/end pos and order
+ */
+ if (PageHead(page))
+ u |= 1 << KPF_COMPOUND_HEAD;
+ if (PageTail(page))
+ u |= 1 << KPF_COMPOUND_TAIL;
+ if (PageHuge(page))
+ u |= 1 << KPF_HUGE;
+
+ u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked);
+
+ /*
+ * Caveats on high order pages:
+ * PG_buddy will only be set on the head page; SLUB/SLQB do the same
+ * for PG_slab; SLOB won't set PG_slab at all on compound pages.
+ */
+ u |= kpf_copy_bit(k, KPF_SLAB, PG_slab);
+ u |= kpf_copy_bit(k, KPF_BUDDY, PG_buddy);
+
+ u |= kpf_copy_bit(k, KPF_ERROR, PG_error);
+ u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty);
+ u |= kpf_copy_bit(k, KPF_UPTODATE, PG_uptodate);
+ u |= kpf_copy_bit(k, KPF_WRITEBACK, PG_writeback);
+
+ u |= kpf_copy_bit(k, KPF_LRU, PG_lru);
+ u |= kpf_copy_bit(k, KPF_REFERENCED, PG_referenced);
+ u |= kpf_copy_bit(k, KPF_ACTIVE, PG_active);
+ u |= kpf_copy_bit(k, KPF_RECLAIM, PG_reclaim);
+
+ u |= kpf_copy_bit(k, KPF_SWAPCACHE, PG_swapcache);
+ u |= kpf_copy_bit(k, KPF_SWAPBACKED, PG_swapbacked);
+
+#ifdef CONFIG_MEMORY_FAILURE
+ u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
+#endif
+
+#ifdef CONFIG_UNEVICTABLE_LRU
+ u |= kpf_copy_bit(k, KPF_UNEVICTABLE, PG_unevictable);
+ u |= kpf_copy_bit(k, KPF_MLOCKED, PG_mlocked);
+#endif
+
+#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
+ u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached);
+#endif
+
+ u |= kpf_copy_bit(k, KPF_RESERVED, PG_reserved);
+ u |= kpf_copy_bit(k, KPF_MAPPEDTODISK, PG_mappedtodisk);
+ u |= kpf_copy_bit(k, KPF_PRIVATE, PG_private);
+ u |= kpf_copy_bit(k, KPF_PRIVATE_2, PG_private_2);
+ u |= kpf_copy_bit(k, KPF_OWNER_PRIVATE, PG_owner_priv_1);
+ u |= kpf_copy_bit(k, KPF_ARCH, PG_arch_1);
+
+ return u;
+};
static ssize_t kpageflags_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
@@ -93,7 +200,6 @@ static ssize_t kpageflags_read(struct fi
unsigned long src = *ppos;
unsigned long pfn;
ssize_t ret = 0;
- u64 kflags, uflags;
pfn = src / KPMSIZE;
count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
@@ -105,24 +211,8 @@ static ssize_t kpageflags_read(struct fi
ppage = pfn_to_page(pfn);
else
ppage = NULL;
- if (!ppage)
- kflags = 0;
- else
- kflags = ppage->flags;
-
- uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) |
- kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
- kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
- kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
- kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
- kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
- kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
- kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
- kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
- kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
- kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
- if (put_user(uflags, out)) {
+ if (put_user(get_uflags(ppage), out)) {
ret = -EFAULT;
break;
}
--
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall, Alexey Dobriyan,
Wu Fengguang, linux-mm
[-- Attachment #1: kpageflags-extending.patch --]
[-- Type: text/plain, Size: 6416 bytes --]
Export all page flags faithfully in /proc/kpageflags.
11. KPF_MMAP (pseudo flag) memory mapped page
12. KPF_ANON (pseudo flag) memory mapped page (anonymous)
13. KPF_SWAPCACHE page is in swap cache
14. KPF_SWAPBACKED page is swap/RAM backed
15. KPF_COMPOUND_HEAD (*)
16. KPF_COMPOUND_TAIL (*)
17. KPF_HUGE hugeTLB pages
18. KPF_UNEVICTABLE page is in the unevictable LRU list
19. KPF_HWPOISON hardware detected corruption
20. KPF_NOPAGE (pseudo flag) no page frame at the address
32-39. more obscure flags for kernel developers
(*) For compound pages, exporting _both_ head/tail info enables
users to tell where a compound page starts/ends, and its order.
The acompanied page-types tool will handle the details like decoupling
overloaded flags and hiding obscure flags to normal users.
Thanks to KOSAKI and Andi for their valuable recommendations!
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
fs/proc/page.c | 150 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 120 insertions(+), 30 deletions(-)
--- linux.orig/fs/proc/page.c
+++ linux/fs/proc/page.c
@@ -71,19 +71,126 @@ static const struct file_operations proc
/* These macros are used to decouple internal flags from exported ones */
-#define KPF_LOCKED 0
-#define KPF_ERROR 1
-#define KPF_REFERENCED 2
-#define KPF_UPTODATE 3
-#define KPF_DIRTY 4
-#define KPF_LRU 5
-#define KPF_ACTIVE 6
-#define KPF_SLAB 7
-#define KPF_WRITEBACK 8
-#define KPF_RECLAIM 9
-#define KPF_BUDDY 10
+#define KPF_LOCKED 0
+#define KPF_ERROR 1
+#define KPF_REFERENCED 2
+#define KPF_UPTODATE 3
+#define KPF_DIRTY 4
+#define KPF_LRU 5
+#define KPF_ACTIVE 6
+#define KPF_SLAB 7
+#define KPF_WRITEBACK 8
+#define KPF_RECLAIM 9
+#define KPF_BUDDY 10
+
+/* 11-20: new additions in 2.6.31 */
+#define KPF_MMAP 11
+#define KPF_ANON 12
+#define KPF_SWAPCACHE 13
+#define KPF_SWAPBACKED 14
+#define KPF_COMPOUND_HEAD 15
+#define KPF_COMPOUND_TAIL 16
+#define KPF_HUGE 17
+#define KPF_UNEVICTABLE 18
+#define KPF_HWPOISON 19
+#define KPF_NOPAGE 20
+
+/* kernel hacking assistances
+ * WARNING: subject to change, never rely on them!
+ */
+#define KPF_RESERVED 32
+#define KPF_MLOCKED 33
+#define KPF_MAPPEDTODISK 34
+#define KPF_PRIVATE 35
+#define KPF_PRIVATE_2 36
+#define KPF_OWNER_PRIVATE 37
+#define KPF_ARCH 38
+#define KPF_UNCACHED 39
-#define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos)
+static inline u64 kpf_copy_bit(u64 kflags, int ubit, int kbit)
+{
+ return ((kflags >> kbit) & 1) << ubit;
+}
+
+static u64 get_uflags(struct page *page)
+{
+ u64 k;
+ u64 u;
+
+ /*
+ * pseudo flag: KPF_NOPAGE
+ * it differentiates a memory hole from a page with no flags
+ */
+ if (!page)
+ return 1 << KPF_NOPAGE;
+
+ k = page->flags;
+ u = 0;
+
+ /*
+ * pseudo flags for the well known (anonymous) memory mapped pages
+ */
+ if (!PageSlab(page) && page_mapped(page))
+ u |= 1 << KPF_MMAP;
+ if (PageAnon(page))
+ u |= 1 << KPF_ANON;
+
+ /*
+ * compound pages: export both head/tail info
+ * they together define a compound page's start/end pos and order
+ */
+ if (PageHead(page))
+ u |= 1 << KPF_COMPOUND_HEAD;
+ if (PageTail(page))
+ u |= 1 << KPF_COMPOUND_TAIL;
+ if (PageHuge(page))
+ u |= 1 << KPF_HUGE;
+
+ u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked);
+
+ /*
+ * Caveats on high order pages:
+ * PG_buddy will only be set on the head page; SLUB/SLQB do the same
+ * for PG_slab; SLOB won't set PG_slab at all on compound pages.
+ */
+ u |= kpf_copy_bit(k, KPF_SLAB, PG_slab);
+ u |= kpf_copy_bit(k, KPF_BUDDY, PG_buddy);
+
+ u |= kpf_copy_bit(k, KPF_ERROR, PG_error);
+ u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty);
+ u |= kpf_copy_bit(k, KPF_UPTODATE, PG_uptodate);
+ u |= kpf_copy_bit(k, KPF_WRITEBACK, PG_writeback);
+
+ u |= kpf_copy_bit(k, KPF_LRU, PG_lru);
+ u |= kpf_copy_bit(k, KPF_REFERENCED, PG_referenced);
+ u |= kpf_copy_bit(k, KPF_ACTIVE, PG_active);
+ u |= kpf_copy_bit(k, KPF_RECLAIM, PG_reclaim);
+
+ u |= kpf_copy_bit(k, KPF_SWAPCACHE, PG_swapcache);
+ u |= kpf_copy_bit(k, KPF_SWAPBACKED, PG_swapbacked);
+
+#ifdef CONFIG_MEMORY_FAILURE
+ u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
+#endif
+
+#ifdef CONFIG_UNEVICTABLE_LRU
+ u |= kpf_copy_bit(k, KPF_UNEVICTABLE, PG_unevictable);
+ u |= kpf_copy_bit(k, KPF_MLOCKED, PG_mlocked);
+#endif
+
+#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
+ u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached);
+#endif
+
+ u |= kpf_copy_bit(k, KPF_RESERVED, PG_reserved);
+ u |= kpf_copy_bit(k, KPF_MAPPEDTODISK, PG_mappedtodisk);
+ u |= kpf_copy_bit(k, KPF_PRIVATE, PG_private);
+ u |= kpf_copy_bit(k, KPF_PRIVATE_2, PG_private_2);
+ u |= kpf_copy_bit(k, KPF_OWNER_PRIVATE, PG_owner_priv_1);
+ u |= kpf_copy_bit(k, KPF_ARCH, PG_arch_1);
+
+ return u;
+};
static ssize_t kpageflags_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
@@ -93,7 +200,6 @@ static ssize_t kpageflags_read(struct fi
unsigned long src = *ppos;
unsigned long pfn;
ssize_t ret = 0;
- u64 kflags, uflags;
pfn = src / KPMSIZE;
count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
@@ -105,24 +211,8 @@ static ssize_t kpageflags_read(struct fi
ppage = pfn_to_page(pfn);
else
ppage = NULL;
- if (!ppage)
- kflags = 0;
- else
- kflags = ppage->flags;
-
- uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) |
- kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
- kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
- kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
- kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
- kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
- kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
- kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
- kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
- kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
- kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
- if (put_user(uflags, out)) {
+ if (put_user(get_uflags(ppage), out)) {
ret = -EFAULT;
break;
}
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 5/7] pagemap: document clarifications
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 1:21 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: kpageflags-doc-fix.patch --]
[-- Type: text/plain, Size: 1177 bytes --]
Some bit ranges were inclusive and some not.
Fix them to be consistently inclusive.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
Documentation/vm/pagemap.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- linux.orig/Documentation/vm/pagemap.txt
+++ linux/Documentation/vm/pagemap.txt
@@ -12,9 +12,9 @@ There are three components to pagemap:
value for each virtual page, containing the following data (from
fs/proc/task_mmu.c, above pagemap_read):
- * Bits 0-55 page frame number (PFN) if present
+ * Bits 0-54 page frame number (PFN) if present
* Bits 0-4 swap type if swapped
- * Bits 5-55 swap offset if swapped
+ * Bits 5-54 swap offset if swapped
* Bits 55-60 page shift (page size = 1<<page shift)
* Bit 61 reserved for future use
* Bit 62 page swapped
@@ -36,7 +36,7 @@ There are three components to pagemap:
* /proc/kpageflags. This file contains a 64-bit set of flags for each
page, indexed by PFN.
- The flags are (from fs/proc/proc_misc, above kpageflags_read):
+ The flags are (from fs/proc/page.c, above kpageflags_read):
0. LOCKED
1. ERROR
--
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 5/7] pagemap: document clarifications
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: kpageflags-doc-fix.patch --]
[-- Type: text/plain, Size: 1402 bytes --]
Some bit ranges were inclusive and some not.
Fix them to be consistently inclusive.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
Documentation/vm/pagemap.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- linux.orig/Documentation/vm/pagemap.txt
+++ linux/Documentation/vm/pagemap.txt
@@ -12,9 +12,9 @@ There are three components to pagemap:
value for each virtual page, containing the following data (from
fs/proc/task_mmu.c, above pagemap_read):
- * Bits 0-55 page frame number (PFN) if present
+ * Bits 0-54 page frame number (PFN) if present
* Bits 0-4 swap type if swapped
- * Bits 5-55 swap offset if swapped
+ * Bits 5-54 swap offset if swapped
* Bits 55-60 page shift (page size = 1<<page shift)
* Bit 61 reserved for future use
* Bit 62 page swapped
@@ -36,7 +36,7 @@ There are three components to pagemap:
* /proc/kpageflags. This file contains a 64-bit set of flags for each
page, indexed by PFN.
- The flags are (from fs/proc/proc_misc, above kpageflags_read):
+ The flags are (from fs/proc/page.c, above kpageflags_read):
0. LOCKED
1. ERROR
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 6/7] pagemap: document 9 more exported page flags
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 1:21 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: kpageflags-doc.patch --]
[-- Type: text/plain, Size: 3145 bytes --]
Also add short descriptions for all of the 20 exported page flags.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
Documentation/vm/pagemap.txt | 66 +++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
--- linux.orig/Documentation/vm/pagemap.txt
+++ linux/Documentation/vm/pagemap.txt
@@ -49,6 +49,72 @@ There are three components to pagemap:
8. WRITEBACK
9. RECLAIM
10. BUDDY
+ 11. MMAP
+ 12. ANON
+ 13. SWAPCACHE
+ 14. SWAPBACKED
+ 15. COMPOUND_HEAD
+ 16. COMPOUND_TAIL
+ 16. HUGE
+ 18. UNEVICTABLE
+ 19. HWPOISON
+ 20. NOPAGE
+
+Short descriptions to the page flags:
+
+ 0. LOCKED
+ page is being locked for exclusive access, eg. by undergoing read/write IO
+
+ 7. SLAB
+ page is managed by the SLAB/SLOB/SLUB/SLQB kernel memory allocator
+ When compound page is used, SLUB/SLQB will only set this flag on the head
+ page; SLOB will not flag it at all.
+
+10. BUDDY
+ a free memory block managed by the buddy system allocator
+ The buddy system organizes free memory in blocks of various orders.
+ An order N block has 2^N physically contiguous pages, with the BUDDY flag
+ set for and _only_ for the first page.
+
+15. COMPOUND_HEAD
+16. COMPOUND_TAIL
+ A compound page with order N consists of 2^N physically contiguous pages.
+ A compound page with order 2 takes the form of "HTTT", where H donates its
+ head page and T donates its tail page(s). The major consumers of compound
+ pages are hugeTLB pages (Documentation/vm/hugetlbpage.txt), the SLUB etc.
+ memory allocators and various device drivers. However in this interface,
+ only huge/giga pages are made visible to end users.
+17. HUGE
+ this is an integral part of a HugeTLB page
+
+19. HWPOISON
+ hardware detected memory corruption on this page: don't touch the data!
+
+20. NOPAGE
+ no page frame exists at the requested address
+
+ [IO related page flags]
+ 1. ERROR IO error occurred
+ 3. UPTODATE page has up-to-date data
+ ie. for file backed page: (in-memory data revision >= on-disk one)
+ 4. DIRTY page has been written to, hence contains new data
+ ie. for file backed page: (in-memory data revision > on-disk one)
+ 8. WRITEBACK page is being synced to disk
+
+ [LRU related page flags]
+ 5. LRU page is in one of the LRU lists
+ 6. ACTIVE page is in the active LRU list
+18. UNEVICTABLE page is in the unevictable (non-)LRU list
+ It is somehow pinned and not a candidate for LRU page reclaims,
+ eg. ramfs pages, shmctl(SHM_LOCK) and mlock() memory segments
+ 2. REFERENCED page has been referenced since last LRU list enqueue/requeue
+ 9. RECLAIM page will be reclaimed soon after its pageout IO completed
+11. MMAP a memory mapped page
+12. ANON a memory mapped page that is not part of a file
+13. SWAPCACHE page is mapped to swap space, ie. has an associated swap entry
+14. SWAPBACKED page is backed by swap/RAM
+
+The page-types tool in this directory can be used to query the above flags.
Using pagemap to do something useful:
--
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 6/7] pagemap: document 9 more exported page flags
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, Andi Kleen, linux-mm
[-- Attachment #1: kpageflags-doc.patch --]
[-- Type: text/plain, Size: 3370 bytes --]
Also add short descriptions for all of the 20 exported page flags.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
Documentation/vm/pagemap.txt | 66 +++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
--- linux.orig/Documentation/vm/pagemap.txt
+++ linux/Documentation/vm/pagemap.txt
@@ -49,6 +49,72 @@ There are three components to pagemap:
8. WRITEBACK
9. RECLAIM
10. BUDDY
+ 11. MMAP
+ 12. ANON
+ 13. SWAPCACHE
+ 14. SWAPBACKED
+ 15. COMPOUND_HEAD
+ 16. COMPOUND_TAIL
+ 16. HUGE
+ 18. UNEVICTABLE
+ 19. HWPOISON
+ 20. NOPAGE
+
+Short descriptions to the page flags:
+
+ 0. LOCKED
+ page is being locked for exclusive access, eg. by undergoing read/write IO
+
+ 7. SLAB
+ page is managed by the SLAB/SLOB/SLUB/SLQB kernel memory allocator
+ When compound page is used, SLUB/SLQB will only set this flag on the head
+ page; SLOB will not flag it at all.
+
+10. BUDDY
+ a free memory block managed by the buddy system allocator
+ The buddy system organizes free memory in blocks of various orders.
+ An order N block has 2^N physically contiguous pages, with the BUDDY flag
+ set for and _only_ for the first page.
+
+15. COMPOUND_HEAD
+16. COMPOUND_TAIL
+ A compound page with order N consists of 2^N physically contiguous pages.
+ A compound page with order 2 takes the form of "HTTT", where H donates its
+ head page and T donates its tail page(s). The major consumers of compound
+ pages are hugeTLB pages (Documentation/vm/hugetlbpage.txt), the SLUB etc.
+ memory allocators and various device drivers. However in this interface,
+ only huge/giga pages are made visible to end users.
+17. HUGE
+ this is an integral part of a HugeTLB page
+
+19. HWPOISON
+ hardware detected memory corruption on this page: don't touch the data!
+
+20. NOPAGE
+ no page frame exists at the requested address
+
+ [IO related page flags]
+ 1. ERROR IO error occurred
+ 3. UPTODATE page has up-to-date data
+ ie. for file backed page: (in-memory data revision >= on-disk one)
+ 4. DIRTY page has been written to, hence contains new data
+ ie. for file backed page: (in-memory data revision > on-disk one)
+ 8. WRITEBACK page is being synced to disk
+
+ [LRU related page flags]
+ 5. LRU page is in one of the LRU lists
+ 6. ACTIVE page is in the active LRU list
+18. UNEVICTABLE page is in the unevictable (non-)LRU list
+ It is somehow pinned and not a candidate for LRU page reclaims,
+ eg. ramfs pages, shmctl(SHM_LOCK) and mlock() memory segments
+ 2. REFERENCED page has been referenced since last LRU list enqueue/requeue
+ 9. RECLAIM page will be reclaimed soon after its pageout IO completed
+11. MMAP a memory mapped page
+12. ANON a memory mapped page that is not part of a file
+13. SWAPCACHE page is mapped to swap space, ie. has an associated swap entry
+14. SWAPBACKED page is backed by swap/RAM
+
+The page-types tool in this directory can be used to query the above flags.
Using pagemap to do something useful:
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 7/7] pagemap: add page-types tool
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 1:21 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Andi Kleen, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, linux-mm
[-- Attachment #1: page-types.patch --]
[-- Type: text/plain, Size: 16103 bytes --]
Add page-types, a handy tool for querying page flags.
It will expand some of the overloaded flags:
PG_slob_free = PG_private
PG_slub_frozen = PG_active
PG_slub_debug = PG_error
PG_readahead = PG_reclaim
and mask out obscure flags except in -raw mode:
PG_reserved
PG_mlocked
PG_mappedtodisk
PG_private
PG_private_2
PG_owner_priv_1
PG_arch_1
PG_uncached
PG_compound* for non hugeTLB pages
CC: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
Documentation/vm/Makefile | 2
Documentation/vm/page-types.c | 696 ++++++++++++++++++++++++++++++++
2 files changed, 697 insertions(+), 1 deletion(-)
--- /dev/null
+++ linux/Documentation/vm/page-types.c
@@ -0,0 +1,696 @@
+/*
+ * page-types: Tool for querying page flags
+ *
+ * Copyright (C) 2009 Intel corporation
+ * Copyright (C) 2009 Wu Fengguang <fengguang.wu@intel.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <getopt.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+
+
+/*
+ * kernel page flags
+ */
+
+#define KPF_BYTES 8
+#define PROC_KPAGEFLAGS "/proc/kpageflags"
+
+/* copied from kpageflags_read() */
+#define KPF_LOCKED 0
+#define KPF_ERROR 1
+#define KPF_REFERENCED 2
+#define KPF_UPTODATE 3
+#define KPF_DIRTY 4
+#define KPF_LRU 5
+#define KPF_ACTIVE 6
+#define KPF_SLAB 7
+#define KPF_WRITEBACK 8
+#define KPF_RECLAIM 9
+#define KPF_BUDDY 10
+
+/* [11-20] new additions in 2.6.31 */
+#define KPF_MMAP 11
+#define KPF_ANON 12
+#define KPF_SWAPCACHE 13
+#define KPF_SWAPBACKED 14
+#define KPF_COMPOUND_HEAD 15
+#define KPF_COMPOUND_TAIL 16
+#define KPF_HUGE 17
+#define KPF_UNEVICTABLE 18
+#define KPF_HWPOISON 19
+#define KPF_NOPAGE 20
+
+/* [32-] kernel hacking assistances */
+#define KPF_RESERVED 32
+#define KPF_MLOCKED 33
+#define KPF_MAPPEDTODISK 34
+#define KPF_PRIVATE 35
+#define KPF_PRIVATE_2 36
+#define KPF_OWNER_PRIVATE 37
+#define KPF_ARCH 38
+#define KPF_UNCACHED 39
+
+/* [48-] take some arbitrary free slots for expanding overloaded flags
+ * not part of kernel API
+ */
+#define KPF_READAHEAD 48
+#define KPF_SLOB_FREE 49
+#define KPF_SLUB_FROZEN 50
+#define KPF_SLUB_DEBUG 51
+
+#define KPF_ALL_BITS ((uint64_t)~0ULL)
+#define KPF_HACKERS_BITS (0xffffULL << 32)
+#define KPF_OVERLOADED_BITS (0xffffULL << 48)
+#define BIT(name) (1ULL << KPF_##name)
+#define BITS_COMPOUND (BIT(COMPOUND_HEAD) | BIT(COMPOUND_TAIL))
+
+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] = "I:reclaim",
+ [KPF_BUDDY] = "B:buddy",
+
+ [KPF_MMAP] = "M:mmap",
+ [KPF_ANON] = "a:anonymous",
+ [KPF_SWAPCACHE] = "s:swapcache",
+ [KPF_SWAPBACKED] = "b:swapbacked",
+ [KPF_COMPOUND_HEAD] = "H:compound_head",
+ [KPF_COMPOUND_TAIL] = "T:compound_tail",
+ [KPF_HUGE] = "G:huge",
+ [KPF_UNEVICTABLE] = "u:unevictable",
+ [KPF_HWPOISON] = "X:hwpoison",
+ [KPF_NOPAGE] = "n:nopage",
+
+ [KPF_RESERVED] = "r:reserved",
+ [KPF_MLOCKED] = "m:mlocked",
+ [KPF_MAPPEDTODISK] = "d:mappedtodisk",
+ [KPF_PRIVATE] = "P:private",
+ [KPF_PRIVATE_2] = "p:private_2",
+ [KPF_OWNER_PRIVATE] = "O:owner_private",
+ [KPF_ARCH] = "h:arch",
+ [KPF_UNCACHED] = "c:uncached",
+
+ [KPF_READAHEAD] = "I:readahead",
+ [KPF_SLOB_FREE] = "P:slob_free",
+ [KPF_SLUB_FROZEN] = "A:slub_frozen",
+ [KPF_SLUB_DEBUG] = "E:slub_debug",
+};
+
+
+/*
+ * data structures
+ */
+
+static int opt_raw; /* for kernel developers */
+static int opt_list; /* list pages (in ranges) */
+static int opt_no_summary; /* don't show summary */
+static pid_t opt_pid; /* process to walk */
+
+#define MAX_ADDR_RANGES 1024
+static int nr_addr_ranges;
+static unsigned long opt_offset[MAX_ADDR_RANGES];
+static unsigned long opt_size[MAX_ADDR_RANGES];
+
+#define MAX_BIT_FILTERS 64
+static int nr_bit_filters;
+static uint64_t opt_mask[MAX_BIT_FILTERS];
+static uint64_t opt_bits[MAX_BIT_FILTERS];
+
+static int page_size;
+
+#define PAGES_BATCH (64 << 10) /* 64k pages */
+static int kpageflags_fd;
+static uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH];
+
+#define HASH_SHIFT 13
+#define HASH_SIZE (1 << HASH_SHIFT)
+#define HASH_MASK (HASH_SIZE - 1)
+#define HASH_KEY(flags) (flags & HASH_MASK)
+
+static unsigned long total_pages;
+static unsigned long nr_pages[HASH_SIZE];
+static uint64_t page_flags[HASH_SIZE];
+
+
+/*
+ * helper functions
+ */
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define min_t(type, x, y) ({ \
+ type __min1 = (x); \
+ type __min2 = (y); \
+ __min1 < __min2 ? __min1 : __min2; })
+
+unsigned long pages2mb(unsigned long pages)
+{
+ return (pages * page_size) >> 20;
+}
+
+void fatal(const char *x, ...)
+{
+ va_list ap;
+
+ va_start(ap, x);
+ vfprintf(stderr, x, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+
+/*
+ * page flag names
+ */
+
+char *page_flag_name(uint64_t flags)
+{
+ static char buf[65];
+ int present;
+ int i, j;
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ present = (flags >> i) & 1;
+ if (!page_flag_names[i]) {
+ if (present)
+ fatal("unkown flag bit %d\n", i);
+ continue;
+ }
+ buf[j++] = present ? page_flag_names[i][0] : '_';
+ }
+
+ return buf;
+}
+
+char *page_flag_longname(uint64_t flags)
+{
+ static char buf[1024];
+ int i, n;
+
+ for (i = 0, n = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ if (!page_flag_names[i])
+ continue;
+ if ((flags >> i) & 1)
+ n += snprintf(buf + n, sizeof(buf) - n, "%s,",
+ page_flag_names[i] + 2);
+ }
+ if (n)
+ n--;
+ buf[n] = '\0';
+
+ return buf;
+}
+
+
+/*
+ * page list and summary
+ */
+
+void show_page_range(unsigned long offset, uint64_t flags)
+{
+ static uint64_t flags0;
+ static unsigned long index;
+ static unsigned long count;
+
+ if (flags == flags0 && offset == index + count) {
+ count++;
+ return;
+ }
+
+ if (count)
+ printf("%lu\t%lu\t%s\n",
+ index, count, page_flag_name(flags0));
+
+ flags0 = flags;
+ index = offset;
+ count = 1;
+}
+
+void show_page(unsigned long offset, uint64_t flags)
+{
+ printf("%lu\t%s\n", offset, page_flag_name(flags));
+}
+
+void show_summary()
+{
+ int i;
+
+ printf(" flags\tpage-count MB"
+ " symbolic-flags\t\t\tlong-symbolic-flags\n");
+
+ for (i = 0; i < ARRAY_SIZE(nr_pages); i++) {
+ if (nr_pages[i])
+ printf("0x%016llx\t%10lu %8lu %s\t%s\n",
+ (unsigned long long)page_flags[i],
+ nr_pages[i],
+ pages2mb(nr_pages[i]),
+ page_flag_name(page_flags[i]),
+ page_flag_longname(page_flags[i]));
+ }
+
+ printf(" total\t%10lu %8lu\n",
+ total_pages, pages2mb(total_pages));
+}
+
+
+/*
+ * page flag filters
+ */
+
+int bit_mask_ok(uint64_t flags)
+{
+ int i;
+
+ for (i = 0; i < nr_bit_filters; i++) {
+ if (opt_bits[i] == KPF_ALL_BITS) {
+ if ((flags & opt_mask[i]) == 0)
+ return 0;
+ } else {
+ if ((flags & opt_mask[i]) != opt_bits[i])
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+uint64_t expand_overloaded_flags(uint64_t flags)
+{
+ /* SLOB/SLUB overload several page flags */
+ if (flags & BIT(SLAB)) {
+ if (flags & BIT(PRIVATE))
+ flags ^= BIT(PRIVATE) | BIT(SLOB_FREE);
+ if (flags & BIT(ACTIVE))
+ flags ^= BIT(ACTIVE) | BIT(SLUB_FROZEN);
+ if (flags & BIT(ERROR))
+ flags ^= BIT(ERROR) | BIT(SLUB_DEBUG);
+ }
+
+ /* PG_reclaim is overloaded as PG_readahead in the read path */
+ if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM))
+ flags ^= BIT(RECLAIM) | BIT(READAHEAD);
+
+ return flags;
+}
+
+uint64_t well_known_flags(uint64_t flags)
+{
+ /* hide flags intended only for kernel hacker */
+ flags &= ~KPF_HACKERS_BITS;
+
+ /* hide non-hugeTLB compound pages */
+ if ((flags & BITS_COMPOUND) && !(flags & BIT(HUGE)))
+ flags &= ~BITS_COMPOUND;
+
+ return flags;
+}
+
+
+/*
+ * page frame walker
+ */
+
+int hash_slot(uint64_t flags)
+{
+ int k = HASH_KEY(flags);
+ int i;
+
+ /* Explicitly reserve slot 0 for flags 0: the following logic
+ * cannot distinguish an unoccupied slot from slot (flags==0).
+ */
+ if (flags == 0)
+ return 0;
+
+ /* search through the remaining (HASH_SIZE-1) slots */
+ for (i = 1; i < ARRAY_SIZE(page_flags); i++, k++) {
+ if (!k || k >= ARRAY_SIZE(page_flags))
+ k = 1;
+ if (page_flags[k] == 0) {
+ page_flags[k] = flags;
+ return k;
+ }
+ if (page_flags[k] == flags)
+ return k;
+ }
+
+ fatal("hash table full: bump up HASH_SHIFT?\n");
+ exit(EXIT_FAILURE);
+}
+
+void add_page(unsigned long offset, uint64_t flags)
+{
+ flags = expand_overloaded_flags(flags);
+
+ if (!opt_raw)
+ flags = well_known_flags(flags);
+
+ if (!bit_mask_ok(flags))
+ return;
+
+ if (opt_list == 1)
+ show_page_range(offset, flags);
+ else if (opt_list == 2)
+ show_page(offset, flags);
+
+ nr_pages[hash_slot(flags)]++;
+ total_pages++;
+}
+
+void walk_pfn(unsigned long index, unsigned long count)
+{
+ unsigned long batch;
+ unsigned long n;
+ unsigned long i;
+
+ if (index > ULONG_MAX / KPF_BYTES)
+ fatal("index overflow: %lu\n", index);
+
+ lseek(kpageflags_fd, index * KPF_BYTES, SEEK_SET);
+
+ while (count) {
+ batch = min_t(unsigned long, count, PAGES_BATCH);
+ n = read(kpageflags_fd, kpageflags_buf, batch * KPF_BYTES);
+ if (n == 0)
+ break;
+ if (n < 0) {
+ perror(PROC_KPAGEFLAGS);
+ exit(EXIT_FAILURE);
+ }
+
+ if (n % KPF_BYTES != 0)
+ fatal("partial read: %lu bytes\n", n);
+ n = n / KPF_BYTES;
+
+ for (i = 0; i < n; i++)
+ add_page(index + i, kpageflags_buf[i]);
+
+ index += batch;
+ count -= batch;
+ }
+}
+
+void walk_addr_ranges(void)
+{
+ int i;
+
+ kpageflags_fd = open(PROC_KPAGEFLAGS, O_RDONLY);
+ if (kpageflags_fd < 0) {
+ perror(PROC_KPAGEFLAGS);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!nr_addr_ranges)
+ walk_pfn(0, ULONG_MAX);
+
+ for (i = 0; i < nr_addr_ranges; i++)
+ walk_pfn(opt_offset[i], opt_size[i]);
+
+ close(kpageflags_fd);
+}
+
+
+/*
+ * user interface
+ */
+
+const char *page_flag_type(uint64_t flag)
+{
+ if (flag & KPF_HACKERS_BITS)
+ return "(r)";
+ if (flag & KPF_OVERLOADED_BITS)
+ return "(o)";
+ return " ";
+}
+
+void usage(void)
+{
+ int i, j;
+
+ printf(
+"page-types [options]\n"
+" -r|--raw Raw mode, for kernel developers\n"
+" -a|--addr addr-spec Walk a range of pages\n"
+" -b|--bits bits-spec Walk pages with specified bits\n"
+#if 0 /* planned features */
+" -p|--pid pid Walk process address space\n"
+" -f|--file filename Walk file address space\n"
+#endif
+"addr-spec:\n"
+" N one page at offset N (unit: pages)\n"
+" N+M pages range from N to N+M-1\n"
+" N,M pages range from N to M-1\n"
+" N, pages range from N to end\n"
+" ,M pages range from 0 to M\n"
+"bits-spec:\n"
+" bit1,bit2 (flags & (bit1|bit2)) != 0\n"
+" bit1,bit2=bit1 (flags & (bit1|bit2)) == bit1\n"
+" bit1,~bit2 (flags & (bit1|bit2)) == bit1\n"
+" =bit1,bit2 flags == (bit1|bit2)\n"
+"bit-names:\n"
+ );
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ if (!page_flag_names[i])
+ continue;
+ printf("%16s%s", page_flag_names[i] + 2,
+ page_flag_type(1ULL << i));
+ if (++j > 3) {
+ j = 0;
+ putchar('\n');
+ }
+ }
+ printf("\n "
+ "(r) raw mode bits (o) overloaded bits\n");
+}
+
+unsigned long long parse_number(const char *str)
+{
+ unsigned long long n;
+
+ n = strtoll(str, NULL, 0);
+
+ if (n == 0 && str[0] != '0')
+ fatal("invalid name or number: %s\n", str);
+
+ return n;
+}
+
+void parse_pid(const char *str)
+{
+ opt_pid = parse_number(str);
+}
+
+void parse_file(const char *name)
+{
+}
+
+void add_addr_range(unsigned long offset, unsigned long size)
+{
+ if (nr_addr_ranges >= MAX_ADDR_RANGES)
+ fatal("too much addr ranges\n");
+
+ opt_offset[nr_addr_ranges] = offset;
+ opt_size[nr_addr_ranges] = size;
+ nr_addr_ranges++;
+}
+
+void parse_addr_range(const char *optarg)
+{
+ unsigned long offset;
+ unsigned long size;
+ char *p;
+
+ p = strchr(optarg, ',');
+ if (!p)
+ p = strchr(optarg, '+');
+
+ if (p == optarg) {
+ offset = 0;
+ size = parse_number(p + 1);
+ } else if (p) {
+ offset = parse_number(optarg);
+ if (p[1] == '\0')
+ size = ULONG_MAX;
+ else {
+ size = parse_number(p + 1);
+ if (*p == ',') {
+ if (size < offset)
+ fatal("invalid range: %lu,%lu\n",
+ offset, size);
+ size -= offset;
+ }
+ }
+ } else {
+ offset = parse_number(optarg);
+ size = 1;
+ }
+
+ add_addr_range(offset, size);
+}
+
+void add_bits_filter(uint64_t mask, uint64_t bits)
+{
+ if (nr_bit_filters >= MAX_BIT_FILTERS)
+ fatal("too much bit filters\n");
+
+ opt_mask[nr_bit_filters] = mask;
+ opt_bits[nr_bit_filters] = bits;
+ nr_bit_filters++;
+}
+
+uint64_t parse_flag_name(const char *str, int len)
+{
+ int i;
+
+ if (!*str || !len)
+ return 0;
+
+ if (len <= 8 && !strncmp(str, "compound", len))
+ return BITS_COMPOUND;
+
+ for (i = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ if (!page_flag_names[i])
+ continue;
+ if (!strncmp(str, page_flag_names[i] + 2, len))
+ return 1ULL << i;
+ }
+
+ return parse_number(str);
+}
+
+uint64_t parse_flag_names(const char *str, int all)
+{
+ const char *p = str;
+ uint64_t flags = 0;
+
+ while (1) {
+ if (*p == ',' || *p == '=' || *p == '\0') {
+ if ((*str != '~') || (*str == '~' && all && *++str))
+ flags |= parse_flag_name(str, p - str);
+ if (*p != ',')
+ break;
+ str = p + 1;
+ }
+ p++;
+ }
+
+ return flags;
+}
+
+void parse_bits_mask(const char *optarg)
+{
+ uint64_t mask;
+ uint64_t bits;
+ const char *p;
+
+ p = strchr(optarg, '=');
+ if (p == optarg) {
+ mask = KPF_ALL_BITS;
+ bits = parse_flag_names(p + 1, 0);
+ } else if (p) {
+ mask = parse_flag_names(optarg, 0);
+ bits = parse_flag_names(p + 1, 0);
+ } else if (strchr(optarg, '~')) {
+ mask = parse_flag_names(optarg, 1);
+ bits = parse_flag_names(optarg, 0);
+ } else {
+ mask = parse_flag_names(optarg, 0);
+ bits = KPF_ALL_BITS;
+ }
+
+ add_bits_filter(mask, bits);
+}
+
+
+struct option opts[] = {
+ { "raw" , 0, NULL, 'r' },
+ { "pid" , 1, NULL, 'p' },
+ { "file" , 1, NULL, 'f' },
+ { "addr" , 1, NULL, 'a' },
+ { "bits" , 1, NULL, 'b' },
+ { "list" , 0, NULL, 'l' },
+ { "list-each" , 0, NULL, 'L' },
+ { "no-summary", 0, NULL, 'N' },
+ { "help" , 0, NULL, 'h' },
+ { NULL , 0, NULL, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+ int c;
+
+ page_size = getpagesize();
+
+ while ((c = getopt_long(argc, argv,
+ "rp:f:a:b:lLNh", opts, NULL)) != -1) {
+ switch (c) {
+ case 'r':
+ opt_raw = 1;
+ break;
+ case 'p':
+ parse_pid(optarg);
+ break;
+ case 'f':
+ parse_file(optarg);
+ break;
+ case 'a':
+ parse_addr_range(optarg);
+ break;
+ case 'b':
+ parse_bits_mask(optarg);
+ break;
+ case 'l':
+ opt_list = 1;
+ break;
+ case 'L':
+ opt_list = 2;
+ break;
+ case 'N':
+ opt_no_summary = 1;
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ if (opt_list == 1)
+ printf("offset\tcount\tflags\n");
+ if (opt_list == 2)
+ printf("offset\tflags\n");
+
+ walk_addr_ranges();
+
+ if (opt_list == 1)
+ show_page_range(0, 0); /* drain the buffer */
+
+ if (opt_no_summary)
+ return 0;
+
+ if (opt_list)
+ printf("\n\n");
+
+ show_summary();
+
+ return 0;
+}
--- linux.orig/Documentation/vm/Makefile
+++ linux/Documentation/vm/Makefile
@@ -2,7 +2,7 @@
obj- := dummy.o
# List of programs to build
-hostprogs-y := slabinfo
+hostprogs-y := slabinfo slqbinfo page-types
# Tell kbuild to always build the programs
always := $(hostprogs-y)
--
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 7/7] pagemap: add page-types tool
@ 2009-05-07 1:21 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 1:21 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Andi Kleen, Wu Fengguang, Matt Mackall, KOSAKI Motohiro, linux-mm
[-- Attachment #1: page-types.patch --]
[-- Type: text/plain, Size: 16328 bytes --]
Add page-types, a handy tool for querying page flags.
It will expand some of the overloaded flags:
PG_slob_free = PG_private
PG_slub_frozen = PG_active
PG_slub_debug = PG_error
PG_readahead = PG_reclaim
and mask out obscure flags except in -raw mode:
PG_reserved
PG_mlocked
PG_mappedtodisk
PG_private
PG_private_2
PG_owner_priv_1
PG_arch_1
PG_uncached
PG_compound* for non hugeTLB pages
CC: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
Documentation/vm/Makefile | 2
Documentation/vm/page-types.c | 696 ++++++++++++++++++++++++++++++++
2 files changed, 697 insertions(+), 1 deletion(-)
--- /dev/null
+++ linux/Documentation/vm/page-types.c
@@ -0,0 +1,696 @@
+/*
+ * page-types: Tool for querying page flags
+ *
+ * Copyright (C) 2009 Intel corporation
+ * Copyright (C) 2009 Wu Fengguang <fengguang.wu@intel.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <getopt.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+
+
+/*
+ * kernel page flags
+ */
+
+#define KPF_BYTES 8
+#define PROC_KPAGEFLAGS "/proc/kpageflags"
+
+/* copied from kpageflags_read() */
+#define KPF_LOCKED 0
+#define KPF_ERROR 1
+#define KPF_REFERENCED 2
+#define KPF_UPTODATE 3
+#define KPF_DIRTY 4
+#define KPF_LRU 5
+#define KPF_ACTIVE 6
+#define KPF_SLAB 7
+#define KPF_WRITEBACK 8
+#define KPF_RECLAIM 9
+#define KPF_BUDDY 10
+
+/* [11-20] new additions in 2.6.31 */
+#define KPF_MMAP 11
+#define KPF_ANON 12
+#define KPF_SWAPCACHE 13
+#define KPF_SWAPBACKED 14
+#define KPF_COMPOUND_HEAD 15
+#define KPF_COMPOUND_TAIL 16
+#define KPF_HUGE 17
+#define KPF_UNEVICTABLE 18
+#define KPF_HWPOISON 19
+#define KPF_NOPAGE 20
+
+/* [32-] kernel hacking assistances */
+#define KPF_RESERVED 32
+#define KPF_MLOCKED 33
+#define KPF_MAPPEDTODISK 34
+#define KPF_PRIVATE 35
+#define KPF_PRIVATE_2 36
+#define KPF_OWNER_PRIVATE 37
+#define KPF_ARCH 38
+#define KPF_UNCACHED 39
+
+/* [48-] take some arbitrary free slots for expanding overloaded flags
+ * not part of kernel API
+ */
+#define KPF_READAHEAD 48
+#define KPF_SLOB_FREE 49
+#define KPF_SLUB_FROZEN 50
+#define KPF_SLUB_DEBUG 51
+
+#define KPF_ALL_BITS ((uint64_t)~0ULL)
+#define KPF_HACKERS_BITS (0xffffULL << 32)
+#define KPF_OVERLOADED_BITS (0xffffULL << 48)
+#define BIT(name) (1ULL << KPF_##name)
+#define BITS_COMPOUND (BIT(COMPOUND_HEAD) | BIT(COMPOUND_TAIL))
+
+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] = "I:reclaim",
+ [KPF_BUDDY] = "B:buddy",
+
+ [KPF_MMAP] = "M:mmap",
+ [KPF_ANON] = "a:anonymous",
+ [KPF_SWAPCACHE] = "s:swapcache",
+ [KPF_SWAPBACKED] = "b:swapbacked",
+ [KPF_COMPOUND_HEAD] = "H:compound_head",
+ [KPF_COMPOUND_TAIL] = "T:compound_tail",
+ [KPF_HUGE] = "G:huge",
+ [KPF_UNEVICTABLE] = "u:unevictable",
+ [KPF_HWPOISON] = "X:hwpoison",
+ [KPF_NOPAGE] = "n:nopage",
+
+ [KPF_RESERVED] = "r:reserved",
+ [KPF_MLOCKED] = "m:mlocked",
+ [KPF_MAPPEDTODISK] = "d:mappedtodisk",
+ [KPF_PRIVATE] = "P:private",
+ [KPF_PRIVATE_2] = "p:private_2",
+ [KPF_OWNER_PRIVATE] = "O:owner_private",
+ [KPF_ARCH] = "h:arch",
+ [KPF_UNCACHED] = "c:uncached",
+
+ [KPF_READAHEAD] = "I:readahead",
+ [KPF_SLOB_FREE] = "P:slob_free",
+ [KPF_SLUB_FROZEN] = "A:slub_frozen",
+ [KPF_SLUB_DEBUG] = "E:slub_debug",
+};
+
+
+/*
+ * data structures
+ */
+
+static int opt_raw; /* for kernel developers */
+static int opt_list; /* list pages (in ranges) */
+static int opt_no_summary; /* don't show summary */
+static pid_t opt_pid; /* process to walk */
+
+#define MAX_ADDR_RANGES 1024
+static int nr_addr_ranges;
+static unsigned long opt_offset[MAX_ADDR_RANGES];
+static unsigned long opt_size[MAX_ADDR_RANGES];
+
+#define MAX_BIT_FILTERS 64
+static int nr_bit_filters;
+static uint64_t opt_mask[MAX_BIT_FILTERS];
+static uint64_t opt_bits[MAX_BIT_FILTERS];
+
+static int page_size;
+
+#define PAGES_BATCH (64 << 10) /* 64k pages */
+static int kpageflags_fd;
+static uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH];
+
+#define HASH_SHIFT 13
+#define HASH_SIZE (1 << HASH_SHIFT)
+#define HASH_MASK (HASH_SIZE - 1)
+#define HASH_KEY(flags) (flags & HASH_MASK)
+
+static unsigned long total_pages;
+static unsigned long nr_pages[HASH_SIZE];
+static uint64_t page_flags[HASH_SIZE];
+
+
+/*
+ * helper functions
+ */
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define min_t(type, x, y) ({ \
+ type __min1 = (x); \
+ type __min2 = (y); \
+ __min1 < __min2 ? __min1 : __min2; })
+
+unsigned long pages2mb(unsigned long pages)
+{
+ return (pages * page_size) >> 20;
+}
+
+void fatal(const char *x, ...)
+{
+ va_list ap;
+
+ va_start(ap, x);
+ vfprintf(stderr, x, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+
+/*
+ * page flag names
+ */
+
+char *page_flag_name(uint64_t flags)
+{
+ static char buf[65];
+ int present;
+ int i, j;
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ present = (flags >> i) & 1;
+ if (!page_flag_names[i]) {
+ if (present)
+ fatal("unkown flag bit %d\n", i);
+ continue;
+ }
+ buf[j++] = present ? page_flag_names[i][0] : '_';
+ }
+
+ return buf;
+}
+
+char *page_flag_longname(uint64_t flags)
+{
+ static char buf[1024];
+ int i, n;
+
+ for (i = 0, n = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ if (!page_flag_names[i])
+ continue;
+ if ((flags >> i) & 1)
+ n += snprintf(buf + n, sizeof(buf) - n, "%s,",
+ page_flag_names[i] + 2);
+ }
+ if (n)
+ n--;
+ buf[n] = '\0';
+
+ return buf;
+}
+
+
+/*
+ * page list and summary
+ */
+
+void show_page_range(unsigned long offset, uint64_t flags)
+{
+ static uint64_t flags0;
+ static unsigned long index;
+ static unsigned long count;
+
+ if (flags == flags0 && offset == index + count) {
+ count++;
+ return;
+ }
+
+ if (count)
+ printf("%lu\t%lu\t%s\n",
+ index, count, page_flag_name(flags0));
+
+ flags0 = flags;
+ index = offset;
+ count = 1;
+}
+
+void show_page(unsigned long offset, uint64_t flags)
+{
+ printf("%lu\t%s\n", offset, page_flag_name(flags));
+}
+
+void show_summary()
+{
+ int i;
+
+ printf(" flags\tpage-count MB"
+ " symbolic-flags\t\t\tlong-symbolic-flags\n");
+
+ for (i = 0; i < ARRAY_SIZE(nr_pages); i++) {
+ if (nr_pages[i])
+ printf("0x%016llx\t%10lu %8lu %s\t%s\n",
+ (unsigned long long)page_flags[i],
+ nr_pages[i],
+ pages2mb(nr_pages[i]),
+ page_flag_name(page_flags[i]),
+ page_flag_longname(page_flags[i]));
+ }
+
+ printf(" total\t%10lu %8lu\n",
+ total_pages, pages2mb(total_pages));
+}
+
+
+/*
+ * page flag filters
+ */
+
+int bit_mask_ok(uint64_t flags)
+{
+ int i;
+
+ for (i = 0; i < nr_bit_filters; i++) {
+ if (opt_bits[i] == KPF_ALL_BITS) {
+ if ((flags & opt_mask[i]) == 0)
+ return 0;
+ } else {
+ if ((flags & opt_mask[i]) != opt_bits[i])
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+uint64_t expand_overloaded_flags(uint64_t flags)
+{
+ /* SLOB/SLUB overload several page flags */
+ if (flags & BIT(SLAB)) {
+ if (flags & BIT(PRIVATE))
+ flags ^= BIT(PRIVATE) | BIT(SLOB_FREE);
+ if (flags & BIT(ACTIVE))
+ flags ^= BIT(ACTIVE) | BIT(SLUB_FROZEN);
+ if (flags & BIT(ERROR))
+ flags ^= BIT(ERROR) | BIT(SLUB_DEBUG);
+ }
+
+ /* PG_reclaim is overloaded as PG_readahead in the read path */
+ if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM))
+ flags ^= BIT(RECLAIM) | BIT(READAHEAD);
+
+ return flags;
+}
+
+uint64_t well_known_flags(uint64_t flags)
+{
+ /* hide flags intended only for kernel hacker */
+ flags &= ~KPF_HACKERS_BITS;
+
+ /* hide non-hugeTLB compound pages */
+ if ((flags & BITS_COMPOUND) && !(flags & BIT(HUGE)))
+ flags &= ~BITS_COMPOUND;
+
+ return flags;
+}
+
+
+/*
+ * page frame walker
+ */
+
+int hash_slot(uint64_t flags)
+{
+ int k = HASH_KEY(flags);
+ int i;
+
+ /* Explicitly reserve slot 0 for flags 0: the following logic
+ * cannot distinguish an unoccupied slot from slot (flags==0).
+ */
+ if (flags == 0)
+ return 0;
+
+ /* search through the remaining (HASH_SIZE-1) slots */
+ for (i = 1; i < ARRAY_SIZE(page_flags); i++, k++) {
+ if (!k || k >= ARRAY_SIZE(page_flags))
+ k = 1;
+ if (page_flags[k] == 0) {
+ page_flags[k] = flags;
+ return k;
+ }
+ if (page_flags[k] == flags)
+ return k;
+ }
+
+ fatal("hash table full: bump up HASH_SHIFT?\n");
+ exit(EXIT_FAILURE);
+}
+
+void add_page(unsigned long offset, uint64_t flags)
+{
+ flags = expand_overloaded_flags(flags);
+
+ if (!opt_raw)
+ flags = well_known_flags(flags);
+
+ if (!bit_mask_ok(flags))
+ return;
+
+ if (opt_list == 1)
+ show_page_range(offset, flags);
+ else if (opt_list == 2)
+ show_page(offset, flags);
+
+ nr_pages[hash_slot(flags)]++;
+ total_pages++;
+}
+
+void walk_pfn(unsigned long index, unsigned long count)
+{
+ unsigned long batch;
+ unsigned long n;
+ unsigned long i;
+
+ if (index > ULONG_MAX / KPF_BYTES)
+ fatal("index overflow: %lu\n", index);
+
+ lseek(kpageflags_fd, index * KPF_BYTES, SEEK_SET);
+
+ while (count) {
+ batch = min_t(unsigned long, count, PAGES_BATCH);
+ n = read(kpageflags_fd, kpageflags_buf, batch * KPF_BYTES);
+ if (n == 0)
+ break;
+ if (n < 0) {
+ perror(PROC_KPAGEFLAGS);
+ exit(EXIT_FAILURE);
+ }
+
+ if (n % KPF_BYTES != 0)
+ fatal("partial read: %lu bytes\n", n);
+ n = n / KPF_BYTES;
+
+ for (i = 0; i < n; i++)
+ add_page(index + i, kpageflags_buf[i]);
+
+ index += batch;
+ count -= batch;
+ }
+}
+
+void walk_addr_ranges(void)
+{
+ int i;
+
+ kpageflags_fd = open(PROC_KPAGEFLAGS, O_RDONLY);
+ if (kpageflags_fd < 0) {
+ perror(PROC_KPAGEFLAGS);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!nr_addr_ranges)
+ walk_pfn(0, ULONG_MAX);
+
+ for (i = 0; i < nr_addr_ranges; i++)
+ walk_pfn(opt_offset[i], opt_size[i]);
+
+ close(kpageflags_fd);
+}
+
+
+/*
+ * user interface
+ */
+
+const char *page_flag_type(uint64_t flag)
+{
+ if (flag & KPF_HACKERS_BITS)
+ return "(r)";
+ if (flag & KPF_OVERLOADED_BITS)
+ return "(o)";
+ return " ";
+}
+
+void usage(void)
+{
+ int i, j;
+
+ printf(
+"page-types [options]\n"
+" -r|--raw Raw mode, for kernel developers\n"
+" -a|--addr addr-spec Walk a range of pages\n"
+" -b|--bits bits-spec Walk pages with specified bits\n"
+#if 0 /* planned features */
+" -p|--pid pid Walk process address space\n"
+" -f|--file filename Walk file address space\n"
+#endif
+"addr-spec:\n"
+" N one page at offset N (unit: pages)\n"
+" N+M pages range from N to N+M-1\n"
+" N,M pages range from N to M-1\n"
+" N, pages range from N to end\n"
+" ,M pages range from 0 to M\n"
+"bits-spec:\n"
+" bit1,bit2 (flags & (bit1|bit2)) != 0\n"
+" bit1,bit2=bit1 (flags & (bit1|bit2)) == bit1\n"
+" bit1,~bit2 (flags & (bit1|bit2)) == bit1\n"
+" =bit1,bit2 flags == (bit1|bit2)\n"
+"bit-names:\n"
+ );
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ if (!page_flag_names[i])
+ continue;
+ printf("%16s%s", page_flag_names[i] + 2,
+ page_flag_type(1ULL << i));
+ if (++j > 3) {
+ j = 0;
+ putchar('\n');
+ }
+ }
+ printf("\n "
+ "(r) raw mode bits (o) overloaded bits\n");
+}
+
+unsigned long long parse_number(const char *str)
+{
+ unsigned long long n;
+
+ n = strtoll(str, NULL, 0);
+
+ if (n == 0 && str[0] != '0')
+ fatal("invalid name or number: %s\n", str);
+
+ return n;
+}
+
+void parse_pid(const char *str)
+{
+ opt_pid = parse_number(str);
+}
+
+void parse_file(const char *name)
+{
+}
+
+void add_addr_range(unsigned long offset, unsigned long size)
+{
+ if (nr_addr_ranges >= MAX_ADDR_RANGES)
+ fatal("too much addr ranges\n");
+
+ opt_offset[nr_addr_ranges] = offset;
+ opt_size[nr_addr_ranges] = size;
+ nr_addr_ranges++;
+}
+
+void parse_addr_range(const char *optarg)
+{
+ unsigned long offset;
+ unsigned long size;
+ char *p;
+
+ p = strchr(optarg, ',');
+ if (!p)
+ p = strchr(optarg, '+');
+
+ if (p == optarg) {
+ offset = 0;
+ size = parse_number(p + 1);
+ } else if (p) {
+ offset = parse_number(optarg);
+ if (p[1] == '\0')
+ size = ULONG_MAX;
+ else {
+ size = parse_number(p + 1);
+ if (*p == ',') {
+ if (size < offset)
+ fatal("invalid range: %lu,%lu\n",
+ offset, size);
+ size -= offset;
+ }
+ }
+ } else {
+ offset = parse_number(optarg);
+ size = 1;
+ }
+
+ add_addr_range(offset, size);
+}
+
+void add_bits_filter(uint64_t mask, uint64_t bits)
+{
+ if (nr_bit_filters >= MAX_BIT_FILTERS)
+ fatal("too much bit filters\n");
+
+ opt_mask[nr_bit_filters] = mask;
+ opt_bits[nr_bit_filters] = bits;
+ nr_bit_filters++;
+}
+
+uint64_t parse_flag_name(const char *str, int len)
+{
+ int i;
+
+ if (!*str || !len)
+ return 0;
+
+ if (len <= 8 && !strncmp(str, "compound", len))
+ return BITS_COMPOUND;
+
+ for (i = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+ if (!page_flag_names[i])
+ continue;
+ if (!strncmp(str, page_flag_names[i] + 2, len))
+ return 1ULL << i;
+ }
+
+ return parse_number(str);
+}
+
+uint64_t parse_flag_names(const char *str, int all)
+{
+ const char *p = str;
+ uint64_t flags = 0;
+
+ while (1) {
+ if (*p == ',' || *p == '=' || *p == '\0') {
+ if ((*str != '~') || (*str == '~' && all && *++str))
+ flags |= parse_flag_name(str, p - str);
+ if (*p != ',')
+ break;
+ str = p + 1;
+ }
+ p++;
+ }
+
+ return flags;
+}
+
+void parse_bits_mask(const char *optarg)
+{
+ uint64_t mask;
+ uint64_t bits;
+ const char *p;
+
+ p = strchr(optarg, '=');
+ if (p == optarg) {
+ mask = KPF_ALL_BITS;
+ bits = parse_flag_names(p + 1, 0);
+ } else if (p) {
+ mask = parse_flag_names(optarg, 0);
+ bits = parse_flag_names(p + 1, 0);
+ } else if (strchr(optarg, '~')) {
+ mask = parse_flag_names(optarg, 1);
+ bits = parse_flag_names(optarg, 0);
+ } else {
+ mask = parse_flag_names(optarg, 0);
+ bits = KPF_ALL_BITS;
+ }
+
+ add_bits_filter(mask, bits);
+}
+
+
+struct option opts[] = {
+ { "raw" , 0, NULL, 'r' },
+ { "pid" , 1, NULL, 'p' },
+ { "file" , 1, NULL, 'f' },
+ { "addr" , 1, NULL, 'a' },
+ { "bits" , 1, NULL, 'b' },
+ { "list" , 0, NULL, 'l' },
+ { "list-each" , 0, NULL, 'L' },
+ { "no-summary", 0, NULL, 'N' },
+ { "help" , 0, NULL, 'h' },
+ { NULL , 0, NULL, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+ int c;
+
+ page_size = getpagesize();
+
+ while ((c = getopt_long(argc, argv,
+ "rp:f:a:b:lLNh", opts, NULL)) != -1) {
+ switch (c) {
+ case 'r':
+ opt_raw = 1;
+ break;
+ case 'p':
+ parse_pid(optarg);
+ break;
+ case 'f':
+ parse_file(optarg);
+ break;
+ case 'a':
+ parse_addr_range(optarg);
+ break;
+ case 'b':
+ parse_bits_mask(optarg);
+ break;
+ case 'l':
+ opt_list = 1;
+ break;
+ case 'L':
+ opt_list = 2;
+ break;
+ case 'N':
+ opt_no_summary = 1;
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ if (opt_list == 1)
+ printf("offset\tcount\tflags\n");
+ if (opt_list == 2)
+ printf("offset\tflags\n");
+
+ walk_addr_ranges();
+
+ if (opt_list == 1)
+ show_page_range(0, 0); /* drain the buffer */
+
+ if (opt_no_summary)
+ return 0;
+
+ if (opt_list)
+ printf("\n\n");
+
+ show_summary();
+
+ return 0;
+}
--- linux.orig/Documentation/vm/Makefile
+++ linux/Documentation/vm/Makefile
@@ -2,7 +2,7 @@
obj- := dummy.o
# List of programs to build
-hostprogs-y := slabinfo
+hostprogs-y := slabinfo slqbinfo page-types
# Tell kbuild to always build the programs
always := $(hostprogs-y)
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 2:04 ` Minchan Kim
-1 siblings, 0 replies; 36+ messages in thread
From: Minchan Kim @ 2009-05-07 2:04 UTC (permalink / raw)
To: Wu Fengguang
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
Hi,
> +#ifdef CONFIG_MEMORY_FAILURE
> + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> +#endif
Did mmtom merge memory failure feature?
--
Kinds Regards
Minchan Kim
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 2:04 ` Minchan Kim
0 siblings, 0 replies; 36+ messages in thread
From: Minchan Kim @ 2009-05-07 2:04 UTC (permalink / raw)
To: Wu Fengguang
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
Hi,
> +#ifdef CONFIG_MEMORY_FAILURE
> + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> +#endif
Did mmtom merge memory failure feature?
--
Kinds Regards
Minchan Kim
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 2:04 ` Minchan Kim
@ 2009-05-07 2:07 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 2:07 UTC (permalink / raw)
To: Minchan Kim
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:04:31AM +0800, Minchan Kim wrote:
>
> Hi,
>
> > +#ifdef CONFIG_MEMORY_FAILURE
> > + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> > +#endif
>
> Did mmtom merge memory failure feature?
Maybe not yet.. but the #ifdef makes it safe :-)
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 2:07 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 2:07 UTC (permalink / raw)
To: Minchan Kim
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:04:31AM +0800, Minchan Kim wrote:
>
> Hi,
>
> > +#ifdef CONFIG_MEMORY_FAILURE
> > + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> > +#endif
>
> Did mmtom merge memory failure feature?
Maybe not yet.. but the #ifdef makes it safe :-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 2:07 ` Wu Fengguang
@ 2009-05-07 2:09 ` KOSAKI Motohiro
-1 siblings, 0 replies; 36+ messages in thread
From: KOSAKI Motohiro @ 2009-05-07 2:09 UTC (permalink / raw)
To: Wu Fengguang
Cc: kosaki.motohiro, Minchan Kim, Andrew Morton, LKML, Andi Kleen,
Matt Mackall, Alexey Dobriyan, linux-mm
> On Thu, May 07, 2009 at 10:04:31AM +0800, Minchan Kim wrote:
> >
> > Hi,
> >
> > > +#ifdef CONFIG_MEMORY_FAILURE
> > > + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> > > +#endif
> >
> > Did mmtom merge memory failure feature?
>
> Maybe not yet.. but the #ifdef makes it safe :-)
Please don't do that.
dependency of the out of tree code mean "please don't merge me".
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 2:09 ` KOSAKI Motohiro
0 siblings, 0 replies; 36+ messages in thread
From: KOSAKI Motohiro @ 2009-05-07 2:09 UTC (permalink / raw)
To: Wu Fengguang
Cc: kosaki.motohiro, Minchan Kim, Andrew Morton, LKML, Andi Kleen,
Matt Mackall, Alexey Dobriyan, linux-mm
> On Thu, May 07, 2009 at 10:04:31AM +0800, Minchan Kim wrote:
> >
> > Hi,
> >
> > > +#ifdef CONFIG_MEMORY_FAILURE
> > > + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> > > +#endif
> >
> > Did mmtom merge memory failure feature?
>
> Maybe not yet.. but the #ifdef makes it safe :-)
Please don't do that.
dependency of the out of tree code mean "please don't merge me".
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 2:09 ` KOSAKI Motohiro
@ 2009-05-07 2:20 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 2:20 UTC (permalink / raw)
To: KOSAKI Motohiro
Cc: Minchan Kim, Andrew Morton, LKML, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:09:43AM +0800, KOSAKI Motohiro wrote:
> > On Thu, May 07, 2009 at 10:04:31AM +0800, Minchan Kim wrote:
> > >
> > > Hi,
> > >
> > > > +#ifdef CONFIG_MEMORY_FAILURE
> > > > + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> > > > +#endif
> > >
> > > Did mmtom merge memory failure feature?
> >
> > Maybe not yet.. but the #ifdef makes it safe :-)
>
> Please don't do that.
> dependency of the out of tree code mean "please don't merge me".
OK. I'll keep that in mind for the next take.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 2:20 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 2:20 UTC (permalink / raw)
To: KOSAKI Motohiro
Cc: Minchan Kim, Andrew Morton, LKML, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:09:43AM +0800, KOSAKI Motohiro wrote:
> > On Thu, May 07, 2009 at 10:04:31AM +0800, Minchan Kim wrote:
> > >
> > > Hi,
> > >
> > > > +#ifdef CONFIG_MEMORY_FAILURE
> > > > + u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
> > > > +#endif
> > >
> > > Did mmtom merge memory failure feature?
> >
> > Maybe not yet.. but the #ifdef makes it safe :-)
>
> Please don't do that.
> dependency of the out of tree code mean "please don't merge me".
OK. I'll keep that in mind for the next take.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-07 2:40 ` Minchan Kim
-1 siblings, 0 replies; 36+ messages in thread
From: Minchan Kim @ 2009-05-07 2:40 UTC (permalink / raw)
To: Wu Fengguang
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, 07 May 2009 09:21:21 +0800
Wu Fengguang <fengguang.wu@intel.com> wrote:
> + * pseudo flags for the well known (anonymous) memory mapped pages
> + */
> + if (!PageSlab(page) && page_mapped(page))
> + u |= 1 << KPF_MMAP;
> + if (PageAnon(page))
> + u |= 1 << KPF_ANON;
Why do you check PageSlab on user pages ?
Is there any case that PageSlab == true && page_mapped == true ?
--
Kinds Regards
Minchan Kim
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 2:40 ` Minchan Kim
0 siblings, 0 replies; 36+ messages in thread
From: Minchan Kim @ 2009-05-07 2:40 UTC (permalink / raw)
To: Wu Fengguang
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, 07 May 2009 09:21:21 +0800
Wu Fengguang <fengguang.wu@intel.com> wrote:
> + * pseudo flags for the well known (anonymous) memory mapped pages
> + */
> + if (!PageSlab(page) && page_mapped(page))
> + u |= 1 << KPF_MMAP;
> + if (PageAnon(page))
> + u |= 1 << KPF_ANON;
Why do you check PageSlab on user pages ?
Is there any case that PageSlab == true && page_mapped == true ?
--
Kinds Regards
Minchan Kim
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 2:40 ` Minchan Kim
@ 2009-05-07 2:46 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 2:46 UTC (permalink / raw)
To: Minchan Kim
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:40:16AM +0800, Minchan Kim wrote:
> On Thu, 07 May 2009 09:21:21 +0800
> Wu Fengguang <fengguang.wu@intel.com> wrote:
>
> > + * pseudo flags for the well known (anonymous) memory mapped pages
> > + */
> > + if (!PageSlab(page) && page_mapped(page))
> > + u |= 1 << KPF_MMAP;
> > + if (PageAnon(page))
> > + u |= 1 << KPF_ANON;
>
> Why do you check PageSlab on user pages ?
> Is there any case that PageSlab == true && page_mapped == true ?
Yes at least for SLUB: it reuses page->_mapcount, so page_mapped() is
meaningless for slab pages.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 2:46 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 2:46 UTC (permalink / raw)
To: Minchan Kim
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:40:16AM +0800, Minchan Kim wrote:
> On Thu, 07 May 2009 09:21:21 +0800
> Wu Fengguang <fengguang.wu@intel.com> wrote:
>
> > + * pseudo flags for the well known (anonymous) memory mapped pages
> > + */
> > + if (!PageSlab(page) && page_mapped(page))
> > + u |= 1 << KPF_MMAP;
> > + if (PageAnon(page))
> > + u |= 1 << KPF_ANON;
>
> Why do you check PageSlab on user pages ?
> Is there any case that PageSlab == true && page_mapped == true ?
Yes at least for SLUB: it reuses page->_mapcount, so page_mapped() is
meaningless for slab pages.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 2:46 ` Wu Fengguang
@ 2009-05-07 2:48 ` KOSAKI Motohiro
-1 siblings, 0 replies; 36+ messages in thread
From: KOSAKI Motohiro @ 2009-05-07 2:48 UTC (permalink / raw)
To: Wu Fengguang
Cc: kosaki.motohiro, Minchan Kim, Andrew Morton, LKML, Andi Kleen,
Matt Mackall, Alexey Dobriyan, linux-mm
> On Thu, May 07, 2009 at 10:40:16AM +0800, Minchan Kim wrote:
> > On Thu, 07 May 2009 09:21:21 +0800
> > Wu Fengguang <fengguang.wu@intel.com> wrote:
> >
> > > + * pseudo flags for the well known (anonymous) memory mapped pages
> > > + */
> > > + if (!PageSlab(page) && page_mapped(page))
> > > + u |= 1 << KPF_MMAP;
> > > + if (PageAnon(page))
> > > + u |= 1 << KPF_ANON;
> >
> > Why do you check PageSlab on user pages ?
> > Is there any case that PageSlab == true && page_mapped == true ?
>
> Yes at least for SLUB: it reuses page->_mapcount, so page_mapped() is
> meaningless for slab pages.
this question and answer implies more comment required...
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 2:48 ` KOSAKI Motohiro
0 siblings, 0 replies; 36+ messages in thread
From: KOSAKI Motohiro @ 2009-05-07 2:48 UTC (permalink / raw)
To: Wu Fengguang
Cc: kosaki.motohiro, Minchan Kim, Andrew Morton, LKML, Andi Kleen,
Matt Mackall, Alexey Dobriyan, linux-mm
> On Thu, May 07, 2009 at 10:40:16AM +0800, Minchan Kim wrote:
> > On Thu, 07 May 2009 09:21:21 +0800
> > Wu Fengguang <fengguang.wu@intel.com> wrote:
> >
> > > + * pseudo flags for the well known (anonymous) memory mapped pages
> > > + */
> > > + if (!PageSlab(page) && page_mapped(page))
> > > + u |= 1 << KPF_MMAP;
> > > + if (PageAnon(page))
> > > + u |= 1 << KPF_ANON;
> >
> > Why do you check PageSlab on user pages ?
> > Is there any case that PageSlab == true && page_mapped == true ?
>
> Yes at least for SLUB: it reuses page->_mapcount, so page_mapped() is
> meaningless for slab pages.
this question and answer implies more comment required...
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
2009-05-07 2:48 ` KOSAKI Motohiro
@ 2009-05-07 3:05 ` Wu Fengguang
-1 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 3:05 UTC (permalink / raw)
To: KOSAKI Motohiro
Cc: Minchan Kim, Andrew Morton, LKML, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:48:55AM +0800, KOSAKI Motohiro wrote:
> > On Thu, May 07, 2009 at 10:40:16AM +0800, Minchan Kim wrote:
> > > On Thu, 07 May 2009 09:21:21 +0800
> > > Wu Fengguang <fengguang.wu@intel.com> wrote:
> > >
> > > > + * pseudo flags for the well known (anonymous) memory mapped pages
> > > > + */
> > > > + if (!PageSlab(page) && page_mapped(page))
> > > > + u |= 1 << KPF_MMAP;
> > > > + if (PageAnon(page))
> > > > + u |= 1 << KPF_ANON;
> > >
> > > Why do you check PageSlab on user pages ?
> > > Is there any case that PageSlab == true && page_mapped == true ?
> >
> > Yes at least for SLUB: it reuses page->_mapcount, so page_mapped() is
> > meaningless for slab pages.
>
> this question and answer implies more comment required...
Good point. Updated comment to:
/*
* pseudo flags for the well known (anonymous) memory mapped pages
*
* Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the
* simple test in page_mapped() is not enough.
*/
if (!PageSlab(page) && page_mapped(page))
u |= 1 << KPF_MMAP;
Thanks,
Fengguang
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/7] proc: export more page flags in /proc/kpageflags
@ 2009-05-07 3:05 ` Wu Fengguang
0 siblings, 0 replies; 36+ messages in thread
From: Wu Fengguang @ 2009-05-07 3:05 UTC (permalink / raw)
To: KOSAKI Motohiro
Cc: Minchan Kim, Andrew Morton, LKML, Andi Kleen, Matt Mackall,
Alexey Dobriyan, linux-mm
On Thu, May 07, 2009 at 10:48:55AM +0800, KOSAKI Motohiro wrote:
> > On Thu, May 07, 2009 at 10:40:16AM +0800, Minchan Kim wrote:
> > > On Thu, 07 May 2009 09:21:21 +0800
> > > Wu Fengguang <fengguang.wu@intel.com> wrote:
> > >
> > > > + * pseudo flags for the well known (anonymous) memory mapped pages
> > > > + */
> > > > + if (!PageSlab(page) && page_mapped(page))
> > > > + u |= 1 << KPF_MMAP;
> > > > + if (PageAnon(page))
> > > > + u |= 1 << KPF_ANON;
> > >
> > > Why do you check PageSlab on user pages ?
> > > Is there any case that PageSlab == true && page_mapped == true ?
> >
> > Yes at least for SLUB: it reuses page->_mapcount, so page_mapped() is
> > meaningless for slab pages.
>
> this question and answer implies more comment required...
Good point. Updated comment to:
/*
* pseudo flags for the well known (anonymous) memory mapped pages
*
* Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the
* simple test in page_mapped() is not enough.
*/
if (!PageSlab(page) && page_mapped(page))
u |= 1 << KPF_MMAP;
Thanks,
Fengguang
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 2/7] slob: use PG_slab for identifying SLOB pages
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-08 18:24 ` Matt Mackall
-1 siblings, 0 replies; 36+ messages in thread
From: Matt Mackall @ 2009-05-08 18:24 UTC (permalink / raw)
To: Wu Fengguang
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, linux-mm, penberg
On Thu, May 07, 2009 at 09:21:19AM +0800, Wu Fengguang wrote:
> For the sake of consistency.
>
> Cc: Matt Mackall <mpm@selenic.com>
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Pekka, please take this one directly.
> ---
> include/linux/page-flags.h | 2 --
> mm/slob.c | 6 +++---
> 2 files changed, 3 insertions(+), 5 deletions(-)
>
> --- linux.orig/include/linux/page-flags.h
> +++ linux/include/linux/page-flags.h
> @@ -120,7 +120,6 @@ enum pageflags {
> PG_savepinned = PG_dirty,
>
> /* SLOB */
> - PG_slob_page = PG_active,
> PG_slob_free = PG_private,
>
> /* SLUB */
> @@ -203,7 +202,6 @@ PAGEFLAG(SavePinned, savepinned); /* X
> PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
> PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
>
> -__PAGEFLAG(SlobPage, slob_page)
> __PAGEFLAG(SlobFree, slob_free)
>
> __PAGEFLAG(SlubFrozen, slub_frozen)
> --- linux.orig/mm/slob.c
> +++ linux/mm/slob.c
> @@ -132,17 +132,17 @@ static LIST_HEAD(free_slob_large);
> */
> static inline int is_slob_page(struct slob_page *sp)
> {
> - return PageSlobPage((struct page *)sp);
> + return PageSlab((struct page *)sp);
> }
>
> static inline void set_slob_page(struct slob_page *sp)
> {
> - __SetPageSlobPage((struct page *)sp);
> + __SetPageSlab((struct page *)sp);
> }
>
> static inline void clear_slob_page(struct slob_page *sp)
> {
> - __ClearPageSlobPage((struct page *)sp);
> + __ClearPageSlab((struct page *)sp);
> }
>
> static inline struct slob_page *slob_page(const void *addr)
>
> --
--
Mathematics is the supreme nostalgia of our time.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 2/7] slob: use PG_slab for identifying SLOB pages
@ 2009-05-08 18:24 ` Matt Mackall
0 siblings, 0 replies; 36+ messages in thread
From: Matt Mackall @ 2009-05-08 18:24 UTC (permalink / raw)
To: Wu Fengguang
Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, linux-mm, penberg
On Thu, May 07, 2009 at 09:21:19AM +0800, Wu Fengguang wrote:
> For the sake of consistency.
>
> Cc: Matt Mackall <mpm@selenic.com>
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Pekka, please take this one directly.
> ---
> include/linux/page-flags.h | 2 --
> mm/slob.c | 6 +++---
> 2 files changed, 3 insertions(+), 5 deletions(-)
>
> --- linux.orig/include/linux/page-flags.h
> +++ linux/include/linux/page-flags.h
> @@ -120,7 +120,6 @@ enum pageflags {
> PG_savepinned = PG_dirty,
>
> /* SLOB */
> - PG_slob_page = PG_active,
> PG_slob_free = PG_private,
>
> /* SLUB */
> @@ -203,7 +202,6 @@ PAGEFLAG(SavePinned, savepinned); /* X
> PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
> PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
>
> -__PAGEFLAG(SlobPage, slob_page)
> __PAGEFLAG(SlobFree, slob_free)
>
> __PAGEFLAG(SlubFrozen, slub_frozen)
> --- linux.orig/mm/slob.c
> +++ linux/mm/slob.c
> @@ -132,17 +132,17 @@ static LIST_HEAD(free_slob_large);
> */
> static inline int is_slob_page(struct slob_page *sp)
> {
> - return PageSlobPage((struct page *)sp);
> + return PageSlab((struct page *)sp);
> }
>
> static inline void set_slob_page(struct slob_page *sp)
> {
> - __SetPageSlobPage((struct page *)sp);
> + __SetPageSlab((struct page *)sp);
> }
>
> static inline void clear_slob_page(struct slob_page *sp)
> {
> - __ClearPageSlobPage((struct page *)sp);
> + __ClearPageSlab((struct page *)sp);
> }
>
> static inline struct slob_page *slob_page(const void *addr)
>
> --
--
Mathematics is the supreme nostalgia of our time.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 3/7] proc: kpagecount/kpageflags code cleanup
2009-05-07 1:21 ` Wu Fengguang
@ 2009-05-08 18:28 ` Matt Mackall
-1 siblings, 0 replies; 36+ messages in thread
From: Matt Mackall @ 2009-05-08 18:28 UTC (permalink / raw)
To: Wu Fengguang; +Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, linux-mm
On Thu, May 07, 2009 at 09:21:20AM +0800, Wu Fengguang wrote:
> Move increments of pfn/out to bottom of the loop.
>
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Acked-by: Matt Mackall <mpm@selenic.com>
> ---
> fs/proc/page.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> --- linux.orig/fs/proc/page.c
> +++ linux/fs/proc/page.c
> @@ -11,6 +11,7 @@
>
> #define KPMSIZE sizeof(u64)
> #define KPMMASK (KPMSIZE - 1)
> +
> /* /proc/kpagecount - an array exposing page counts
> *
> * Each entry is a u64 representing the corresponding
> @@ -32,20 +33,22 @@ static ssize_t kpagecount_read(struct fi
> return -EINVAL;
>
> while (count > 0) {
> - ppage = NULL;
> if (pfn_valid(pfn))
> ppage = pfn_to_page(pfn);
> - pfn++;
> + else
> + ppage = NULL;
> if (!ppage)
> pcount = 0;
> else
> pcount = page_mapcount(ppage);
>
> - if (put_user(pcount, out++)) {
> + if (put_user(pcount, out)) {
> ret = -EFAULT;
> break;
> }
>
> + pfn++;
> + out++;
> count -= KPMSIZE;
> }
>
> @@ -98,10 +101,10 @@ static ssize_t kpageflags_read(struct fi
> return -EINVAL;
>
> while (count > 0) {
> - ppage = NULL;
> if (pfn_valid(pfn))
> ppage = pfn_to_page(pfn);
> - pfn++;
> + else
> + ppage = NULL;
> if (!ppage)
> kflags = 0;
> else
> @@ -119,11 +122,13 @@ static ssize_t kpageflags_read(struct fi
> kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
> kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
>
> - if (put_user(uflags, out++)) {
> + if (put_user(uflags, out)) {
> ret = -EFAULT;
> break;
> }
>
> + pfn++;
> + out++;
> count -= KPMSIZE;
> }
>
>
> --
--
Mathematics is the supreme nostalgia of our time.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 3/7] proc: kpagecount/kpageflags code cleanup
@ 2009-05-08 18:28 ` Matt Mackall
0 siblings, 0 replies; 36+ messages in thread
From: Matt Mackall @ 2009-05-08 18:28 UTC (permalink / raw)
To: Wu Fengguang; +Cc: Andrew Morton, LKML, KOSAKI Motohiro, Andi Kleen, linux-mm
On Thu, May 07, 2009 at 09:21:20AM +0800, Wu Fengguang wrote:
> Move increments of pfn/out to bottom of the loop.
>
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Acked-by: Matt Mackall <mpm@selenic.com>
> ---
> fs/proc/page.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> --- linux.orig/fs/proc/page.c
> +++ linux/fs/proc/page.c
> @@ -11,6 +11,7 @@
>
> #define KPMSIZE sizeof(u64)
> #define KPMMASK (KPMSIZE - 1)
> +
> /* /proc/kpagecount - an array exposing page counts
> *
> * Each entry is a u64 representing the corresponding
> @@ -32,20 +33,22 @@ static ssize_t kpagecount_read(struct fi
> return -EINVAL;
>
> while (count > 0) {
> - ppage = NULL;
> if (pfn_valid(pfn))
> ppage = pfn_to_page(pfn);
> - pfn++;
> + else
> + ppage = NULL;
> if (!ppage)
> pcount = 0;
> else
> pcount = page_mapcount(ppage);
>
> - if (put_user(pcount, out++)) {
> + if (put_user(pcount, out)) {
> ret = -EFAULT;
> break;
> }
>
> + pfn++;
> + out++;
> count -= KPMSIZE;
> }
>
> @@ -98,10 +101,10 @@ static ssize_t kpageflags_read(struct fi
> return -EINVAL;
>
> while (count > 0) {
> - ppage = NULL;
> if (pfn_valid(pfn))
> ppage = pfn_to_page(pfn);
> - pfn++;
> + else
> + ppage = NULL;
> if (!ppage)
> kflags = 0;
> else
> @@ -119,11 +122,13 @@ static ssize_t kpageflags_read(struct fi
> kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
> kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
>
> - if (put_user(uflags, out++)) {
> + if (put_user(uflags, out)) {
> ret = -EFAULT;
> break;
> }
>
> + pfn++;
> + out++;
> count -= KPMSIZE;
> }
>
>
> --
--
Mathematics is the supreme nostalgia of our time.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2009-05-08 18:29 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-07 1:21 [PATCH 0/7] export more page flags in /proc/kpageflags (take 5) Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
2009-05-07 1:21 ` [PATCH 1/7] mm: introduce PageHuge() for testing huge/gigantic pages Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
2009-05-07 1:21 ` [PATCH 2/7] slob: use PG_slab for identifying SLOB pages Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
2009-05-08 18:24 ` Matt Mackall
2009-05-08 18:24 ` Matt Mackall
2009-05-07 1:21 ` [PATCH 3/7] proc: kpagecount/kpageflags code cleanup Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
2009-05-08 18:28 ` Matt Mackall
2009-05-08 18:28 ` Matt Mackall
2009-05-07 1:21 ` [PATCH 4/7] proc: export more page flags in /proc/kpageflags Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
2009-05-07 2:04 ` Minchan Kim
2009-05-07 2:04 ` Minchan Kim
2009-05-07 2:07 ` Wu Fengguang
2009-05-07 2:07 ` Wu Fengguang
2009-05-07 2:09 ` KOSAKI Motohiro
2009-05-07 2:09 ` KOSAKI Motohiro
2009-05-07 2:20 ` Wu Fengguang
2009-05-07 2:20 ` Wu Fengguang
2009-05-07 2:40 ` Minchan Kim
2009-05-07 2:40 ` Minchan Kim
2009-05-07 2:46 ` Wu Fengguang
2009-05-07 2:46 ` Wu Fengguang
2009-05-07 2:48 ` KOSAKI Motohiro
2009-05-07 2:48 ` KOSAKI Motohiro
2009-05-07 3:05 ` Wu Fengguang
2009-05-07 3:05 ` Wu Fengguang
2009-05-07 1:21 ` [PATCH 5/7] pagemap: document clarifications Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
2009-05-07 1:21 ` [PATCH 6/7] pagemap: document 9 more exported page flags Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
2009-05-07 1:21 ` [PATCH 7/7] pagemap: add page-types tool Wu Fengguang
2009-05-07 1:21 ` Wu Fengguang
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.