free_pages(tbl_vaddr, get_order(tbl_size));
free_pages((unsigned long)mem->slots, get_order(slots_size));
} else {
- memblock_free_late(__pa(mem->areas),
+ memblock_free(mem->areas,
array_size(sizeof(*mem->areas), mem->nareas));
- memblock_free_late(mem->start, tbl_size);
- memblock_free_late(__pa(mem->slots), slots_size);
+ memblock_phys_free(mem->start, tbl_size);
+ memblock_free(mem->slots, slots_size);
}
memset(mem, 0, sizeof(*mem));
*/
void __init memblock_discard(void)
{
- phys_addr_t addr, size;
+ phys_addr_t size;
+ void *addr;
if (memblock.reserved.regions != memblock_reserved_init_regions) {
- addr = __pa(memblock.reserved.regions);
+ addr = memblock.reserved.regions;
size = PAGE_ALIGN(sizeof(struct memblock_region) *
memblock.reserved.max);
if (memblock_reserved_in_slab)
- kfree(memblock.reserved.regions);
+ kfree(addr);
else
- memblock_free_late(addr, size);
+ memblock_free(addr, size);
}
if (memblock.memory.regions != memblock_memory_init_regions) {
- addr = __pa(memblock.memory.regions);
+ addr = memblock.memory.regions;
size = PAGE_ALIGN(sizeof(struct memblock_region) *
memblock.memory.max);
if (memblock_memory_in_slab)
- kfree(memblock.memory.regions);
+ kfree(addr);
else
- memblock_free_late(addr, size);
+ memblock_free(addr, size);
}
memblock_memory = NULL;
* @size: size of the boot memory block in bytes
*
* Free boot memory block previously allocated by memblock_alloc_xx() API.
- * The freeing memory will not be released to the buddy allocator.
+ * If called after the buddy allocator is available, the memory is released to
+ * the buddy allocator.
*/
void __init_memblock memblock_free(void *ptr, size_t size)
{
* @size: size of the boot memory block in bytes
*
* Free boot memory block previously allocated by memblock_phys_alloc_xx() API.
- * The freeing memory will not be released to the buddy allocator.
+ * If called after the buddy allocator is available, the memory is released to
+ * the buddy allocator.
*/
int __init_memblock memblock_phys_free(phys_addr_t base, phys_addr_t size)
{
phys_addr_t end = base + size - 1;
+ int ret;
memblock_dbg("%s: [%pa-%pa] %pS\n", __func__,
&base, &end, (void *)_RET_IP_);
kmemleak_free_part_phys(base, size);
- return memblock_remove_range(&memblock.reserved, base, size);
+ ret = memblock_remove_range(&memblock.reserved, base, size);
+
+ if (slab_is_available())
+ __free_reserved_area(base, base + size, -1);
+
+ return ret;
}
int __init_memblock __memblock_reserve(phys_addr_t base, phys_addr_t size,
return addr;
}
-/**
- * memblock_free_late - free pages directly to buddy allocator
- * @base: phys starting address of the boot memory block
- * @size: size of the boot memory block in bytes
- *
- * This is only useful when the memblock allocator has already been torn
- * down, but we are still initializing the system. Pages are released directly
- * to the buddy allocator.
- */
-void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
-{
- phys_addr_t end = base + size - 1;
-
- memblock_dbg("%s: [%pa-%pa] %pS\n",
- __func__, &base, &end, (void *)_RET_IP_);
-
- kmemleak_free_part_phys(base, size);
- __free_reserved_area(base, base + size, -1);
-}
-
/*
* Remaining API functions
*/