diff mbox series

[v1] drivers/base/memory: add memory block to memory group after registration succeeded

Message ID 20220128144540.153902-1-david@redhat.com (mailing list archive)
State New
Headers show
Series [v1] drivers/base/memory: add memory block to memory group after registration succeeded | expand

Commit Message

David Hildenbrand Jan. 28, 2022, 2:45 p.m. UTC
If register_memory() fails, we freed the memory block but already added
the memory block to the group list, not good. Let's defer adding the
block to the memory group to after registering the memory block device.

We do handle it properly during unregister_memory(), but that's not
called when the registration fails.

Fixes: 028fc57a1c36 ("drivers/base/memory: introduce "memory groups" to logically group memory blocks")
Cc: stable@vger.kernel.org # v5.15+
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 drivers/base/memory.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Comments

Oscar Salvador Jan. 31, 2022, 5:52 a.m. UTC | #1
On Fri, Jan 28, 2022 at 03:45:40PM +0100, David Hildenbrand wrote:
> If register_memory() fails, we freed the memory block but already added
> the memory block to the group list, not good. Let's defer adding the
> block to the memory group to after registering the memory block device.
> 
> We do handle it properly during unregister_memory(), but that's not
> called when the registration fails.
> 
> Fixes: 028fc57a1c36 ("drivers/base/memory: introduce "memory groups" to logically group memory blocks")
> Cc: stable@vger.kernel.org # v5.15+
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Oscar Salvador <osalvador@suse.de>
> Signed-off-by: David Hildenbrand <david@redhat.com>

Reviewed-by: Oscar Salvador <osalvador@suse.de>
Andrew Morton Feb. 1, 2022, 1:01 a.m. UTC | #2
On Fri, 28 Jan 2022 15:45:40 +0100 David Hildenbrand <david@redhat.com> wrote:

> If register_memory() fails, we freed the memory block but already added
> the memory block to the group list, not good. Let's defer adding the
> block to the memory group to after registering the memory block device.
> 
> We do handle it properly during unregister_memory(), but that's not
> called when the registration fails.
> 

I guess this has never been known to happen.  So I queued the fix for
5.18-rc1, cc:stable.
David Hildenbrand Feb. 1, 2022, 8:16 a.m. UTC | #3
On 01.02.22 02:01, Andrew Morton wrote:
> On Fri, 28 Jan 2022 15:45:40 +0100 David Hildenbrand <david@redhat.com> wrote:
> 
>> If register_memory() fails, we freed the memory block but already added
>> the memory block to the group list, not good. Let's defer adding the
>> block to the memory group to after registering the memory block device.
>>
>> We do handle it properly during unregister_memory(), but that's not
>> called when the registration fails.
>>
> 
> I guess this has never been known to happen.  So I queued the fix for
> 5.18-rc1, cc:stable.

Triggering that registration error is fairly hard, usually we fail
memory hotplug because we fail to allocate the (largish) memmap. So I am
not aware that this BUG actually triggered.
Michal Hocko Feb. 1, 2022, 12:10 p.m. UTC | #4
On Mon 31-01-22 17:01:23, Andrew Morton wrote:
> On Fri, 28 Jan 2022 15:45:40 +0100 David Hildenbrand <david@redhat.com> wrote:
> 
> > If register_memory() fails, we freed the memory block but already added
> > the memory block to the group list, not good. Let's defer adding the
> > block to the memory group to after registering the memory block device.
> > 
> > We do handle it properly during unregister_memory(), but that's not
> > called when the registration fails.
> > 
> 
> I guess this has never been known to happen.  So I queued the fix for
> 5.18-rc1, cc:stable.

I do not think this is worth stable backporting. Chances of a failure
are pretty small and I am not aware of any existing report.
Michal Hocko Feb. 1, 2022, 12:11 p.m. UTC | #5
On Fri 28-01-22 15:45:40, David Hildenbrand wrote:
> If register_memory() fails, we freed the memory block but already added
> the memory block to the group list, not good. Let's defer adding the
> block to the memory group to after registering the memory block device.
> 
> We do handle it properly during unregister_memory(), but that's not
> called when the registration fails.
> 
> Fixes: 028fc57a1c36 ("drivers/base/memory: introduce "memory groups" to logically group memory blocks")
> Cc: stable@vger.kernel.org # v5.15+
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Oscar Salvador <osalvador@suse.de>
> Signed-off-by: David Hildenbrand <david@redhat.com>

Acked-by: Michal Hocko <mhocko@suse.com>

Thanks!

> ---
>  drivers/base/memory.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index 365cd4a7f239..60c38f9cf1a7 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -663,14 +663,16 @@ static int init_memory_block(unsigned long block_id, unsigned long state,
>  	mem->nr_vmemmap_pages = nr_vmemmap_pages;
>  	INIT_LIST_HEAD(&mem->group_next);
>  
> +	ret = register_memory(mem);
> +	if (ret)
> +		return ret;
> +
>  	if (group) {
>  		mem->group = group;
>  		list_add(&mem->group_next, &group->memory_blocks);
>  	}
>  
> -	ret = register_memory(mem);
> -
> -	return ret;
> +	return 0;
>  }
>  
>  static int add_memory_block(unsigned long base_section_nr)
> -- 
> 2.34.1
diff mbox series

Patch

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 365cd4a7f239..60c38f9cf1a7 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -663,14 +663,16 @@  static int init_memory_block(unsigned long block_id, unsigned long state,
 	mem->nr_vmemmap_pages = nr_vmemmap_pages;
 	INIT_LIST_HEAD(&mem->group_next);
 
+	ret = register_memory(mem);
+	if (ret)
+		return ret;
+
 	if (group) {
 		mem->group = group;
 		list_add(&mem->group_next, &group->memory_blocks);
 	}
 
-	ret = register_memory(mem);
-
-	return ret;
+	return 0;
 }
 
 static int add_memory_block(unsigned long base_section_nr)