On 07.05.19 20:38, David Hildenbrand wrote:
> Only memory to be added to the buddy and to be onlined/offlined by
> user space using memory block devices needs (and should have!) memory
> block devices.
> 
> Factor out creation of memory block devices Create all devices after
> arch_add_memory() succeeded. We can later drop the want_memblock parameter,
> because it is now effectively stale.
> 
> Only after memory block devices have been added, memory can be onlined
> by user space. This implies, that memory is not visible to user space at
> all before arch_add_memory() succeeded.
> 
> Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <raf...@kernel.org>
> Cc: David Hildenbrand <da...@redhat.com>
> Cc: "mike.tra...@hpe.com" <mike.tra...@hpe.com>
> Cc: Andrew Morton <a...@linux-foundation.org>
> Cc: Ingo Molnar <mi...@kernel.org>
> Cc: Andrew Banman <andrew.ban...@hpe.com>
> Cc: Oscar Salvador <osalva...@suse.de>
> Cc: Michal Hocko <mho...@suse.com>
> Cc: Pavel Tatashin <pasha.tatas...@soleen.com>
> Cc: Qian Cai <c...@lca.pw>
> Cc: Wei Yang <richard.weiy...@gmail.com>
> Cc: Arun KS <aru...@codeaurora.org>
> Cc: Mathieu Malaterre <ma...@debian.org>
> Signed-off-by: David Hildenbrand <da...@redhat.com>
> ---
>  drivers/base/memory.c  | 70 ++++++++++++++++++++++++++----------------
>  include/linux/memory.h |  2 +-
>  mm/memory_hotplug.c    | 15 ++++-----
>  3 files changed, 53 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index 6e0cb4fda179..862c202a18ca 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -701,44 +701,62 @@ static int add_memory_block(int base_section_nr)
>       return 0;
>  }
>  
> +static void unregister_memory(struct memory_block *memory)
> +{
> +     BUG_ON(memory->dev.bus != &memory_subsys);
> +
> +     /* drop the ref. we got via find_memory_block() */
> +     put_device(&memory->dev);
> +     device_unregister(&memory->dev);
> +}
> +
>  /*
> - * need an interface for the VM to add new memory regions,
> - * but without onlining it.
> + * Create memory block devices for the given memory area. Start and size
> + * have to be aligned to memory block granularity. Memory block devices
> + * will be initialized as offline.
>   */
> -int hotplug_memory_register(int nid, struct mem_section *section)
> +int hotplug_memory_register(unsigned long start, unsigned long size)
>  {
> -     int ret = 0;
> +     unsigned long block_nr_pages = memory_block_size_bytes() >> PAGE_SHIFT;
> +     unsigned long start_pfn = PFN_DOWN(start);
> +     unsigned long end_pfn = start_pfn + (size >> PAGE_SHIFT);
> +     unsigned long pfn;
>       struct memory_block *mem;
> +     int ret = 0;
>  
> -     mutex_lock(&mem_sysfs_mutex);
> +     BUG_ON(!IS_ALIGNED(start, memory_block_size_bytes()));
> +     BUG_ON(!IS_ALIGNED(size, memory_block_size_bytes()));
>  
> -     mem = find_memory_block(section);
> -     if (mem) {
> -             mem->section_count++;
> -             put_device(&mem->dev);
> -     } else {
> -             ret = init_memory_block(&mem, section, MEM_OFFLINE);
> +     mutex_lock(&mem_sysfs_mutex);
> +     for (pfn = start_pfn; pfn != end_pfn; pfn += block_nr_pages) {
> +             mem = find_memory_block(__pfn_to_section(pfn));
> +             if (mem) {
> +                     WARN_ON_ONCE(false);
> +                     put_device(&mem->dev);
> +                     continue;
> +             }
> +             ret = init_memory_block(&mem, __pfn_to_section(pfn),
> +                                     MEM_OFFLINE);
>               if (ret)
> -                     goto out;
> -             mem->section_count++;
> +                     break;
> +             mem->section_count = memory_block_size_bytes() /
> +                                  MIN_MEMORY_BLOCK_SIZE;
> +     }
> +     if (ret) {
> +             end_pfn = pfn;
> +             for (pfn = start_pfn; pfn != end_pfn; pfn += block_nr_pages) {
> +                     mem = find_memory_block(__pfn_to_section(pfn));
> +                     if (!mem)
> +                             continue;
> +                     mem->section_count = 0;
> +                     unregister_memory(mem);
> +             }
>       }
> -
> -out:
>       mutex_unlock(&mem_sysfs_mutex);
>       return ret;
>  }
>  
> -static void
> -unregister_memory(struct memory_block *memory)
> -{
> -     BUG_ON(memory->dev.bus != &memory_subsys);
> -
> -     /* drop the ref. we got via find_memory_block() */
> -     put_device(&memory->dev);
> -     device_unregister(&memory->dev);
> -}
> -
> -void unregister_memory_section(struct mem_section *section)
> +static int remove_memory_section(struct mem_section *section)
>  {

The function change is misplaces in this patch will drop it so this
patch compiles without the other patches.


-- 

Thanks,

David / dhildenb

Reply via email to