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

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to