From: Baoquan He <hidden> Date: 2024-03-18 14:21:52
In function free_area_init_core(), the code calculating
zone->managed_pages and the subtracting dma_reserve from DMA zone looks
very confusing.
From git history, the code calculating zone->managed_pages was for
zone->present_pages originally. The early rough assignment is for
optimize zone's pcp and water mark setting. Later, managed_pages was
introduced into zone to represent the number of managed pages by buddy.
Now, zone->managed_pages is zeroed out and reset in mem_init() when
calling memblock_free_all(). zone's pcp and wmark setting relying on
actual zone->managed_pages are done later than mem_init() invocation.
So we don't need rush to early calculate and set zone->managed_pages,
just set it as zone->present_pages, will adjust it in mem_init().
And also add a new function calc_nr_kernel_pages() to count up free but
not reserved pages in memblock, then assign it to nr_all_pages and
nr_kernel_pages after memmap pages are allocated.
Baoquan He (6):
mm/mm_init.c: remove the useless dma_reserve
x86: remove unneeded memblock_find_dma_reserve()
mm/mm_init.c: add new function calc_nr_all_pages()
mm/mm_init.c: remove meaningless calculation of zone->managed_pages in
free_area_init_core()
mm/mm_init.c: remove unneeded calc_memmap_size()
mm/mm_init.c: remove arch_reserved_kernel_pages()
arch/powerpc/include/asm/mmu.h | 4 --
arch/powerpc/kernel/fadump.c | 5 --
arch/x86/include/asm/pgtable.h | 1 -
arch/x86/kernel/setup.c | 2 -
arch/x86/mm/init.c | 47 -------------
include/linux/mm.h | 4 --
mm/mm_init.c | 117 +++++++++------------------------
7 files changed, 30 insertions(+), 150 deletions(-)
--
2.41.0
From: Baoquan He <hidden> Date: 2024-03-18 14:21:57
Variable dma_reserve and its usage was introduced in commit 0e0b864e069c
("[PATCH] Account for memmap and optionally the kernel image as holes").
Its original purpose was to accounting for the reserved pages in DMA
zone to make DMA zone's watermarks calculation more accurate on x86.
However, currently there's zone->managed_pages to account for all
available pages for buddy, zone->present_pages to account for all
present physical pages in zone. What is more important, on x86,
calculating and setting the zone->managed_pages is a temporary move,
all zone's managed_pages will be zeroed out and reset to the actual
value according to how many pages are added to buddy allocator in
mem_init(). Before mem_init(), no buddy alloction is requested. And
zone's pcp and watermark setting are all done after mem_init(). So,
no need to worry about the DMA zone's setting accuracy during
free_area_init().
Hence, remove dma_reserve and its handling in free_area_init_core()
because it's useless and causes confusion.
Signed-off-by: Baoquan He <redacted>
---
arch/x86/mm/init.c | 2 --
include/linux/mm.h | 1 -
mm/mm_init.c | 23 -----------------------
3 files changed, 26 deletions(-)
@@ -3210,7 +3210,6 @@ static inline int early_pfn_to_nid(unsigned long pfn)externint__meminitearly_pfn_to_nid(unsignedlongpfn);#endif-externvoidset_dma_reserve(unsignedlongnew_dma_reserve);externvoidmem_init(void);externvoid__initmmap_init(void);
From: Baoquan He <hidden> Date: 2024-03-18 14:22:01
This is not needed any more.
Signed-off-by: Baoquan He <redacted>
---
arch/x86/include/asm/pgtable.h | 1 -
arch/x86/kernel/setup.c | 2 --
arch/x86/mm/init.c | 45 ----------------------------------
3 files changed, 48 deletions(-)
From: Baoquan He <hidden> Date: 2024-03-18 14:22:05
This is a preparation to calculate nr_kernel_pages and nr_all_pages,
both of which will be used later in alloc_large_system_hash().
nr_all_pages counts up all free but not reserved memory in memblock
allocator, including HIGHMEM memory. While nr_kernel_pages counts up
all free but not reserved low memory in memblock allocator, excluding
HIGHMEM memory.
Signed-off-by: Baoquan He <redacted>
---
mm/mm_init.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
From: Baoquan He <hidden> Date: 2024-03-18 14:22:09
Currently, in free_area_init_core(), when initialize zone's field, a
rough value is set to zone->managed_pages. That value is calculated by
(zone->present_pages - memmap_pages).
In the meantime, add the value to nr_all_pages and nr_kernel_pages which
represent all free pages of system (only low memory or including HIGHMEM
memory separately). Both of them are gonna be used in
alloc_large_system_hash().
However, the rough calculation and setting of zone->managed_pages is
meaningless because
a) memmap pages are allocated on units of node in sparse_init() or
alloc_node_mem_map(pgdat); The simple (zone->present_pages -
memmap_pages) is too rough to make sense for zone;
b) the set zone->managed_pages will be zeroed out and reset with
acutal value in mem_init() via memblock_free_all(). Before the
resetting, no buddy allocation request is issued.
Here, remove the meaningless and complicated calculation of
(zone->present_pages - memmap_pages), directly set zone->present_pages to
zone->managed_pages. It will be adjusted in mem_init().
And also remove the assignment of nr_all_pages and nr_kernel_pages in
free_area_init_core(). Instead, call the newly added calc_nr_kernel_pages()
to count up all free but not reserved memory in memblock and assign to
nr_all_pages and nr_kernel_pages. The counting excludes memmap_pages,
and other kernel used data, which is more accurate than old way and
simpler, and can also cover the ppc required arch_reserved_kernel_pages()
case.
Signed-off-by: Baoquan He <redacted>
---
mm/mm_init.c | 38 ++++++--------------------------------
1 file changed, 6 insertions(+), 32 deletions(-)
@@ -1584,41 +1584,14 @@ static void __init free_area_init_core(struct pglist_data *pgdat)for(j=0;j<MAX_NR_ZONES;j++){structzone*zone=pgdat->node_zones+j;-unsignedlongsize,freesize,memmap_pages;--size=zone->spanned_pages;-freesize=zone->present_pages;--/*-*Adjustfreesizesothatitaccountsforhowmuchmemory-*isusedbythiszoneformemmap.Thisaffectsthewatermark-*andper-cpuinitialisations-*/-memmap_pages=calc_memmap_size(size,freesize);-if(!is_highmem_idx(j)){-if(freesize>=memmap_pages){-freesize-=memmap_pages;-if(memmap_pages)-pr_debug(" %s zone: %lu pages used for memmap\n",-zone_names[j],memmap_pages);-}else-pr_warn(" %s zone: %lu memmap pages exceeds freesize %lu\n",-zone_names[j],memmap_pages,freesize);-}--if(!is_highmem_idx(j))-nr_kernel_pages+=freesize;-/* Charge for highmem memmap if there are enough kernel pages */-elseif(nr_kernel_pages>memmap_pages*2)-nr_kernel_pages-=memmap_pages;-nr_all_pages+=freesize;+unsignedlongsize=zone->spanned_pages;/*-*Setanapproximatevalueforlowmemhere,itwillbeadjusted-*whenthebootmemallocatorfreespagesintothebuddysystem.-*Andallhighmempageswillbemanagedbythebuddysystem.+*Setthezone->managed_pagesaszone->present_pagesroughly,it+*bezeroedoutandresetwhenmemblockallocatorfreespagesinto+*buddysystem.*/-zone_init_internals(zone,j,nid,freesize);+zone_init_internals(zone,j,nid,zone->present_pages);if(!size)continue;
@@ -1915,6 +1888,7 @@ void __init free_area_init(unsigned long *max_zone_pfn)check_for_memory(pgdat);}+calc_nr_kernel_pages();memmap_init();/* disable hash distribution for systems with a single node */
From: Baoquan He <hidden> Date: 2024-03-18 14:22:16
Since the current calculation of calc_nr_kernel_pages() has taken into
consideration of kernel reserved memory, no need to have
arch_reserved_kernel_pages() any more.
Signed-off-by: Baoquan He <redacted>
---
arch/powerpc/include/asm/mmu.h | 4 ----
arch/powerpc/kernel/fadump.c | 5 -----
include/linux/mm.h | 3 ---
mm/mm_init.c | 12 ------------
4 files changed, 24 deletions(-)
From: Mike Rapoport <rppt@kernel.org> Date: 2024-03-19 15:50:25
Hi Baoquan,
On Mon, Mar 18, 2024 at 10:21:34PM +0800, Baoquan He wrote:
This is not needed any more.
I'd swap this and the first patch, so that the first patch would remove
memblock_find_dma_reserve() and it's changelog will explain why it's not
needed and then the second patch will simply drop unused set_dma_reserve()
From: Mike Rapoport <rppt@kernel.org> Date: 2024-03-19 16:18:13
On Mon, Mar 18, 2024 at 10:21:36PM +0800, Baoquan He wrote:
Currently, in free_area_init_core(), when initialize zone's field, a
rough value is set to zone->managed_pages. That value is calculated by
(zone->present_pages - memmap_pages).
In the meantime, add the value to nr_all_pages and nr_kernel_pages which
represent all free pages of system (only low memory or including HIGHMEM
memory separately). Both of them are gonna be used in
alloc_large_system_hash().
However, the rough calculation and setting of zone->managed_pages is
meaningless because
a) memmap pages are allocated on units of node in sparse_init() or
alloc_node_mem_map(pgdat); The simple (zone->present_pages -
memmap_pages) is too rough to make sense for zone;
b) the set zone->managed_pages will be zeroed out and reset with
acutal value in mem_init() via memblock_free_all(). Before the
resetting, no buddy allocation request is issued.
Here, remove the meaningless and complicated calculation of
(zone->present_pages - memmap_pages), directly set zone->present_pages to
zone->managed_pages. It will be adjusted in mem_init().
Do you mean "set zone->managed_pages to zone->present_pages"?
I think we can just set zone->managed_pages to 0 in free_area_init_core().
Anyway it will be reset before the first use.
quoted hunk
And also remove the assignment of nr_all_pages and nr_kernel_pages in
free_area_init_core(). Instead, call the newly added calc_nr_kernel_pages()
to count up all free but not reserved memory in memblock and assign to
nr_all_pages and nr_kernel_pages. The counting excludes memmap_pages,
and other kernel used data, which is more accurate than old way and
simpler, and can also cover the ppc required arch_reserved_kernel_pages()
case.
Signed-off-by: Baoquan He <redacted>
---
mm/mm_init.c | 38 ++++++--------------------------------
1 file changed, 6 insertions(+), 32 deletions(-)
@@ -1584,41 +1584,14 @@ static void __init free_area_init_core(struct pglist_data *pgdat)for(j=0;j<MAX_NR_ZONES;j++){structzone*zone=pgdat->node_zones+j;-unsignedlongsize,freesize,memmap_pages;--size=zone->spanned_pages;-freesize=zone->present_pages;--/*-*Adjustfreesizesothatitaccountsforhowmuchmemory-*isusedbythiszoneformemmap.Thisaffectsthewatermark-*andper-cpuinitialisations-*/-memmap_pages=calc_memmap_size(size,freesize);-if(!is_highmem_idx(j)){-if(freesize>=memmap_pages){-freesize-=memmap_pages;-if(memmap_pages)-pr_debug(" %s zone: %lu pages used for memmap\n",-zone_names[j],memmap_pages);-}else-pr_warn(" %s zone: %lu memmap pages exceeds freesize %lu\n",-zone_names[j],memmap_pages,freesize);-}--if(!is_highmem_idx(j))-nr_kernel_pages+=freesize;-/* Charge for highmem memmap if there are enough kernel pages */-elseif(nr_kernel_pages>memmap_pages*2)-nr_kernel_pages-=memmap_pages;-nr_all_pages+=freesize;+unsignedlongsize=zone->spanned_pages;/*-*Setanapproximatevalueforlowmemhere,itwillbeadjusted-*whenthebootmemallocatorfreespagesintothebuddysystem.-*Andallhighmempageswillbemanagedbythebuddysystem.+*Setthezone->managed_pagesaszone->present_pagesroughly,it+*bezeroedoutandresetwhenmemblockallocatorfreespagesinto+*buddysystem.*/-zone_init_internals(zone,j,nid,freesize);+zone_init_internals(zone,j,nid,zone->present_pages);if(!size)continue;
@@ -1915,6 +1888,7 @@ void __init free_area_init(unsigned long *max_zone_pfn)check_for_memory(pgdat);}+calc_nr_kernel_pages();memmap_init();/* disable hash distribution for systems with a single node */
From: Baoquan He <hidden> Date: 2024-03-20 07:53:04
On 03/19/24 at 05:49pm, Mike Rapoport wrote:
Hi Baoquan,
On Mon, Mar 18, 2024 at 10:21:34PM +0800, Baoquan He wrote:
quoted
This is not needed any more.
I'd swap this and the first patch, so that the first patch would remove
memblock_find_dma_reserve() and it's changelog will explain why it's not
needed and then the second patch will simply drop unused set_dma_reserve()
Thanks, Mike.
My thought on the patch 1/2 splitting is:
patch 1 is removing all relevant codes in mm, including the usage of
dma_reserve in free_area_init_core() and exporting set_dma_reserve()
to any ARCH which want to subtract the dma_reserve from DMA zone.
Patch 2 purely remove the code in x86 ARCH about how to get dma_reserve.
Your suggestion is also good to me, I can rearrange the order and
repost.
From: Baoquan He <hidden> Date: 2024-03-20 08:18:31
On 03/19/24 at 06:17pm, Mike Rapoport wrote:
On Mon, Mar 18, 2024 at 10:21:36PM +0800, Baoquan He wrote:
quoted
Currently, in free_area_init_core(), when initialize zone's field, a
rough value is set to zone->managed_pages. That value is calculated by
(zone->present_pages - memmap_pages).
In the meantime, add the value to nr_all_pages and nr_kernel_pages which
represent all free pages of system (only low memory or including HIGHMEM
memory separately). Both of them are gonna be used in
alloc_large_system_hash().
However, the rough calculation and setting of zone->managed_pages is
meaningless because
a) memmap pages are allocated on units of node in sparse_init() or
alloc_node_mem_map(pgdat); The simple (zone->present_pages -
memmap_pages) is too rough to make sense for zone;
b) the set zone->managed_pages will be zeroed out and reset with
acutal value in mem_init() via memblock_free_all(). Before the
resetting, no buddy allocation request is issued.
Here, remove the meaningless and complicated calculation of
(zone->present_pages - memmap_pages), directly set zone->present_pages to
zone->managed_pages. It will be adjusted in mem_init().
Do you mean "set zone->managed_pages to zone->present_pages"?
Hmm, maybe 'set zone->managed_pages as zone->present_pages'
or
'assign zone->present_pages to zone->managed_pages'
which is more precise.
Wwill update.
I think we can just set zone->managed_pages to 0 in free_area_init_core().
Anyway it will be reset before the first use.
Yeah, setting to 0 is also fine. I thougt of 0 ever. Considering
zone->present_pages is closer value to actual zone->managed_pages
than 0, and it may be needed in the future in some way before
mem_init(). If no strong objection, I will keep the assigning
'zone->present_pages' to 'zone->managed_pages'.
Thanks again for careful reviewing.
From: Baoquan He <hidden> Date: 2024-03-20 08:47:34
On 03/20/24 at 04:18pm, Baoquan He wrote:
On 03/19/24 at 06:17pm, Mike Rapoport wrote:
quoted
On Mon, Mar 18, 2024 at 10:21:36PM +0800, Baoquan He wrote:
quoted
Currently, in free_area_init_core(), when initialize zone's field, a
rough value is set to zone->managed_pages. That value is calculated by
(zone->present_pages - memmap_pages).
In the meantime, add the value to nr_all_pages and nr_kernel_pages which
represent all free pages of system (only low memory or including HIGHMEM
memory separately). Both of them are gonna be used in
alloc_large_system_hash().
However, the rough calculation and setting of zone->managed_pages is
meaningless because
a) memmap pages are allocated on units of node in sparse_init() or
alloc_node_mem_map(pgdat); The simple (zone->present_pages -
memmap_pages) is too rough to make sense for zone;
b) the set zone->managed_pages will be zeroed out and reset with
acutal value in mem_init() via memblock_free_all(). Before the
resetting, no buddy allocation request is issued.
Here, remove the meaningless and complicated calculation of
(zone->present_pages - memmap_pages), directly set zone->present_pages to
zone->managed_pages. It will be adjusted in mem_init().
Do you mean "set zone->managed_pages to zone->present_pages"?
Hmm, maybe 'set zone->managed_pages as zone->present_pages'
or
'assign zone->present_pages to zone->managed_pages'
which is more precise.
Wwill update.
quoted
I think we can just set zone->managed_pages to 0 in free_area_init_core().
Anyway it will be reset before the first use.
Rethink about this, it's better to set zone->managed_pages to 0 because
there isn't any page added to buddy. Will update.
Yeah, setting to 0 is also fine. I thougt of 0 ever. Considering
zone->present_pages is closer value to actual zone->managed_pages
than 0, and it may be needed in the future in some way before
mem_init(). If no strong objection, I will keep the assigning
'zone->present_pages' to 'zone->managed_pages'.
Thanks again for careful reviewing.
From: Mike Rapoport <rppt@kernel.org> Date: 2024-03-20 09:37:57
On Wed, Mar 20, 2024 at 03:52:52PM +0800, Baoquan He wrote:
On 03/19/24 at 05:49pm, Mike Rapoport wrote:
quoted
Hi Baoquan,
On Mon, Mar 18, 2024 at 10:21:34PM +0800, Baoquan He wrote:
quoted
This is not needed any more.
I'd swap this and the first patch, so that the first patch would remove
memblock_find_dma_reserve() and it's changelog will explain why it's not
needed and then the second patch will simply drop unused set_dma_reserve()
Thanks, Mike.
My thought on the patch 1/2 splitting is:
patch 1 is removing all relevant codes in mm, including the usage of
dma_reserve in free_area_init_core() and exporting set_dma_reserve()
to any ARCH which want to subtract the dma_reserve from DMA zone.
Patch 2 purely remove the code in x86 ARCH about how to get dma_reserve.
I think it's better first to remove the usage of set_dma_reserve() in x86
and then clean up the unused code.
Your suggestion is also good to me, I can rearrange the order and
repost.
From: Baoquan He <hidden> Date: 2024-03-20 13:14:38
On 03/20/24 at 11:36am, Mike Rapoport wrote:
On Wed, Mar 20, 2024 at 03:52:52PM +0800, Baoquan He wrote:
quoted
On 03/19/24 at 05:49pm, Mike Rapoport wrote:
quoted
Hi Baoquan,
On Mon, Mar 18, 2024 at 10:21:34PM +0800, Baoquan He wrote:
quoted
This is not needed any more.
I'd swap this and the first patch, so that the first patch would remove
memblock_find_dma_reserve() and it's changelog will explain why it's not
needed and then the second patch will simply drop unused set_dma_reserve()
Thanks, Mike.
My thought on the patch 1/2 splitting is:
patch 1 is removing all relevant codes in mm, including the usage of
dma_reserve in free_area_init_core() and exporting set_dma_reserve()
to any ARCH which want to subtract the dma_reserve from DMA zone.
Patch 2 purely remove the code in x86 ARCH about how to get dma_reserve.
I think it's better first to remove the usage of set_dma_reserve() in x86
and then clean up the unused code.
OK, firslty remove the only user, that sounds reasonable. Will change.
Thanks.