1 #include <linux/bootmem.h>
2 #include <linux/compiler.h>
4 #include <linux/init.h>
6 #include <linux/mmzone.h>
7 #include <linux/proc_fs.h>
8 #include <linux/seq_file.h>
9 #include <asm/uaccess.h>
12 #define KPMSIZE sizeof(u64)
13 #define KPMMASK (KPMSIZE - 1)
14 /* /proc/kpagecount - an array exposing page counts
16 * Each entry is a u64 representing the corresponding
17 * physical page count.
19 static ssize_t
kpagecount_read(struct file
*file
, char __user
*buf
,
20 size_t count
, loff_t
*ppos
)
22 u64 __user
*out
= (u64 __user
*)buf
;
24 unsigned long src
= *ppos
;
30 count
= min_t(size_t, count
, (max_pfn
* KPMSIZE
) - src
);
31 if (src
& KPMMASK
|| count
& KPMMASK
)
37 ppage
= pfn_to_page(pfn
);
42 pcount
= page_mapcount(ppage
);
44 if (put_user(pcount
, out
++)) {
52 *ppos
+= (char __user
*)out
- buf
;
54 ret
= (char __user
*)out
- buf
;
58 static const struct file_operations proc_kpagecount_operations
= {
60 .read
= kpagecount_read
,
63 /* /proc/kpageflags - an array exposing page flags
65 * Each entry is a u64 representing the corresponding
66 * physical page flags.
69 /* These macros are used to decouple internal flags from exported ones */
73 #define KPF_REFERENCED 2
74 #define KPF_UPTODATE 3
79 #define KPF_WRITEBACK 8
83 #define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos)
85 static ssize_t
kpageflags_read(struct file
*file
, char __user
*buf
,
86 size_t count
, loff_t
*ppos
)
88 u64 __user
*out
= (u64 __user
*)buf
;
90 unsigned long src
= *ppos
;
96 count
= min_t(unsigned long, count
, (max_pfn
* KPMSIZE
) - src
);
97 if (src
& KPMMASK
|| count
& KPMMASK
)
103 ppage
= pfn_to_page(pfn
);
108 kflags
= ppage
->flags
;
110 uflags
= kpf_copy_bit(KPF_LOCKED
, PG_locked
, kflags
) |
111 kpf_copy_bit(kflags
, KPF_ERROR
, PG_error
) |
112 kpf_copy_bit(kflags
, KPF_REFERENCED
, PG_referenced
) |
113 kpf_copy_bit(kflags
, KPF_UPTODATE
, PG_uptodate
) |
114 kpf_copy_bit(kflags
, KPF_DIRTY
, PG_dirty
) |
115 kpf_copy_bit(kflags
, KPF_LRU
, PG_lru
) |
116 kpf_copy_bit(kflags
, KPF_ACTIVE
, PG_active
) |
117 kpf_copy_bit(kflags
, KPF_SLAB
, PG_slab
) |
118 kpf_copy_bit(kflags
, KPF_WRITEBACK
, PG_writeback
) |
119 kpf_copy_bit(kflags
, KPF_RECLAIM
, PG_reclaim
) |
120 kpf_copy_bit(kflags
, KPF_BUDDY
, PG_buddy
);
122 if (put_user(uflags
, out
++)) {
130 *ppos
+= (char __user
*)out
- buf
;
132 ret
= (char __user
*)out
- buf
;
136 static const struct file_operations proc_kpageflags_operations
= {
138 .read
= kpageflags_read
,
141 static int __init
proc_page_init(void)
143 proc_create("kpagecount", S_IRUSR
, NULL
, &proc_kpagecount_operations
);
144 proc_create("kpageflags", S_IRUSR
, NULL
, &proc_kpageflags_operations
);
147 module_init(proc_page_init
);