* [PATCH] memblocks: Move late alloc warning down to phys alloc
@ 2024-06-14 13:30 James Gowans
2024-06-18 11:02 ` Mike Rapoport
0 siblings, 1 reply; 4+ messages in thread
From: James Gowans @ 2024-06-14 13:30 UTC (permalink / raw)
To: Mike Rapoport, Andrew Morton
Cc: James Gowans, linux-mm, linux-kernel, Alex Graf
If a driver/subsystem tries to do an allocation after memblocks have
been freed and the memory handed to the buddy allocator, it will not
actually be legal to use that allocation - the buddy allocator owns the
memory. This is handled by the memblocks function which does allocations
and returns virtual addresses by printing a warning and doing a kmalloc
instead. However, the physical allocation function does not to do this
check - callers of the physical alloc function are unprotected against
mis-use.
Improve the error catching here by moving the check into the physical
allocation function which is used by the virtual addr allocation
function.
Signed-off-by: James Gowans <jgowans@amazon.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Alex Graf <graf@amazon.de>
---
mm/memblock.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/mm/memblock.c b/mm/memblock.c
index d09136e040d3..dd4f237dc1fc 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1457,6 +1457,17 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
align = SMP_CACHE_BYTES;
}
+ /*
+ * Detect any accidental use of these APIs after slab is ready, as at
+ * this moment memblock may be deinitialized already and its
+ * internal data may be destroyed (after execution of memblock_free_all)
+ */
+ if (WARN_ON_ONCE(slab_is_available())) {
+ void *vaddr = kzalloc_node(size, GFP_NOWAIT, nid);
+
+ return vaddr ? virt_to_phys(vaddr) : 0;
+ }
+
again:
found = memblock_find_in_range_node(size, align, start, end, nid,
flags);
@@ -1576,13 +1587,6 @@ static void * __init memblock_alloc_internal(
{
phys_addr_t alloc;
- /*
- * Detect any accidental use of these APIs after slab is ready, as at
- * this moment memblock may be deinitialized already and its
- * internal data may be destroyed (after execution of memblock_free_all)
- */
- if (WARN_ON_ONCE(slab_is_available()))
- return kzalloc_node(size, GFP_NOWAIT, nid);
if (max_addr > memblock.current_limit)
max_addr = memblock.current_limit;
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] memblocks: Move late alloc warning down to phys alloc
2024-06-14 13:30 [PATCH] memblocks: Move late alloc warning down to phys alloc James Gowans
@ 2024-06-18 11:02 ` Mike Rapoport
2024-06-19 7:53 ` Gowans, James
0 siblings, 1 reply; 4+ messages in thread
From: Mike Rapoport @ 2024-06-18 11:02 UTC (permalink / raw)
To: James Gowans; +Cc: Andrew Morton, linux-mm, linux-kernel, Alex Graf
On Fri, Jun 14, 2024 at 03:30:16PM +0200, James Gowans wrote:
> Subject: [PATCH] memblocks: Move late alloc warning down to phys alloc
Nit: memblock
> If a driver/subsystem tries to do an allocation after memblocks have
> been freed and the memory handed to the buddy allocator, it will not
> actually be legal to use that allocation - the buddy allocator owns the
> memory. This is handled by the memblocks function which does allocations
> and returns virtual addresses by printing a warning and doing a kmalloc
> instead. However, the physical allocation function does not to do this
> check - callers of the physical alloc function are unprotected against
> mis-use.
Did you see such misuse or this is a theoretical issue?
> Improve the error catching here by moving the check into the physical
> allocation function which is used by the virtual addr allocation
> function.
>
> Signed-off-by: James Gowans <jgowans@amazon.com>
> Cc: Mike Rapoport <rppt@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Alex Graf <graf@amazon.de>
> ---
> mm/memblock.c | 18 +++++++++++-------
> 1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/mm/memblock.c b/mm/memblock.c
> index d09136e040d3..dd4f237dc1fc 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -1457,6 +1457,17 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
> align = SMP_CACHE_BYTES;
> }
>
> + /*
> + * Detect any accidental use of these APIs after slab is ready, as at
> + * this moment memblock may be deinitialized already and its
> + * internal data may be destroyed (after execution of memblock_free_all)
> + */
> + if (WARN_ON_ONCE(slab_is_available())) {
> + void *vaddr = kzalloc_node(size, GFP_NOWAIT, nid);
> +
> + return vaddr ? virt_to_phys(vaddr) : 0;
> + }
I'd move this before alignment check.
> +
> again:
> found = memblock_find_in_range_node(size, align, start, end, nid,
> flags);
> @@ -1576,13 +1587,6 @@ static void * __init memblock_alloc_internal(
> {
> phys_addr_t alloc;
>
> - /*
> - * Detect any accidental use of these APIs after slab is ready, as at
> - * this moment memblock may be deinitialized already and its
> - * internal data may be destroyed (after execution of memblock_free_all)
> - */
> - if (WARN_ON_ONCE(slab_is_available()))
> - return kzalloc_node(size, GFP_NOWAIT, nid);
>
> if (max_addr > memblock.current_limit)
> max_addr = memblock.current_limit;
> --
> 2.34.1
>
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] memblocks: Move late alloc warning down to phys alloc
2024-06-18 11:02 ` Mike Rapoport
@ 2024-06-19 7:53 ` Gowans, James
2024-06-19 9:24 ` Mike Rapoport
0 siblings, 1 reply; 4+ messages in thread
From: Gowans, James @ 2024-06-19 7:53 UTC (permalink / raw)
To: rppt; +Cc: linux-mm, Graf (AWS), Alexander, linux-kernel, akpm
On Tue, 2024-06-18 at 14:02 +0300, Mike Rapoport wrote:
> On Fri, Jun 14, 2024 at 03:30:16PM +0200, James Gowans wrote:
> > Subject: [PATCH] memblocks: Move late alloc warning down to phys alloc
>
> Nit: memblock
Ack!
>
> > If a driver/subsystem tries to do an allocation after memblocks have
> > been freed and the memory handed to the buddy allocator, it will not
> > actually be legal to use that allocation - the buddy allocator owns the
> > memory. This is handled by the memblocks function which does allocations
> > and returns virtual addresses by printing a warning and doing a kmalloc
> > instead. However, the physical allocation function does not to do this
> > check - callers of the physical alloc function are unprotected against
> > mis-use.
>
> Did you see such misuse or this is a theoretical issue?
Yeah, I was driving the memblock allocator badly when prototyping
something. Allocating a large contiguous block of memory for an in-
memory filesystem and I was doing the allocation in an initcall, but by
that point it was too late. The memblock allocator happily gave me a
large chunk of memory, but it was already in use by the buddy allocator,
so ended up with memory corruption. Oops! Getting this warning would
have made the problem immediately obvious.
>
> > Improve the error catching here by moving the check into the physical
> > allocation function which is used by the virtual addr allocation
> > function.
> >
> > Signed-off-by: James Gowans <jgowans@amazon.com>
> > Cc: Mike Rapoport <rppt@kernel.org>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Alex Graf <graf@amazon.de>
> > ---
> > mm/memblock.c | 18 +++++++++++-------
> > 1 file changed, 11 insertions(+), 7 deletions(-)
> >
> > diff --git a/mm/memblock.c b/mm/memblock.c
> > index d09136e040d3..dd4f237dc1fc 100644
> > --- a/mm/memblock.c
> > +++ b/mm/memblock.c
> > @@ -1457,6 +1457,17 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
> > align = SMP_CACHE_BYTES;
> > }
> >
> > + /*
> > + * Detect any accidental use of these APIs after slab is ready, as at
> > + * this moment memblock may be deinitialized already and its
> > + * internal data may be destroyed (after execution of memblock_free_all)
> > + */
> > + if (WARN_ON_ONCE(slab_is_available())) {
> > + void *vaddr = kzalloc_node(size, GFP_NOWAIT, nid);
> > +
> > + return vaddr ? virt_to_phys(vaddr) : 0;
> > + }
>
> I'd move this before alignment check.
Ack, will do in V2.
Anything else or should I make the tweaks and post V2?
JG
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] memblocks: Move late alloc warning down to phys alloc
2024-06-19 7:53 ` Gowans, James
@ 2024-06-19 9:24 ` Mike Rapoport
0 siblings, 0 replies; 4+ messages in thread
From: Mike Rapoport @ 2024-06-19 9:24 UTC (permalink / raw)
To: Gowans, James; +Cc: linux-mm, Graf (AWS), Alexander, linux-kernel, akpm
On Wed, Jun 19, 2024 at 07:53:14AM +0000, Gowans, James wrote:
> On Tue, 2024-06-18 at 14:02 +0300, Mike Rapoport wrote:
> > On Fri, Jun 14, 2024 at 03:30:16PM +0200, James Gowans wrote:
> > > Subject: [PATCH] memblocks: Move late alloc warning down to phys alloc
> >
> > Nit: memblock
>
> Ack!
>
> >
> > > If a driver/subsystem tries to do an allocation after memblocks have
And another one here :) ^
> > > been freed and the memory handed to the buddy allocator, it will not
> > > actually be legal to use that allocation - the buddy allocator owns the
> > > memory. This is handled by the memblocks function which does allocations
> > > and returns virtual addresses by printing a warning and doing a kmalloc
> > > instead. However, the physical allocation function does not to do this
> > > check - callers of the physical alloc function are unprotected against
> > > mis-use.
> >
> > Did you see such misuse or this is a theoretical issue?
>
> Yeah, I was driving the memblock allocator badly when prototyping
> something. Allocating a large contiguous block of memory for an in-
> memory filesystem and I was doing the allocation in an initcall, but by
> that point it was too late. The memblock allocator happily gave me a
> large chunk of memory, but it was already in use by the buddy allocator,
> so ended up with memory corruption. Oops! Getting this warning would
> have made the problem immediately obvious.
>
> >
> > > Improve the error catching here by moving the check into the physical
> > > allocation function which is used by the virtual addr allocation
> > > function.
> > >
> > > Signed-off-by: James Gowans <jgowans@amazon.com>
> > > Cc: Mike Rapoport <rppt@kernel.org>
> > > Cc: Andrew Morton <akpm@linux-foundation.org>
> > > Cc: Alex Graf <graf@amazon.de>
> > > ---
> > > mm/memblock.c | 18 +++++++++++-------
> > > 1 file changed, 11 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/mm/memblock.c b/mm/memblock.c
> > > index d09136e040d3..dd4f237dc1fc 100644
> > > --- a/mm/memblock.c
> > > +++ b/mm/memblock.c
> > > @@ -1457,6 +1457,17 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
> > > align = SMP_CACHE_BYTES;
> > > }
> > >
> > > + /*
> > > + * Detect any accidental use of these APIs after slab is ready, as at
> > > + * this moment memblock may be deinitialized already and its
> > > + * internal data may be destroyed (after execution of memblock_free_all)
> > > + */
> > > + if (WARN_ON_ONCE(slab_is_available())) {
> > > + void *vaddr = kzalloc_node(size, GFP_NOWAIT, nid);
> > > +
> > > + return vaddr ? virt_to_phys(vaddr) : 0;
> > > + }
> >
> > I'd move this before alignment check.
>
> Ack, will do in V2.
>
> Anything else or should I make the tweaks and post V2?
Looks ok to me.
> JG
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-06-19 9:26 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-14 13:30 [PATCH] memblocks: Move late alloc warning down to phys alloc James Gowans
2024-06-18 11:02 ` Mike Rapoport
2024-06-19 7:53 ` Gowans, James
2024-06-19 9:24 ` Mike Rapoport
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox