On Fri, Jun 28, 2019 at 10:14:43AM +0530, Anshuman Khandual wrote: > This enables vmemmap_populate() and vmemmap_free() functions to incorporate > struct vmem_altmap based device memory allocation and free requests. With > this device memory with specific atlmap configuration can be hot plugged > and hot removed as ZONE_DEVICE memory on arm64 platforms. > > Cc: Catalin Marinas <catalin.marinas@xxxxxxx> > Cc: Will Deacon <will.deacon@xxxxxxx> > Cc: Mark Rutland <mark.rutland@xxxxxxx> > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > Cc: linux-kernel@xxxxxxxxxxxxxxx > > Signed-off-by: Anshuman Khandual <anshuman.khandual@xxxxxxx> > --- > arch/arm64/mm/mmu.c | 57 ++++++++++++++++++++++++++++++++++------------------- > 1 file changed, 37 insertions(+), 20 deletions(-) > > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c > index 39e18d1..8867bbd 100644 > --- a/arch/arm64/mm/mmu.c > +++ b/arch/arm64/mm/mmu.c > @@ -735,15 +735,26 @@ int kern_addr_valid(unsigned long addr) > } > > #ifdef CONFIG_MEMORY_HOTPLUG > -static void free_hotplug_page_range(struct page *page, size_t size) > +static void free_hotplug_page_range(struct page *page, size_t size, > + struct vmem_altmap *altmap) > { > - WARN_ON(!page || PageReserved(page)); > - free_pages((unsigned long)page_address(page), get_order(size)); > + if (altmap) { > + /* > + * vmemmap_populate() creates vmemmap mapping either at pte > + * or pmd level. Unmapping request at any other level would > + * be a problem. > + */ > + WARN_ON((size != PAGE_SIZE) && (size != PMD_SIZE)); > + vmem_altmap_free(altmap, size >> PAGE_SHIFT); > + } else { > + WARN_ON(!page || PageReserved(page)); > + free_pages((unsigned long)page_address(page), get_order(size)); > + } > } > > static void free_hotplug_pgtable_page(struct page *page) > { > - free_hotplug_page_range(page, PAGE_SIZE); > + free_hotplug_page_range(page, PAGE_SIZE, NULL); > } > > static void free_pte_table(pmd_t *pmdp, unsigned long addr) > @@ -807,7 +818,8 @@ static void free_pud_table(pgd_t *pgdp, unsigned long addr) > } > > static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr, > - unsigned long end, bool sparse_vmap) > + unsigned long end, bool sparse_vmap, > + struct vmem_altmap *altmap) Do you still need the sparse_vmap parameter, or can you just pass a NULL altmap pointer when sparse_vmap is false? Will