static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) { unsigned long start, start_pfn; struct zone *zone; int ret; start_pfn = base >> PAGE_SHIFT; if (!pfn_valid(start_pfn)) { lmb_remove(base, lmb_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, lmb_size >> PAGE_SHIFT); if (ret) return ret; /* * Update memory regions for memory remove */ lmb_remove(base, lmb_size); /* * Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(base); ret = remove_section_mapping(start, start + lmb_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_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; }