By default struct page.flags filter checks flags of every page. For
compound pages, some flags are only set to head page. The -g option
allows search to skip the whole compound page when the flags of head
page match the conditions.
---
help.c | 3 +++
memory.c | 21 +++++++++++++++++----
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/help.c b/help.c
index 8d45667..716de33 100644
--- a/help.c
+++ b/help.c
@@ -2855,6 +2855,9 @@ char *help_search[] = {
" the mask is preceded by a letter n. When used multiple times,
only",
" pages that meet all conditions will be searched. Only works
for",
" virtual address space (either user or kernel).",
+" -g",
+" Skip whole compound page instead of only skipping head pages
when",
+" using with -f. Only has effect with -f.",
" -c Search for character string values instead of unsigned longs.
If",
" the string contains any space(s), it must be encompassed by
double",
" quotes.",
diff --git a/memory.c b/memory.c
index 70649a2..db7dddb 100644
--- a/memory.c
+++ b/memory.c
@@ -110,6 +110,7 @@ struct searchinfo {
ulong vaddr_end;
ulonglong paddr_start;
ulonglong paddr_end;
+ char pg_skip_compound_page;
int pg_nmasks;
char pg_mask_neg[MAXARGS];
ulong pg_mask[MAXARGS];
@@ -13514,7 +13515,7 @@ cmd_search(void)
searchinfo.mode = SEARCH_ULONG; /* default search */
- while ((c = getopt(argcnt, args, "tl:ukKVps:e:v:m:f:hwcx:")) != EOF) {
+ while ((c = getopt(argcnt, args, "tl:ukKVps:e:v:m:f:ghwcx:")) != EOF) {
switch(c)
{
case 'u':
@@ -13597,6 +13598,10 @@ cmd_search(void)
searchinfo.pg_nmasks++;
break;
+ case 'g':
+ searchinfo.pg_skip_compound_page = 1;
+ break;
+
case 'l':
len = stol(optarg, FAULT_ON_ERROR, NULL);
break;
@@ -14439,6 +14444,7 @@ skip_pages(struct searchinfo *si, struct mem_map_cache *mmc, ulong
page, ulong *
{
int i;
ulong flags;
+ int order;
if (page < mmc->start || page > mmc->end) {
mmc->start = page;
@@ -14461,11 +14467,18 @@ skip_pages(struct searchinfo *si, struct mem_map_cache *mmc,
ulong page, ulong *
return 0;
skip:
+ if (si->pg_skip_compound_page)
+ order = page + SIZE(page) < mmc->end ?
+ __compound_order(mmc->cache + page - mmc->start) :
+ compound_order(page);
+ else
+ order = 0;
+
if (CRASHDEBUG(5))
- fprintf(fp, "ignore page: struct %lx, vaddr %lx, flags %lx\n",
- page, *pp, flags);
+ fprintf(fp, "ignore page: struct %lx, vaddr %lx, flags %lx, order %d\n",
+ page, *pp, flags, order);
- *pp += PAGESIZE();
+ *pp += PAGESIZE() * (1 << order);
return 1;
}
--
2.2.0.rc0.207.ga3a616c