Add the folio_order() which keeps the same logic as kernel code,
and it will be used in the later patches.
Signed-off-by: Huang Shijie <huangsj(a)hygon.cn>
---
defs.h | 4 ++++
memory.c | 22 ++++++++++++++++++++++
symbols.c | 2 ++
3 files changed, 28 insertions(+)
diff --git a/defs.h b/defs.h
index 60cf56a..fdea94f 100644
--- a/defs.h
+++ b/defs.h
@@ -1425,6 +1425,7 @@ struct offset_table { /* stash of commonly-used
offsets */
long page_buffers;
long page_lru;
long page_pte;
+ long folio__flags_1;
long swap_info_struct_swap_file;
long swap_info_struct_swap_vfsmnt;
long swap_info_struct_flags;
@@ -2398,6 +2399,7 @@ struct size_table { /* stash of commonly-used sizes */
long probe;
long kobj_map;
long page_flags;
+ long folio__flags_1;
long module_sect_attr;
long task_struct_utime;
long task_struct_stime;
@@ -6007,6 +6009,8 @@ ulong do_xarray(ulong, int, struct list_pair *, int);
#define XARRAY_TAG_MASK (3UL)
#define XARRAY_TAG_INTERNAL (2UL)
+int folio_order(ulong folio);
+
int file_dump(ulong, ulong, ulong, int, int);
#define DUMP_FULL_NAME 0x1
#define DUMP_INODE_ONLY 0x2
diff --git a/memory.c b/memory.c
index cbc8d2f..9080332 100644
--- a/memory.c
+++ b/memory.c
@@ -547,6 +547,9 @@ vm_init(void)
MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
MEMBER_OFFSET_INIT(page_page_type, "page", "page_type");
+ MEMBER_OFFSET_INIT(folio__flags_1, "folio", "_flags_1");
+ MEMBER_SIZE_INIT(folio__flags_1, "folio", "_flags_1");
+
MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd");
MEMBER_OFFSET_INIT(swap_info_struct_swap_file,
@@ -5690,6 +5693,7 @@ PG_slab_flag_init(void)
#define v26_PG_private 12
+#define PG_head 6
#define PGMM_CACHED (512)
static void
@@ -20423,6 +20427,24 @@ static unsigned int oo_objects(ulong oo)
return (oo & ((1 << 16) - 1));
}
+int
+folio_order(ulong folio)
+{
+ ulong v = 0;
+
+ /* 1.) Check PG_head bit in the first page's flags. */
+ readmem(folio + OFFSET(page_flags), KVADDR, &v, sizeof(ulong),
+ "folio.page.flags", FAULT_ON_ERROR);
+ if (!(v & (1 << PG_head)))
+ return 0;
+
+ /* 2.) Get folio->_flags_1 in the second page */
+ readmem(folio + OFFSET(folio__flags_1), KVADDR, &v, sizeof(ulong),
+ "folio->_flags_1", FAULT_ON_ERROR);
+
+ return v & 0xff;
+}
+
#ifdef NOT_USED
ulong
slab_to_kmem_cache_node(struct meminfo *si, ulong slab_page)
diff --git a/symbols.c b/symbols.c
index e6865ca..19fcc03 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10451,6 +10451,7 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " page_private: %ld\n",
OFFSET(page_private));
fprintf(fp, " page_page_type: %ld\n",
OFFSET(page_page_type));
+ fprintf(fp, " folio__flags_1: %ld\n", OFFSET(folio__flags_1));
fprintf(fp, " trace_print_flags_mask: %ld\n",
OFFSET(trace_print_flags_mask));
@@ -11961,6 +11962,7 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, "\n size_table:\n");
fprintf(fp, " page: %ld\n", SIZE(page));
fprintf(fp, " page_flags: %ld\n", SIZE(page_flags));
+ fprintf(fp, " folio__flags_1: %ld\n", SIZE(folio__flags_1));
fprintf(fp, " trace_print_flags: %ld\n",
SIZE(trace_print_flags));
fprintf(fp, " free_area_struct: %ld\n",
SIZE(free_area_struct));
--
2.43.0