Message ID | 20240415142448.333271-1-skseofh@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | memblock: add no-map alloc functions | expand |
Context | Check | Description |
---|---|---|
robh/checkpatch | warning | total: 60 errors, 42 warnings, 111 lines checked |
robh/patch-applied | fail | build log |
On Mon, Apr 15, 2024 at 11:24:48PM +0900, skseofh@gmail.com wrote: > From: Daero Lee <daero_le.lee@samsung.com> > > Like reserved-memory with the no-map property, there are memory regions > need to be allocated in memblock.memory marked with the > MEMBLOCK_NOMAP flag, but sholud not be allocated in memblock.reserved. Can you please explain your use case? Why do you need this functionality? > So, functions were added that find the required memory area in > memblock.memory, but do not allocate it to memblock.reserved. > > The early_init_dt_alloc_reserved_memory_arch function was modified > using the no-map alloc function. > > Signed-off-by: Daero Lee <daero_le.lee@samsung.com> > --- > drivers/of/of_reserved_mem.c | 9 +++-- > mm/memblock.c | 78 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 84 insertions(+), 3 deletions(-) > > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c > index 8236ecae2953..504f2f60689c 100644 > --- a/drivers/of/of_reserved_mem.c > +++ b/drivers/of/of_reserved_mem.c > @@ -40,15 +40,18 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, > > end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end; > align = !align ? SMP_CACHE_BYTES : align; > - base = memblock_phys_alloc_range(size, align, start, end); > + if (nomap) { > + base = memblock_phys_alloc_range_nomap(size, align, start, end); > + } else { > + base = memblock_phys_alloc_range(size, align, start, end); > + } > + This changes behaviour of internal function, what effect will it have on the users? > if (!base) > return -ENOMEM; > > *res_base = base; > if (nomap) { > err = memblock_mark_nomap(base, size); > - if (err) > - memblock_phys_free(base, size); > } > > kmemleak_ignore_phys(base);
On Mon, Apr 15, 2024 at 11:24:48PM +0900, skseofh@gmail.com wrote: >From: Daero Lee <daero_le.lee@samsung.com> > >Like reserved-memory with the no-map property, there are memory regions >need to be allocated in memblock.memory marked with the >MEMBLOCK_NOMAP flag, but sholud not be allocated in memblock.reserved. > >So, functions were added that find the required memory area in >memblock.memory, but do not allocate it to memblock.reserved. > >The early_init_dt_alloc_reserved_memory_arch function was modified >using the no-map alloc function. > >Signed-off-by: Daero Lee <daero_le.lee@samsung.com> >--- > drivers/of/of_reserved_mem.c | 9 +++-- > mm/memblock.c | 78 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 84 insertions(+), 3 deletions(-) > >diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c >index 8236ecae2953..504f2f60689c 100644 >--- a/drivers/of/of_reserved_mem.c >+++ b/drivers/of/of_reserved_mem.c >@@ -40,15 +40,18 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, > > end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end; > align = !align ? SMP_CACHE_BYTES : align; >- base = memblock_phys_alloc_range(size, align, start, end); >+ if (nomap) { >+ base = memblock_phys_alloc_range_nomap(size, align, start, end); >+ } else { >+ base = memblock_phys_alloc_range(size, align, start, end); >+ } >+ > if (!base) > return -ENOMEM; > > *res_base = base; > if (nomap) { > err = memblock_mark_nomap(base, size); >- if (err) >- memblock_phys_free(base, size); > } > > kmemleak_ignore_phys(base); >diff --git a/mm/memblock.c b/mm/memblock.c >index d09136e040d3..f103f1ecbfad 100644 >--- a/mm/memblock.c >+++ b/mm/memblock.c >@@ -1506,6 +1506,72 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, > return found; > } > >+phys_addr_t __init memblock_alloc_range_nid_nomap(phys_addr_t size, >+ phys_addr_t align, phys_addr_t start, >+ phys_addr_t end, int nid, >+ bool exact_nid) >+{ >+ enum memblock_flags flags = choose_memblock_flags(); >+ phys_addr_t found; >+ >+ if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) >+ nid = NUMA_NO_NODE; >+ >+ if (!align) { >+ /* Can't use WARNs this early in boot on powerpc */ >+ dump_stack(); >+ align = SMP_CACHE_BYTES; >+ } >+ >+again: >+ found = memblock_find_in_range_node(size, align, start, end, nid, >+ flags); >+ if (found) >+ goto done; Only find without reserve has no effect on memblock meta data. It seems run but nothing happens. What you want to achieve for this function?
On Mon, Apr 15, 2024 at 06:26:55PM +0300, Mike Rapoport wrote: [...] >> + > >This changes behaviour of internal function, what effect will it have on >the users? > >> if (!base) >> return -ENOMEM; >> >> *res_base = base; >> if (nomap) { >> err = memblock_mark_nomap(base, size); Mike One question may not directly relevant to this thread. NOMAP doesn't apply to all arch? I took a look into the direct mapping function on x86, memory_map_top_down(). It seems iterate all available pfn instead of skipping NOMAP range. >> - if (err) >> - memblock_phys_free(base, size); >> } >> >> kmemleak_ignore_phys(base); > >-- >Sincerely yours, >Mike.
On Wed, Apr 17, 2024 at 02:31:47AM +0000, Wei Yang wrote: > On Mon, Apr 15, 2024 at 06:26:55PM +0300, Mike Rapoport wrote: > [...] > >> + > > > >This changes behaviour of internal function, what effect will it have on > >the users? > > > >> if (!base) > >> return -ENOMEM; > >> > >> *res_base = base; > >> if (nomap) { > >> err = memblock_mark_nomap(base, size); > > Mike > > One question may not directly relevant to this thread. > > NOMAP doesn't apply to all arch? I took a look into the direct mapping > function on x86, memory_map_top_down(). It seems iterate all available pfn > instead of skipping NOMAP range. Right, x86 does not use NOMAP. NOMAP was introduced to ensure that device/firmware memory on arm64 does not have an alias mapping in the direct map because MMU does not allow alias mapping with different caching modes. > >> - if (err) > >> - memblock_phys_free(base, size); > >> } > >> > >> kmemleak_ignore_phys(base); > > > >-- > >Sincerely yours, > >Mike. > > -- > Wei Yang > Help you, Help me
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 8236ecae2953..504f2f60689c 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -40,15 +40,18 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end; align = !align ? SMP_CACHE_BYTES : align; - base = memblock_phys_alloc_range(size, align, start, end); + if (nomap) { + base = memblock_phys_alloc_range_nomap(size, align, start, end); + } else { + base = memblock_phys_alloc_range(size, align, start, end); + } + if (!base) return -ENOMEM; *res_base = base; if (nomap) { err = memblock_mark_nomap(base, size); - if (err) - memblock_phys_free(base, size); } kmemleak_ignore_phys(base); diff --git a/mm/memblock.c b/mm/memblock.c index d09136e040d3..f103f1ecbfad 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1506,6 +1506,72 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, return found; } +phys_addr_t __init memblock_alloc_range_nid_nomap(phys_addr_t size, + phys_addr_t align, phys_addr_t start, + phys_addr_t end, int nid, + bool exact_nid) +{ + enum memblock_flags flags = choose_memblock_flags(); + phys_addr_t found; + + if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) + nid = NUMA_NO_NODE; + + if (!align) { + /* Can't use WARNs this early in boot on powerpc */ + dump_stack(); + align = SMP_CACHE_BYTES; + } + +again: + found = memblock_find_in_range_node(size, align, start, end, nid, + flags); + if (found) + goto done; + + if (nid != NUMA_NO_NODE && !exact_nid) { + found = memblock_find_in_range_node(size, align, start, + end, NUMA_NO_NODE, + flags); + if (found) + goto done; + } + + if (flags & MEMBLOCK_MIRROR) { + flags &= ~MEMBLOCK_MIRROR; + pr_warn_ratelimited("Could not allocate %pap bytes of mirrored memory\n", + &size); + goto again; + } + + return 0; + +done: + /* + * Skip kmemleak for those places like kasan_init() and + * early_pgtable_alloc() due to high volume. + */ + if (end != MEMBLOCK_ALLOC_NOLEAKTRACE) + /* + * Memblock allocated blocks are never reported as + * leaks. This is because many of these blocks are + * only referred via the physical address which is + * not looked up by kmemleak. + */ + kmemleak_alloc_phys(found, size, 0); + + /* + * Some Virtual Machine platforms, such as Intel TDX or AMD SEV-SNP, + * require memory to be accepted before it can be used by the + * guest. + * + * Accept the memory of the allocated buffer. + */ + accept_memory(found, found + size); + + return found; +} + /** * memblock_phys_alloc_range - allocate a memory block inside specified range * @size: size of memory block to be allocated in bytes @@ -1530,6 +1596,18 @@ phys_addr_t __init memblock_phys_alloc_range(phys_addr_t size, false); } +phys_addr_t __init memblock_phys_alloc_range_nomap(phys_addr_t size, + phys_addr_t align, + phys_addr_t start, + phys_addr_t end) +{ + memblock_dbg("%s: %llu bytes align=0x%llx from=%pa max_addr=%pa %pS\n", + __func__, (u64)size, (u64)align, &start, &end, + (void *)_RET_IP_); + return memblock_alloc_range_nid_nomap(size, align, start, end, + NUMA_NO_NODE, false); +} + /** * memblock_phys_alloc_try_nid - allocate a memory block from specified NUMA node * @size: size of memory block to be allocated in bytes