* + mm-report-per-page-metadata-information.patch added to mm-unstable branch
@ 2024-02-07 23:10 Andrew Morton
2024-02-08 3:14 ` Johannes Weiner
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Morton @ 2024-02-07 23:10 UTC (permalink / raw)
To: mm-commits, yosryahmed, yang.yang29, willy, weixugc,
wangkefeng.wang, vbabka, tomas.mudrunka, surenb, shakeelb, rppt,
rdunlap, rafael, pasha.tatashin, muchun.song, Liam.Howlett,
kirill.shutemov, ivan, hannes, gregkh, david, corbet, chenlinxuan,
bhelgaas, adobriyan, souravpanda, akpm
The patch titled
Subject: mm: report per-page metadata information
has been added to the -mm mm-unstable branch. Its filename is
mm-report-per-page-metadata-information.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-report-per-page-metadata-information.patch
This patch will later appear in the mm-unstable branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days
------------------------------------------------------
From: Sourav Panda <souravpanda@google.com>
Subject: mm: report per-page metadata information
Date: Mon, 29 Jan 2024 14:42:04 -0800
Adds two new per-node fields, namely nr_page_metadata and
nr_page_metadata_boot, to /sys/devices/system/node/nodeN/vmstat and a
global PageMetadata field to /proc/meminfo. This information can be used
by users to see how much memory is being used by per-page metadata, which
can vary depending on build configuration, machine architecture, and
system use.
Per-page metadata is the amount of memory that Linux needs in order to
manage memory at the page granularity. The majority of such memory is
used by "struct page" and "page_ext" data structures. In contrast to most
other memory consumption statistics, per-page metadata might not be
included in MemTotal. For example, MemTotal does not include memblock
allocations but includes buddy allocations. In this patch, exported field
nr_page_metadata in /sys/devices/system/node/nodeN/vmstat would
exclusively track buddy allocations while nr_page_metadata_boot would
exclusively track memblock allocations. Furthermore, PageMetadata in
/proc/meminfo would exclusively track buddy allocations allowing it to be
compared against MemTotal.
This memory depends on build configurations, machine architectures, and
the way system is used:
Build configuration may include extra fields into "struct page", and
enable / disable "page_ext". Machine architecture defines base page
sizes. For example 4K x86, 8K SPARC, 64K ARM64 (optionally), etc. The
per-page metadata overhead is smaller on machines with larger page sizes.
System use can change per-page overhead by using vmemmap optimizations
with hugetlb pages, and emulated pmem devdax pages. Also, boot parameters
can determine whether page_ext is needed to be allocated. This memory can
be part of MemTotal or be outside MemTotal depending on whether the memory
was hot-plugged, booted with, or hugetlb memory was returned back to the
system.
Link: https://lkml.kernel.org/r/20240129224204.1812062-2-souravpanda@google.com
Signed-off-by: Sourav Panda <souravpanda@google.com>
Suggested-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Chen Linxuan <chenlinxuan@uniontech.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Ivan Babrou <ivan@cloudflare.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Mike Rapoport (IBM) <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Tomas Mudrunka <tomas.mudrunka@gmail.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Wei Xu <weixugc@google.com>
Cc: Yang Yang <yang.yang29@zte.com.cn>
Cc: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Documentation/filesystems/proc.rst | 3 ++
fs/proc/meminfo.c | 4 +++
include/linux/mmzone.h | 4 +++
include/linux/vmstat.h | 4 +++
mm/hugetlb_vmemmap.c | 19 ++++++++++++----
mm/mm_init.c | 5 +++-
mm/page_alloc.c | 1
mm/page_ext.c | 32 +++++++++++++++++++--------
mm/sparse-vmemmap.c | 8 ++++++
mm/sparse.c | 7 +++++
mm/vmstat.c | 26 +++++++++++++++++++++
11 files changed, 98 insertions(+), 15 deletions(-)
--- a/Documentation/filesystems/proc.rst~mm-report-per-page-metadata-information
+++ a/Documentation/filesystems/proc.rst
@@ -993,6 +993,7 @@ Example output. You may not have all of
AnonPages: 4654780 kB
Mapped: 266244 kB
Shmem: 9976 kB
+ PageMetadata: 513419 kB
KReclaimable: 517708 kB
Slab: 660044 kB
SReclaimable: 517708 kB
@@ -1095,6 +1096,8 @@ Mapped
files which have been mmapped, such as libraries
Shmem
Total memory used by shared memory (shmem) and tmpfs
+PageMetadata
+ Memory used for per-page metadata
KReclaimable
Kernel allocations that the kernel will attempt to reclaim
under memory pressure. Includes SReclaimable (below), and other
--- a/fs/proc/meminfo.c~mm-report-per-page-metadata-information
+++ a/fs/proc/meminfo.c
@@ -39,6 +39,7 @@ static int meminfo_proc_show(struct seq_
long available;
unsigned long pages[NR_LRU_LISTS];
unsigned long sreclaimable, sunreclaim;
+ unsigned long nr_page_metadata;
int lru;
si_meminfo(&i);
@@ -57,6 +58,8 @@ static int meminfo_proc_show(struct seq_
sreclaimable = global_node_page_state_pages(NR_SLAB_RECLAIMABLE_B);
sunreclaim = global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
+ nr_page_metadata = global_node_page_state_pages(NR_PAGE_METADATA);
+
show_val_kb(m, "MemTotal: ", i.totalram);
show_val_kb(m, "MemFree: ", i.freeram);
show_val_kb(m, "MemAvailable: ", available);
@@ -104,6 +107,7 @@ static int meminfo_proc_show(struct seq_
show_val_kb(m, "Mapped: ",
global_node_page_state(NR_FILE_MAPPED));
show_val_kb(m, "Shmem: ", i.sharedram);
+ show_val_kb(m, "PageMetadata: ", nr_page_metadata);
show_val_kb(m, "KReclaimable: ", sreclaimable +
global_node_page_state(NR_KERNEL_MISC_RECLAIMABLE));
show_val_kb(m, "Slab: ", sreclaimable + sunreclaim);
--- a/include/linux/mmzone.h~mm-report-per-page-metadata-information
+++ a/include/linux/mmzone.h
@@ -214,6 +214,10 @@ enum node_stat_item {
PGDEMOTE_KSWAPD,
PGDEMOTE_DIRECT,
PGDEMOTE_KHUGEPAGED,
+ NR_PAGE_METADATA, /* Page metadata size (struct page and page_ext)
+ * in pages
+ */
+ NR_PAGE_METADATA_BOOT, /* NR_PAGE_METADATA for bootmem */
NR_VM_NODE_STAT_ITEMS
};
--- a/include/linux/vmstat.h~mm-report-per-page-metadata-information
+++ a/include/linux/vmstat.h
@@ -632,4 +632,8 @@ static inline void lruvec_stat_sub_folio
{
lruvec_stat_mod_folio(folio, idx, -folio_nr_pages(folio));
}
+
+void __init mod_node_early_perpage_metadata(int nid, long delta);
+void __init store_early_perpage_metadata(void);
+
#endif /* _LINUX_VMSTAT_H */
--- a/mm/hugetlb_vmemmap.c~mm-report-per-page-metadata-information
+++ a/mm/hugetlb_vmemmap.c
@@ -184,10 +184,14 @@ static int vmemmap_remap_range(unsigned
*/
static inline void free_vmemmap_page(struct page *page)
{
- if (PageReserved(page))
+ if (PageReserved(page)) {
free_bootmem_page(page);
- else
+ mod_node_page_state(page_pgdat(page), NR_PAGE_METADATA_BOOT,
+ -1);
+ } else {
__free_page(page);
+ mod_node_page_state(page_pgdat(page), NR_PAGE_METADATA, -1);
+ }
}
/* Free a list of the vmemmap pages */
@@ -338,6 +342,7 @@ static int vmemmap_remap_free(unsigned l
copy_page(page_to_virt(walk.reuse_page),
(void *)walk.reuse_addr);
list_add(&walk.reuse_page->lru, vmemmap_pages);
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA, 1);
}
/*
@@ -384,14 +389,20 @@ static int alloc_vmemmap_page_list(unsig
unsigned long nr_pages = (end - start) >> PAGE_SHIFT;
int nid = page_to_nid((struct page *)start);
struct page *page, *next;
+ int i;
- while (nr_pages--) {
+ for (i = 0; i < nr_pages; i++) {
page = alloc_pages_node(nid, gfp_mask, 0);
- if (!page)
+ if (!page) {
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA,
+ i);
goto out;
+ }
list_add(&page->lru, list);
}
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA, nr_pages);
+
return 0;
out:
list_for_each_entry_safe(page, next, list, lru)
--- a/mm/mm_init.c~mm-report-per-page-metadata-information
+++ a/mm/mm_init.c
@@ -20,6 +20,7 @@
#include <linux/nmi.h>
#include <linux/buffer_head.h>
#include <linux/kmemleak.h>
+#include <linux/vmstat.h>
#include <linux/kfence.h>
#include <linux/page_ext.h>
#include <linux/pti.h>
@@ -1644,7 +1645,7 @@ static void __init alloc_node_mem_map(st
start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
offset = pgdat->node_start_pfn - start;
/*
- * The zone's endpoints aren't required to be MAX_PAGE_ORDER
+ * The zone's endpoints aren't required to be MAX_PAGE_ORDER
* aligned but the node_mem_map endpoints must be in order
* for the buddy allocator to function correctly.
*/
@@ -1656,6 +1657,8 @@ static void __init alloc_node_mem_map(st
panic("Failed to allocate %ld bytes for node %d memory map\n",
size, pgdat->node_id);
pgdat->node_mem_map = map + offset;
+ mod_node_early_perpage_metadata(pgdat->node_id,
+ DIV_ROUND_UP(size, PAGE_SIZE));
pr_debug("%s: node %d, pgdat %08lx, node_mem_map %08lx\n",
__func__, pgdat->node_id, (unsigned long)pgdat,
(unsigned long)pgdat->node_mem_map);
--- a/mm/page_alloc.c~mm-report-per-page-metadata-information
+++ a/mm/page_alloc.c
@@ -5638,6 +5638,7 @@ void __init setup_per_cpu_pageset(void)
for_each_online_pgdat(pgdat)
pgdat->per_cpu_nodestats =
alloc_percpu(struct per_cpu_nodestat);
+ store_early_perpage_metadata();
}
__meminit void zone_pcp_init(struct zone *zone)
--- a/mm/page_ext.c~mm-report-per-page-metadata-information
+++ a/mm/page_ext.c
@@ -201,6 +201,8 @@ static int __init alloc_node_page_ext(in
return -ENOMEM;
NODE_DATA(nid)->node_page_ext = base;
total_usage += table_size;
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA_BOOT,
+ DIV_ROUND_UP(table_size, PAGE_SIZE));
return 0;
}
@@ -255,12 +257,15 @@ static void *__meminit alloc_page_ext(si
void *addr = NULL;
addr = alloc_pages_exact_nid(nid, size, flags);
- if (addr) {
+ if (addr)
kmemleak_alloc(addr, size, 1, flags);
- return addr;
- }
+ else
+ addr = vzalloc_node(size, nid);
- addr = vzalloc_node(size, nid);
+ if (addr) {
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA,
+ DIV_ROUND_UP(size, PAGE_SIZE));
+ }
return addr;
}
@@ -303,18 +308,27 @@ static int __meminit init_section_page_e
static void free_page_ext(void *addr)
{
+ size_t table_size;
+ struct page *page;
+ struct pglist_data *pgdat;
+
+ table_size = page_ext_size * PAGES_PER_SECTION;
+
if (is_vmalloc_addr(addr)) {
+ page = vmalloc_to_page(addr);
+ pgdat = page_pgdat(page);
vfree(addr);
} else {
- struct page *page = virt_to_page(addr);
- size_t table_size;
-
- table_size = page_ext_size * PAGES_PER_SECTION;
-
+ page = virt_to_page(addr);
+ pgdat = page_pgdat(page);
BUG_ON(PageReserved(page));
kmemleak_free(addr);
free_pages_exact(addr, table_size);
}
+
+ mod_node_page_state(pgdat, NR_PAGE_METADATA,
+ -1L * (DIV_ROUND_UP(table_size, PAGE_SIZE)));
+
}
static void __free_page_ext(unsigned long pfn)
--- a/mm/sparse.c~mm-report-per-page-metadata-information
+++ a/mm/sparse.c
@@ -14,7 +14,7 @@
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/bootmem_info.h>
-
+#include <linux/vmstat.h>
#include "internal.h"
#include <asm/dma.h>
@@ -465,6 +465,9 @@ static void __init sparse_buffer_init(un
*/
sparsemap_buf = memmap_alloc(size, section_map_size(), addr, nid, true);
sparsemap_buf_end = sparsemap_buf + size;
+#ifndef CONFIG_SPARSEMEM_VMEMMAP
+ mod_node_early_perpage_metadata(nid, DIV_ROUND_UP(size, PAGE_SIZE));
+#endif
}
static void __init sparse_buffer_fini(void)
@@ -641,6 +644,8 @@ static void depopulate_section_memmap(un
unsigned long start = (unsigned long) pfn_to_page(pfn);
unsigned long end = start + nr_pages * sizeof(struct page);
+ mod_node_page_state(page_pgdat(pfn_to_page(pfn)), NR_PAGE_METADATA,
+ -1L * (DIV_ROUND_UP(end - start, PAGE_SIZE)));
vmemmap_free(start, end, altmap);
}
static void free_map_bootmem(struct page *memmap)
--- a/mm/sparse-vmemmap.c~mm-report-per-page-metadata-information
+++ a/mm/sparse-vmemmap.c
@@ -469,5 +469,13 @@ struct page * __meminit __populate_secti
if (r < 0)
return NULL;
+ if (system_state == SYSTEM_BOOTING) {
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA_BOOT,
+ DIV_ROUND_UP(end - start, PAGE_SIZE));
+ } else {
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA,
+ DIV_ROUND_UP(end - start, PAGE_SIZE));
+ }
+
return pfn_to_page(pfn);
}
--- a/mm/vmstat.c~mm-report-per-page-metadata-information
+++ a/mm/vmstat.c
@@ -1253,6 +1253,9 @@ const char * const vmstat_text[] = {
"pgdemote_direct",
"pgdemote_khugepaged",
+ "nr_page_metadata",
+ "nr_page_metadata_boot",
+
/* enum writeback_stat_item counters */
"nr_dirty_threshold",
"nr_dirty_background_threshold",
@@ -2279,4 +2282,27 @@ static int __init extfrag_debug_init(voi
}
module_init(extfrag_debug_init);
+
#endif
+
+/*
+ * Page metadata size (struct page and page_ext) in pages
+ */
+static unsigned long early_perpage_metadata[MAX_NUMNODES] __initdata;
+
+void __init mod_node_early_perpage_metadata(int nid, long delta)
+{
+ early_perpage_metadata[nid] += delta;
+}
+
+void __init store_early_perpage_metadata(void)
+{
+ int nid;
+ struct pglist_data *pgdat;
+
+ for_each_online_pgdat(pgdat) {
+ nid = pgdat->node_id;
+ mod_node_page_state(NODE_DATA(nid), NR_PAGE_METADATA_BOOT,
+ early_perpage_metadata[nid]);
+ }
+}
_
Patches currently in -mm which might be from souravpanda@google.com are
mm-report-per-page-metadata-information.patch
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: + mm-report-per-page-metadata-information.patch added to mm-unstable branch
2024-02-07 23:10 Andrew Morton
@ 2024-02-08 3:14 ` Johannes Weiner
2024-02-08 3:27 ` Yosry Ahmed
0 siblings, 1 reply; 9+ messages in thread
From: Johannes Weiner @ 2024-02-08 3:14 UTC (permalink / raw)
To: Andrew Morton
Cc: mm-commits, yosryahmed, yang.yang29, willy, weixugc,
wangkefeng.wang, vbabka, tomas.mudrunka, surenb, shakeelb, rppt,
rdunlap, rafael, pasha.tatashin, muchun.song, Liam.Howlett,
kirill.shutemov, ivan, gregkh, david, corbet, chenlinxuan,
bhelgaas, adobriyan, souravpanda
On Wed, Feb 07, 2024 at 03:10:13PM -0800, Andrew Morton wrote:
>
> The patch titled
> Subject: mm: report per-page metadata information
> has been added to the -mm mm-unstable branch. Its filename is
> mm-report-per-page-metadata-information.patch
>
> This patch will shortly appear at
> https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-report-per-page-metadata-information.patch
>
> This patch will later appear in the mm-unstable branch at
> git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
>
> Before you just go and hit "reply", please:
> a) Consider who else should be cc'ed
> b) Prefer to cc a suitable mailing list as well
> c) Ideally: find the original patch on the mailing list and do a
> reply-to-all to that, adding suitable additional cc's
>
> *** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
>
> The -mm tree is included into linux-next via the mm-everything
> branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
> and is updated there every 2-3 working days
>
> ------------------------------------------------------
> From: Sourav Panda <souravpanda@google.com>
> Subject: mm: report per-page metadata information
> Date: Mon, 29 Jan 2024 14:42:04 -0800
>
> Adds two new per-node fields, namely nr_page_metadata and
> nr_page_metadata_boot, to /sys/devices/system/node/nodeN/vmstat and a
> global PageMetadata field to /proc/meminfo. This information can be used
> by users to see how much memory is being used by per-page metadata, which
> can vary depending on build configuration, machine architecture, and
> system use.
/me wonders what page metadata is.
> Per-page metadata is the amount of memory that Linux needs in order to
> manage memory at the page granularity. The majority of such memory is
> used by "struct page" and "page_ext" data structures.
The term for this in Linux MM is "memmap".
That's what's used throughout the code, in Kconfig options, and it
shows up in the documentation as well. It's in the names of most files
and functions that adjust your new counters. The new name is
unnecessary, and frankly it's quite vague and nondescript.
Also no reason to keep the stat name intentionally "open ended". As
became clear from the side discussions on MemTotal, all proposals to
change the semantics of counters later on will be nacked on the basis
of established user expectations. So just call it what it is now.
This should be NR_MEMMAP, nr_memmap, MemMap etc.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: + mm-report-per-page-metadata-information.patch added to mm-unstable branch
2024-02-08 3:14 ` Johannes Weiner
@ 2024-02-08 3:27 ` Yosry Ahmed
2024-02-08 6:44 ` Johannes Weiner
0 siblings, 1 reply; 9+ messages in thread
From: Yosry Ahmed @ 2024-02-08 3:27 UTC (permalink / raw)
To: Johannes Weiner
Cc: Andrew Morton, mm-commits, yang.yang29, willy, weixugc,
wangkefeng.wang, vbabka, tomas.mudrunka, surenb, shakeelb, rppt,
rdunlap, rafael, pasha.tatashin, muchun.song, Liam.Howlett,
kirill.shutemov, ivan, gregkh, david, corbet, chenlinxuan,
bhelgaas, adobriyan, souravpanda
> >
> > Adds two new per-node fields, namely nr_page_metadata and
> > nr_page_metadata_boot, to /sys/devices/system/node/nodeN/vmstat and a
> > global PageMetadata field to /proc/meminfo. This information can be used
> > by users to see how much memory is being used by per-page metadata, which
> > can vary depending on build configuration, machine architecture, and
> > system use.
>
> /me wonders what page metadata is.
>
> > Per-page metadata is the amount of memory that Linux needs in order to
> > manage memory at the page granularity. The majority of such memory is
> > used by "struct page" and "page_ext" data structures.
>
> The term for this in Linux MM is "memmap".
>
> That's what's used throughout the code, in Kconfig options, and it
> shows up in the documentation as well. It's in the names of most files
> and functions that adjust your new counters. The new name is
> unnecessary, and frankly it's quite vague and nondescript.
>
> Also no reason to keep the stat name intentionally "open ended". As
> became clear from the side discussions on MemTotal, all proposals to
> change the semantics of counters later on will be nacked on the basis
> of established user expectations. So just call it what it is now.
I am not closely following this series, but I just wanted to point out
that this is not always true. We are actively extending
NR_SECONDARY_PAGETABLE to add IOMMU page tables in addition to KVM
page tables [1]. In that case as well, the name was left open-ended
exactly for this purpose [2].
[1]https://lore.kernel.org/lkml/20240207174102.1486130-11-pasha.tatashin@soleen.com/
[2]https://lore.kernel.org/lkml/20220823004639.2387269-2-yosryahmed@google.com/
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: + mm-report-per-page-metadata-information.patch added to mm-unstable branch
2024-02-08 3:27 ` Yosry Ahmed
@ 2024-02-08 6:44 ` Johannes Weiner
2024-02-08 18:08 ` Pasha Tatashin
0 siblings, 1 reply; 9+ messages in thread
From: Johannes Weiner @ 2024-02-08 6:44 UTC (permalink / raw)
To: Yosry Ahmed
Cc: Andrew Morton, mm-commits, yang.yang29, willy, weixugc,
wangkefeng.wang, vbabka, tomas.mudrunka, surenb, shakeelb, rppt,
rdunlap, rafael, pasha.tatashin, muchun.song, Liam.Howlett,
kirill.shutemov, ivan, gregkh, david, corbet, chenlinxuan,
bhelgaas, adobriyan, souravpanda
On Wed, Feb 07, 2024 at 07:27:34PM -0800, Yosry Ahmed wrote:
> > >
> > > Adds two new per-node fields, namely nr_page_metadata and
> > > nr_page_metadata_boot, to /sys/devices/system/node/nodeN/vmstat and a
> > > global PageMetadata field to /proc/meminfo. This information can be used
> > > by users to see how much memory is being used by per-page metadata, which
> > > can vary depending on build configuration, machine architecture, and
> > > system use.
> >
> > /me wonders what page metadata is.
> >
> > > Per-page metadata is the amount of memory that Linux needs in order to
> > > manage memory at the page granularity. The majority of such memory is
> > > used by "struct page" and "page_ext" data structures.
> >
> > The term for this in Linux MM is "memmap".
> >
> > That's what's used throughout the code, in Kconfig options, and it
> > shows up in the documentation as well. It's in the names of most files
> > and functions that adjust your new counters. The new name is
> > unnecessary, and frankly it's quite vague and nondescript.
> >
> > Also no reason to keep the stat name intentionally "open ended". As
> > became clear from the side discussions on MemTotal, all proposals to
> > change the semantics of counters later on will be nacked on the basis
> > of established user expectations. So just call it what it is now.
>
> I am not closely following this series, but I just wanted to point out
> that this is not always true. We are actively extending
> NR_SECONDARY_PAGETABLE to add IOMMU page tables in addition to KVM
> page tables [1]. In that case as well, the name was left open-ended
> exactly for this purpose [2].
I think you're glossing over quite some nuance here.
Sure there might be highly specific scenarios where you can get away
with it. Like with a very recently introduced counter for somewhat
niche audiences, and bucketing/grouping that was IIRC planned from the
start. It's probably not reasonable to advocate nondescript interface
names as a strategy for getting out of ABI commitments.
My point was that "memmap" is the established term for what the author
describes. And that this concept is sufficiently first-class that
mixing it with other things later is unlikely to be acceptable. I
didn't know WHY a new name for this was chosen, so I provided
arguments for two motivations that I could think of, that's all.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: + mm-report-per-page-metadata-information.patch added to mm-unstable branch
2024-02-08 6:44 ` Johannes Weiner
@ 2024-02-08 18:08 ` Pasha Tatashin
2024-02-08 23:50 ` Wei Xu
0 siblings, 1 reply; 9+ messages in thread
From: Pasha Tatashin @ 2024-02-08 18:08 UTC (permalink / raw)
To: Johannes Weiner
Cc: Yosry Ahmed, Andrew Morton, mm-commits, yang.yang29, willy,
weixugc, wangkefeng.wang, vbabka, tomas.mudrunka, surenb,
shakeelb, rppt, rdunlap, rafael, muchun.song, Liam.Howlett,
kirill.shutemov, ivan, gregkh, david, corbet, chenlinxuan,
bhelgaas, adobriyan, souravpanda
> > I am not closely following this series, but I just wanted to point out
> > that this is not always true. We are actively extending
> > NR_SECONDARY_PAGETABLE to add IOMMU page tables in addition to KVM
> > page tables [1]. In that case as well, the name was left open-ended
> > exactly for this purpose [2].
>
> I think you're glossing over quite some nuance here.
>
> Sure there might be highly specific scenarios where you can get away
> with it. Like with a very recently introduced counter for somewhat
> niche audiences, and bucketing/grouping that was IIRC planned from the
> start. It's probably not reasonable to advocate nondescript interface
> names as a strategy for getting out of ABI commitments.
>
> My point was that "memmap" is the established term for what the author
> describes. And that this concept is sufficiently first-class that
> mixing it with other things later is unlikely to be acceptable. I
> didn't know WHY a new name for this was chosen, so I provided
> arguments for two motivations that I could think of, that's all.
Sure, we can rename it to NR_MEMMAP_BOOT / NR_MEMMAP. We picked
NR_PAGE_METADATA_BOOT/NR_PAGE_METADATA as we thought it was a clearer
choice. It directly conveys the concept of page metadata overhead,
eliminating ambiguity about future potential structures. Today, it is
"struct page", and "pag_ext", tomorrow memdesc and more.
Pasha
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: + mm-report-per-page-metadata-information.patch added to mm-unstable branch
2024-02-08 18:08 ` Pasha Tatashin
@ 2024-02-08 23:50 ` Wei Xu
2024-02-09 0:25 ` Johannes Weiner
0 siblings, 1 reply; 9+ messages in thread
From: Wei Xu @ 2024-02-08 23:50 UTC (permalink / raw)
To: Pasha Tatashin
Cc: Johannes Weiner, Yosry Ahmed, Andrew Morton, mm-commits,
yang.yang29, willy, wangkefeng.wang, vbabka, tomas.mudrunka,
surenb, shakeelb, rppt, rdunlap, rafael, muchun.song,
Liam.Howlett, kirill.shutemov, ivan, gregkh, david, corbet,
chenlinxuan, bhelgaas, adobriyan, souravpanda
On Thu, Feb 8, 2024 at 10:08 AM Pasha Tatashin
<pasha.tatashin@soleen.com> wrote:
>
> > > I am not closely following this series, but I just wanted to point out
> > > that this is not always true. We are actively extending
> > > NR_SECONDARY_PAGETABLE to add IOMMU page tables in addition to KVM
> > > page tables [1]. In that case as well, the name was left open-ended
> > > exactly for this purpose [2].
> >
> > I think you're glossing over quite some nuance here.
> >
> > Sure there might be highly specific scenarios where you can get away
> > with it. Like with a very recently introduced counter for somewhat
> > niche audiences, and bucketing/grouping that was IIRC planned from the
> > start. It's probably not reasonable to advocate nondescript interface
> > names as a strategy for getting out of ABI commitments.
> >
> > My point was that "memmap" is the established term for what the author
> > describes. And that this concept is sufficiently first-class that
> > mixing it with other things later is unlikely to be acceptable. I
> > didn't know WHY a new name for this was chosen, so I provided
> > arguments for two motivations that I could think of, that's all.
>
> Sure, we can rename it to NR_MEMMAP_BOOT / NR_MEMMAP. We picked
> NR_PAGE_METADATA_BOOT/NR_PAGE_METADATA as we thought it was a clearer
> choice. It directly conveys the concept of page metadata overhead,
> eliminating ambiguity about future potential structures. Today, it is
> "struct page", and "pag_ext", tomorrow memdesc and more.
Technically, page_ext is not part of memmap if we go by the kernel code, right?
> Pasha
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: + mm-report-per-page-metadata-information.patch added to mm-unstable branch
2024-02-08 23:50 ` Wei Xu
@ 2024-02-09 0:25 ` Johannes Weiner
2024-02-09 1:21 ` Wei Xu
0 siblings, 1 reply; 9+ messages in thread
From: Johannes Weiner @ 2024-02-09 0:25 UTC (permalink / raw)
To: Wei Xu
Cc: Pasha Tatashin, Yosry Ahmed, Andrew Morton, mm-commits,
yang.yang29, willy, wangkefeng.wang, vbabka, tomas.mudrunka,
surenb, shakeelb, rppt, rdunlap, rafael, muchun.song,
Liam.Howlett, kirill.shutemov, ivan, gregkh, david, corbet,
chenlinxuan, bhelgaas, adobriyan, souravpanda
On Thu, Feb 08, 2024 at 03:50:12PM -0800, Wei Xu wrote:
> On Thu, Feb 8, 2024 at 10:08 AM Pasha Tatashin
> <pasha.tatashin@soleen.com> wrote:
> >
> > > > I am not closely following this series, but I just wanted to point out
> > > > that this is not always true. We are actively extending
> > > > NR_SECONDARY_PAGETABLE to add IOMMU page tables in addition to KVM
> > > > page tables [1]. In that case as well, the name was left open-ended
> > > > exactly for this purpose [2].
> > >
> > > I think you're glossing over quite some nuance here.
> > >
> > > Sure there might be highly specific scenarios where you can get away
> > > with it. Like with a very recently introduced counter for somewhat
> > > niche audiences, and bucketing/grouping that was IIRC planned from the
> > > start. It's probably not reasonable to advocate nondescript interface
> > > names as a strategy for getting out of ABI commitments.
> > >
> > > My point was that "memmap" is the established term for what the author
> > > describes. And that this concept is sufficiently first-class that
> > > mixing it with other things later is unlikely to be acceptable. I
> > > didn't know WHY a new name for this was chosen, so I provided
> > > arguments for two motivations that I could think of, that's all.
> >
> > Sure, we can rename it to NR_MEMMAP_BOOT / NR_MEMMAP. We picked
> > NR_PAGE_METADATA_BOOT/NR_PAGE_METADATA as we thought it was a clearer
> > choice. It directly conveys the concept of page metadata overhead,
> > eliminating ambiguity about future potential structures. Today, it is
> > "struct page", and "pag_ext", tomorrow memdesc and more.
>
> Technically, page_ext is not part of memmap if we go by the kernel code, right?
From a user POV it's the same: the fixed linear overhead of mapping
out physical memory for kernel use. struct page is the build-time
component, struct page_ext is the boot-time component, but I'd say
that distinction is mostly just an implementation detail.
If between memdesc, folio, slab etc. struct page disappears entirely
some day, "memmap" remains a valid concept and a cost of interest.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: + mm-report-per-page-metadata-information.patch added to mm-unstable branch
2024-02-09 0:25 ` Johannes Weiner
@ 2024-02-09 1:21 ` Wei Xu
0 siblings, 0 replies; 9+ messages in thread
From: Wei Xu @ 2024-02-09 1:21 UTC (permalink / raw)
To: Johannes Weiner
Cc: Pasha Tatashin, Yosry Ahmed, Andrew Morton, mm-commits,
yang.yang29, willy, wangkefeng.wang, vbabka, tomas.mudrunka,
surenb, shakeelb, rppt, rdunlap, rafael, muchun.song,
Liam.Howlett, kirill.shutemov, ivan, gregkh, david, corbet,
chenlinxuan, bhelgaas, adobriyan, souravpanda
On Thu, Feb 8, 2024 at 4:25 PM Johannes Weiner <hannes@cmpxchg.org> wrote:
>
> On Thu, Feb 08, 2024 at 03:50:12PM -0800, Wei Xu wrote:
> > On Thu, Feb 8, 2024 at 10:08 AM Pasha Tatashin
> > <pasha.tatashin@soleen.com> wrote:
> > >
> > > > > I am not closely following this series, but I just wanted to point out
> > > > > that this is not always true. We are actively extending
> > > > > NR_SECONDARY_PAGETABLE to add IOMMU page tables in addition to KVM
> > > > > page tables [1]. In that case as well, the name was left open-ended
> > > > > exactly for this purpose [2].
> > > >
> > > > I think you're glossing over quite some nuance here.
> > > >
> > > > Sure there might be highly specific scenarios where you can get away
> > > > with it. Like with a very recently introduced counter for somewhat
> > > > niche audiences, and bucketing/grouping that was IIRC planned from the
> > > > start. It's probably not reasonable to advocate nondescript interface
> > > > names as a strategy for getting out of ABI commitments.
> > > >
> > > > My point was that "memmap" is the established term for what the author
> > > > describes. And that this concept is sufficiently first-class that
> > > > mixing it with other things later is unlikely to be acceptable. I
> > > > didn't know WHY a new name for this was chosen, so I provided
> > > > arguments for two motivations that I could think of, that's all.
> > >
> > > Sure, we can rename it to NR_MEMMAP_BOOT / NR_MEMMAP. We picked
> > > NR_PAGE_METADATA_BOOT/NR_PAGE_METADATA as we thought it was a clearer
> > > choice. It directly conveys the concept of page metadata overhead,
> > > eliminating ambiguity about future potential structures. Today, it is
> > > "struct page", and "pag_ext", tomorrow memdesc and more.
> >
> > Technically, page_ext is not part of memmap if we go by the kernel code, right?
>
> From a user POV it's the same: the fixed linear overhead of mapping
> out physical memory for kernel use. struct page is the build-time
> component, struct page_ext is the boot-time component, but I'd say
> that distinction is mostly just an implementation detail.
>
> If between memdesc, folio, slab etc. struct page disappears entirely
> some day, "memmap" remains a valid concept and a cost of interest.
"memmap" is not a meaningful concept to the userspace. If we choose it
because it is well-known within the kernel code, someday some kernel
engineers may be surprised to see non-memmap overheads get reported as
"memmap".
Anyway, I don't have a strong opinion on this field name. Just want to
point out this potential issue.
^ permalink raw reply [flat|nested] 9+ messages in thread
* + mm-report-per-page-metadata-information.patch added to mm-unstable branch
@ 2024-06-11 22:30 Andrew Morton
0 siblings, 0 replies; 9+ messages in thread
From: Andrew Morton @ 2024-06-11 22:30 UTC (permalink / raw)
To: mm-commits, yosryahmed, yang.yang29, weixugc, wangkefeng.wang,
vbabka, tomas.mudrunka, surenb, shakeelb, rppt, rientjes, rdunlap,
rafael, pasha.tatashin, muchun.song, mike.kravetz, Liam.Howlett,
kirill.shutemov, ivan, hannes, gregkh, david, corbet, chenlinxuan,
bhelgaas, adobriyan, souravpanda, akpm
The patch titled
Subject: mm: report per-page metadata information
has been added to the -mm mm-unstable branch. Its filename is
mm-report-per-page-metadata-information.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-report-per-page-metadata-information.patch
This patch will later appear in the mm-unstable branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days
------------------------------------------------------
From: Sourav Panda <souravpanda@google.com>
Subject: mm: report per-page metadata information
Date: Wed, 5 Jun 2024 22:27:51 +0000
Today, we do not have any observability of per-page metadata and how much
it takes away from the machine capacity. Thus, we want to describe the
amount of memory that is going towards per-page metadata, which can vary
depending on build configuration, machine architecture, and system use.
This patch adds 2 fields to /proc/vmstat that can used as shown below:
Accounting per-page metadata allocated by boot-allocator:
/proc/vmstat:nr_memmap_boot * PAGE_SIZE
Accounting per-page metadata allocated by buddy-allocator:
/proc/vmstat:nr_memmap * PAGE_SIZE
Accounting total Perpage metadata allocated on the machine:
(/proc/vmstat:nr_memmap_boot +
/proc/vmstat:nr_memmap) * PAGE_SIZE
Utility for userspace:
Observability: Describe the amount of memory overhead that is going to
per-page metadata on the system at any given time since this overhead is
not currently observable.
Debugging: Tracking the changes or absolute value in struct pages can help
detect anomalies as they can be correlated with other metrics in the
machine (e.g., memtotal, number of huge pages, etc).
page_ext overheads: Some kernel features such as page_owner
page_table_check that use page_ext can be optionally enabled via kernel
parameters. Having the total per-page metadata information helps users
precisely measure impact. Furthermore, page-metadata metrics will reflect
the amount of struct pages reliquished (or overhead reduced) when
hugetlbfs pages are reserved which will vary depending on whether hugetlb
vmemmap optimization is enabled or not.
For background and results see:
lore.kernel.org/all/20240220214558.3377482-1-souravpanda@google.com
Link: https://lkml.kernel.org/r/20240605222751.1406125-1-souravpanda@google.com
Signed-off-by: Sourav Panda <souravpanda@google.com>
Acked-by: David Rientjes <rientjes@google.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Chen Linxuan <chenlinxuan@uniontech.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Ivan Babrou <ivan@cloudflare.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Mike Rapoport (IBM) <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Tomas Mudrunka <tomas.mudrunka@gmail.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Wei Xu <weixugc@google.com>
Cc: Yang Yang <yang.yang29@zte.com.cn>
Cc: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
include/linux/mmzone.h | 2 ++
include/linux/vmstat.h | 4 ++++
mm/hugetlb_vmemmap.c | 17 +++++++++++++----
mm/mm_init.c | 3 +++
mm/page_alloc.c | 1 +
mm/page_ext.c | 32 +++++++++++++++++++++++---------
mm/sparse-vmemmap.c | 8 ++++++++
mm/sparse.c | 7 ++++++-
mm/vmstat.c | 26 +++++++++++++++++++++++++-
9 files changed, 85 insertions(+), 15 deletions(-)
--- a/include/linux/mmzone.h~mm-report-per-page-metadata-information
+++ a/include/linux/mmzone.h
@@ -220,6 +220,8 @@ enum node_stat_item {
PGDEMOTE_KSWAPD,
PGDEMOTE_DIRECT,
PGDEMOTE_KHUGEPAGED,
+ NR_MEMMAP, /* page metadata allocated through buddy allocator */
+ NR_MEMMAP_BOOT, /* page metadata allocated through boot allocator */
NR_VM_NODE_STAT_ITEMS
};
--- a/include/linux/vmstat.h~mm-report-per-page-metadata-information
+++ a/include/linux/vmstat.h
@@ -608,4 +608,8 @@ static inline void lruvec_stat_sub_folio
{
lruvec_stat_mod_folio(folio, idx, -folio_nr_pages(folio));
}
+
+void __meminit mod_node_early_perpage_metadata(int nid, long delta);
+void __meminit store_early_perpage_metadata(void);
+
#endif /* _LINUX_VMSTAT_H */
--- a/mm/hugetlb_vmemmap.c~mm-report-per-page-metadata-information
+++ a/mm/hugetlb_vmemmap.c
@@ -184,10 +184,13 @@ static int vmemmap_remap_range(unsigned
*/
static inline void free_vmemmap_page(struct page *page)
{
- if (PageReserved(page))
+ if (PageReserved(page)) {
free_bootmem_page(page);
- else
+ mod_node_page_state(page_pgdat(page), NR_MEMMAP_BOOT, -1);
+ } else {
__free_page(page);
+ mod_node_page_state(page_pgdat(page), NR_MEMMAP, -1);
+ }
}
/* Free a list of the vmemmap pages */
@@ -338,6 +341,7 @@ static int vmemmap_remap_free(unsigned l
copy_page(page_to_virt(walk.reuse_page),
(void *)walk.reuse_addr);
list_add(&walk.reuse_page->lru, vmemmap_pages);
+ mod_node_page_state(NODE_DATA(nid), NR_MEMMAP, 1);
}
/*
@@ -384,14 +388,19 @@ static int alloc_vmemmap_page_list(unsig
unsigned long nr_pages = (end - start) >> PAGE_SHIFT;
int nid = page_to_nid((struct page *)start);
struct page *page, *next;
+ int i;
- while (nr_pages--) {
+ for (i = 0; i < nr_pages; i++) {
page = alloc_pages_node(nid, gfp_mask, 0);
- if (!page)
+ if (!page) {
+ mod_node_page_state(NODE_DATA(nid), NR_MEMMAP, i);
goto out;
+ }
list_add(&page->lru, list);
}
+ mod_node_page_state(NODE_DATA(nid), NR_MEMMAP, nr_pages);
+
return 0;
out:
list_for_each_entry_safe(page, next, list, lru)
--- a/mm/mm_init.c~mm-report-per-page-metadata-information
+++ a/mm/mm_init.c
@@ -29,6 +29,7 @@
#include <linux/cma.h>
#include <linux/crash_dump.h>
#include <linux/execmem.h>
+#include <linux/vmstat.h>
#include "internal.h"
#include "slab.h"
#include "shuffle.h"
@@ -1624,6 +1625,8 @@ static void __init alloc_node_mem_map(st
panic("Failed to allocate %ld bytes for node %d memory map\n",
size, pgdat->node_id);
pgdat->node_mem_map = map + offset;
+ mod_node_early_perpage_metadata(pgdat->node_id,
+ DIV_ROUND_UP(size, PAGE_SIZE));
pr_debug("%s: node %d, pgdat %08lx, node_mem_map %08lx\n",
__func__, pgdat->node_id, (unsigned long)pgdat,
(unsigned long)pgdat->node_mem_map);
--- a/mm/page_alloc.c~mm-report-per-page-metadata-information
+++ a/mm/page_alloc.c
@@ -5761,6 +5761,7 @@ void __init setup_per_cpu_pageset(void)
for_each_online_pgdat(pgdat)
pgdat->per_cpu_nodestats =
alloc_percpu(struct per_cpu_nodestat);
+ store_early_perpage_metadata();
}
__meminit void zone_pcp_init(struct zone *zone)
--- a/mm/page_ext.c~mm-report-per-page-metadata-information
+++ a/mm/page_ext.c
@@ -214,6 +214,8 @@ static int __init alloc_node_page_ext(in
return -ENOMEM;
NODE_DATA(nid)->node_page_ext = base;
total_usage += table_size;
+ mod_node_page_state(NODE_DATA(nid), NR_MEMMAP_BOOT,
+ DIV_ROUND_UP(table_size, PAGE_SIZE));
return 0;
}
@@ -268,12 +270,15 @@ static void *__meminit alloc_page_ext(si
void *addr = NULL;
addr = alloc_pages_exact_nid(nid, size, flags);
- if (addr) {
+ if (addr)
kmemleak_alloc(addr, size, 1, flags);
- return addr;
- }
+ else
+ addr = vzalloc_node(size, nid);
- addr = vzalloc_node(size, nid);
+ if (addr) {
+ mod_node_page_state(NODE_DATA(nid), NR_MEMMAP,
+ DIV_ROUND_UP(size, PAGE_SIZE));
+ }
return addr;
}
@@ -316,18 +321,27 @@ static int __meminit init_section_page_e
static void free_page_ext(void *addr)
{
+ size_t table_size;
+ struct page *page;
+ struct pglist_data *pgdat;
+
+ table_size = page_ext_size * PAGES_PER_SECTION;
+
if (is_vmalloc_addr(addr)) {
+ page = vmalloc_to_page(addr);
+ pgdat = page_pgdat(page);
vfree(addr);
} else {
- struct page *page = virt_to_page(addr);
- size_t table_size;
-
- table_size = page_ext_size * PAGES_PER_SECTION;
-
+ page = virt_to_page(addr);
+ pgdat = page_pgdat(page);
BUG_ON(PageReserved(page));
kmemleak_free(addr);
free_pages_exact(addr, table_size);
}
+
+ mod_node_page_state(pgdat, NR_MEMMAP,
+ -1L * (DIV_ROUND_UP(table_size, PAGE_SIZE)));
+
}
static void __free_page_ext(unsigned long pfn)
--- a/mm/sparse.c~mm-report-per-page-metadata-information
+++ a/mm/sparse.c
@@ -14,7 +14,7 @@
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/bootmem_info.h>
-
+#include <linux/vmstat.h>
#include "internal.h"
#include <asm/dma.h>
@@ -465,6 +465,9 @@ static void __init sparse_buffer_init(un
*/
sparsemap_buf = memmap_alloc(size, section_map_size(), addr, nid, true);
sparsemap_buf_end = sparsemap_buf + size;
+#ifndef CONFIG_SPARSEMEM_VMEMMAP
+ mod_node_early_perpage_metadata(nid, DIV_ROUND_UP(size, PAGE_SIZE));
+#endif
}
static void __init sparse_buffer_fini(void)
@@ -643,6 +646,8 @@ static void depopulate_section_memmap(un
unsigned long start = (unsigned long) pfn_to_page(pfn);
unsigned long end = start + nr_pages * sizeof(struct page);
+ mod_node_page_state(page_pgdat(pfn_to_page(pfn)), NR_MEMMAP,
+ -1L * (DIV_ROUND_UP(end - start, PAGE_SIZE)));
vmemmap_free(start, end, altmap);
}
static void free_map_bootmem(struct page *memmap)
--- a/mm/sparse-vmemmap.c~mm-report-per-page-metadata-information
+++ a/mm/sparse-vmemmap.c
@@ -469,5 +469,13 @@ struct page * __meminit __populate_secti
if (r < 0)
return NULL;
+ if (system_state == SYSTEM_BOOTING) {
+ mod_node_early_perpage_metadata(nid, DIV_ROUND_UP(end - start,
+ PAGE_SIZE));
+ } else {
+ mod_node_page_state(NODE_DATA(nid), NR_MEMMAP,
+ DIV_ROUND_UP(end - start, PAGE_SIZE));
+ }
+
return pfn_to_page(pfn);
}
--- a/mm/vmstat.c~mm-report-per-page-metadata-information
+++ a/mm/vmstat.c
@@ -1255,7 +1255,8 @@ const char * const vmstat_text[] = {
"pgdemote_kswapd",
"pgdemote_direct",
"pgdemote_khugepaged",
-
+ "nr_memmap",
+ "nr_memmap_boot",
/* enum writeback_stat_item counters */
"nr_dirty_threshold",
"nr_dirty_background_threshold",
@@ -2306,4 +2307,27 @@ static int __init extfrag_debug_init(voi
}
module_init(extfrag_debug_init);
+
#endif
+
+/*
+ * Page metadata size (struct page and page_ext) in pages
+ */
+static unsigned long early_perpage_metadata[MAX_NUMNODES] __meminitdata;
+
+void __meminit mod_node_early_perpage_metadata(int nid, long delta)
+{
+ early_perpage_metadata[nid] += delta;
+}
+
+void __meminit store_early_perpage_metadata(void)
+{
+ int nid;
+ struct pglist_data *pgdat;
+
+ for_each_online_pgdat(pgdat) {
+ nid = pgdat->node_id;
+ mod_node_page_state(NODE_DATA(nid), NR_MEMMAP_BOOT,
+ early_perpage_metadata[nid]);
+ }
+}
_
Patches currently in -mm which might be from souravpanda@google.com are
mm-report-per-page-metadata-information.patch
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-06-11 22:30 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-11 22:30 + mm-report-per-page-metadata-information.patch added to mm-unstable branch Andrew Morton
-- strict thread matches above, loose matches on Subject: below --
2024-02-07 23:10 Andrew Morton
2024-02-08 3:14 ` Johannes Weiner
2024-02-08 3:27 ` Yosry Ahmed
2024-02-08 6:44 ` Johannes Weiner
2024-02-08 18:08 ` Pasha Tatashin
2024-02-08 23:50 ` Wei Xu
2024-02-09 0:25 ` Johannes Weiner
2024-02-09 1:21 ` Wei Xu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.