static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long start, start_pfn; struct zone *zone; int ret; start_pfn = base >> PAGE_SHIFT; if (!pfn_valid(start_pfn)) { memblock_remove(base, memblock_size); return 0; } zone = page_zone(pfn_to_page(start_pfn)); ret = __remove_pages(zone, start_pfn, memblock_size >> PAGE_SHIFT); if (ret) return ret; memblock_remove(base, memblock_size); start = (unsigned long)__va(base); ret = remove_section_mapping(start, start + memblock_size); vm_unmap_aliases(); return ret; }
int arch_remove_memory(u64 start, u64 size) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; struct zone *zone; int ret; zone = page_zone(pfn_to_page(start_pfn)); ret = __remove_pages(zone, start_pfn, nr_pages); if (ret) return ret; /* Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start); ret = remove_section_mapping(start, start + size); /* Ensure all vmalloc mappings are flushed in case they also * hit that section of memory */ vm_unmap_aliases(); resize_hpt_for_hotplug(memblock_phys_mem_size()); return ret; }
int __meminit arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; struct page *page; int ret; /* * If we have an altmap then we need to skip over any reserved PFNs * when querying the zone. */ page = pfn_to_page(start_pfn); if (altmap) page += vmem_altmap_offset(altmap); ret = __remove_pages(page_zone(page), start_pfn, nr_pages, altmap); if (ret) return ret; /* Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start); flush_inval_dcache_range(start, start + size); ret = remove_section_mapping(start, start + size); /* Ensure all vmalloc mappings are flushed in case they also * hit that section of memory */ vm_unmap_aliases(); resize_hpt_for_hotplug(memblock_phys_mem_size()); return ret; }
static int pseries_remove_memory(struct device_node *np) { const char *type; const unsigned int *my_index; const unsigned int *regs; u64 start_pfn, start; struct zone *zone; int ret = -EINVAL; /* * Check to see if we are actually removing memory */ type = of_get_property(np, "device_type", NULL); if (type == NULL || strcmp(type, "memory") != 0) return 0; /* * Find the memory index and size of the removing section */ my_index = of_get_property(np, "ibm,my-drc-index", NULL); if (!my_index) return ret; regs = of_get_property(np, "reg", NULL); if (!regs) return ret; start_pfn = section_nr_to_pfn(*my_index & 0xffff); zone = page_zone(pfn_to_page(start_pfn)); /* * Remove section mappings and sysfs entries for the * section of the memory we are removing. * * NOTE: Ideally, this should be done in generic code like * remove_memory(). But remove_memory() gets called by writing * to sysfs "state" file and we can't remove sysfs entries * while writing to it. So we have to defer it to here. */ ret = __remove_pages(zone, start_pfn, regs[3] >> PAGE_SHIFT); if (ret) return ret; /* * Update memory regions for memory remove */ lmb_remove(start_pfn << PAGE_SHIFT, regs[3]); /* * Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start_pfn << PAGE_SHIFT); ret = remove_section_mapping(start, start + regs[3]); return ret; }
static int pseries_remove_memory(u64 start, u64 size) { int ret; /* Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start); ret = remove_section_mapping(start, start + size); /* Ensure all vmalloc mappings are flushed in case they also * hit that section of memory */ vm_unmap_aliases(); return ret; }
static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long start, start_pfn; struct zone *zone; int ret; start_pfn = base >> PAGE_SHIFT; if (!pfn_valid(start_pfn)) { memblock_remove(base, memblock_size); return 0; } zone = page_zone(pfn_to_page(start_pfn)); /* * Remove section mappings and sysfs entries for the * section of the memory we are removing. * * NOTE: Ideally, this should be done in generic code like * remove_memory(). But remove_memory() gets called by writing * to sysfs "state" file and we can't remove sysfs entries * while writing to it. So we have to defer it to here. */ ret = __remove_pages(zone, start_pfn, memblock_size >> PAGE_SHIFT); if (ret) return ret; /* * Update memory regions for memory remove */ memblock_remove(base, memblock_size); /* * Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(base); ret = remove_section_mapping(start, start + memblock_size); /* Ensure all vmalloc mappings are flushed in case they also * hit that section of memory */ vm_unmap_aliases(); return ret; }