aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/kernel-page-flags.h1
-rw-r--r--tools/vm/page-types.c32
2 files changed, 21 insertions, 12 deletions
diff --git a/include/linux/kernel-page-flags.h b/include/linux/kernel-page-flags.h
index 546eb6a76934..f65ce09784f1 100644
--- a/include/linux/kernel-page-flags.h
+++ b/include/linux/kernel-page-flags.h
@@ -15,5 +15,6 @@
15#define KPF_OWNER_PRIVATE 37 15#define KPF_OWNER_PRIVATE 37
16#define KPF_ARCH 38 16#define KPF_ARCH 38
17#define KPF_UNCACHED 39 17#define KPF_UNCACHED 39
18#define KPF_SOFTDIRTY 40
18 19
19#endif /* LINUX_KERNEL_PAGE_FLAGS_H */ 20#endif /* LINUX_KERNEL_PAGE_FLAGS_H */
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
index 71c9c2511ee7..d5e9d6d185c8 100644
--- a/tools/vm/page-types.c
+++ b/tools/vm/page-types.c
@@ -59,12 +59,14 @@
59#define PM_PSHIFT_BITS 6 59#define PM_PSHIFT_BITS 6
60#define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS) 60#define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS)
61#define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET) 61#define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET)
62#define PM_PSHIFT(x) (((u64) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK) 62#define __PM_PSHIFT(x) (((uint64_t) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK)
63#define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1) 63#define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1)
64#define PM_PFRAME(x) ((x) & PM_PFRAME_MASK) 64#define PM_PFRAME(x) ((x) & PM_PFRAME_MASK)
65 65
66#define __PM_SOFT_DIRTY (1LL)
66#define PM_PRESENT PM_STATUS(4LL) 67#define PM_PRESENT PM_STATUS(4LL)
67#define PM_SWAP PM_STATUS(2LL) 68#define PM_SWAP PM_STATUS(2LL)
69#define PM_SOFT_DIRTY __PM_PSHIFT(__PM_SOFT_DIRTY)
68 70
69 71
70/* 72/*
@@ -83,6 +85,7 @@
83#define KPF_OWNER_PRIVATE 37 85#define KPF_OWNER_PRIVATE 37
84#define KPF_ARCH 38 86#define KPF_ARCH 38
85#define KPF_UNCACHED 39 87#define KPF_UNCACHED 39
88#define KPF_SOFTDIRTY 40
86 89
87/* [48-] take some arbitrary free slots for expanding overloaded flags 90/* [48-] take some arbitrary free slots for expanding overloaded flags
88 * not part of kernel API 91 * not part of kernel API
@@ -132,6 +135,7 @@ static const char * const page_flag_names[] = {
132 [KPF_OWNER_PRIVATE] = "O:owner_private", 135 [KPF_OWNER_PRIVATE] = "O:owner_private",
133 [KPF_ARCH] = "h:arch", 136 [KPF_ARCH] = "h:arch",
134 [KPF_UNCACHED] = "c:uncached", 137 [KPF_UNCACHED] = "c:uncached",
138 [KPF_SOFTDIRTY] = "f:softdirty",
135 139
136 [KPF_READAHEAD] = "I:readahead", 140 [KPF_READAHEAD] = "I:readahead",
137 [KPF_SLOB_FREE] = "P:slob_free", 141 [KPF_SLOB_FREE] = "P:slob_free",
@@ -417,7 +421,7 @@ static int bit_mask_ok(uint64_t flags)
417 return 1; 421 return 1;
418} 422}
419 423
420static uint64_t expand_overloaded_flags(uint64_t flags) 424static uint64_t expand_overloaded_flags(uint64_t flags, uint64_t pme)
421{ 425{
422 /* SLOB/SLUB overload several page flags */ 426 /* SLOB/SLUB overload several page flags */
423 if (flags & BIT(SLAB)) { 427 if (flags & BIT(SLAB)) {
@@ -433,6 +437,9 @@ static uint64_t expand_overloaded_flags(uint64_t flags)
433 if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM)) 437 if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM))
434 flags ^= BIT(RECLAIM) | BIT(READAHEAD); 438 flags ^= BIT(RECLAIM) | BIT(READAHEAD);
435 439
440 if (pme & PM_SOFT_DIRTY)
441 flags |= BIT(SOFTDIRTY);
442
436 return flags; 443 return flags;
437} 444}
438 445
@@ -448,11 +455,11 @@ static uint64_t well_known_flags(uint64_t flags)
448 return flags; 455 return flags;
449} 456}
450 457
451static uint64_t kpageflags_flags(uint64_t flags) 458static uint64_t kpageflags_flags(uint64_t flags, uint64_t pme)
452{ 459{
453 flags = expand_overloaded_flags(flags); 460 if (opt_raw)
454 461 flags = expand_overloaded_flags(flags, pme);
455 if (!opt_raw) 462 else
456 flags = well_known_flags(flags); 463 flags = well_known_flags(flags);
457 464
458 return flags; 465 return flags;
@@ -545,9 +552,9 @@ static size_t hash_slot(uint64_t flags)
545} 552}
546 553
547static void add_page(unsigned long voffset, 554static void add_page(unsigned long voffset,
548 unsigned long offset, uint64_t flags) 555 unsigned long offset, uint64_t flags, uint64_t pme)
549{ 556{
550 flags = kpageflags_flags(flags); 557 flags = kpageflags_flags(flags, pme);
551 558
552 if (!bit_mask_ok(flags)) 559 if (!bit_mask_ok(flags))
553 return; 560 return;
@@ -569,7 +576,8 @@ static void add_page(unsigned long voffset,
569#define KPAGEFLAGS_BATCH (64 << 10) /* 64k pages */ 576#define KPAGEFLAGS_BATCH (64 << 10) /* 64k pages */
570static void walk_pfn(unsigned long voffset, 577static void walk_pfn(unsigned long voffset,
571 unsigned long index, 578 unsigned long index,
572 unsigned long count) 579 unsigned long count,
580 uint64_t pme)
573{ 581{
574 uint64_t buf[KPAGEFLAGS_BATCH]; 582 uint64_t buf[KPAGEFLAGS_BATCH];
575 unsigned long batch; 583 unsigned long batch;
@@ -583,7 +591,7 @@ static void walk_pfn(unsigned long voffset,
583 break; 591 break;
584 592
585 for (i = 0; i < pages; i++) 593 for (i = 0; i < pages; i++)
586 add_page(voffset + i, index + i, buf[i]); 594 add_page(voffset + i, index + i, buf[i], pme);
587 595
588 index += pages; 596 index += pages;
589 count -= pages; 597 count -= pages;
@@ -608,7 +616,7 @@ static void walk_vma(unsigned long index, unsigned long count)
608 for (i = 0; i < pages; i++) { 616 for (i = 0; i < pages; i++) {
609 pfn = pagemap_pfn(buf[i]); 617 pfn = pagemap_pfn(buf[i]);
610 if (pfn) 618 if (pfn)
611 walk_pfn(index + i, pfn, 1); 619 walk_pfn(index + i, pfn, 1, buf[i]);
612 } 620 }
613 621
614 index += pages; 622 index += pages;
@@ -659,7 +667,7 @@ static void walk_addr_ranges(void)
659 667
660 for (i = 0; i < nr_addr_ranges; i++) 668 for (i = 0; i < nr_addr_ranges; i++)
661 if (!opt_pid) 669 if (!opt_pid)
662 walk_pfn(0, opt_offset[i], opt_size[i]); 670 walk_pfn(0, opt_offset[i], opt_size[i], 0);
663 else 671 else
664 walk_task(opt_offset[i], opt_size[i]); 672 walk_task(opt_offset[i], opt_size[i]);
665 673