|
@@ -1105,6 +1105,31 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
|
|
|
*out_nid = r->nid;
|
|
|
}
|
|
|
|
|
|
+unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn,
|
|
|
+ unsigned long max_pfn)
|
|
|
+{
|
|
|
+ struct memblock_type *type = &memblock.memory;
|
|
|
+ unsigned int right = type->cnt;
|
|
|
+ unsigned int mid, left = 0;
|
|
|
+ phys_addr_t addr = PFN_PHYS(pfn + 1);
|
|
|
+
|
|
|
+ do {
|
|
|
+ mid = (right + left) / 2;
|
|
|
+
|
|
|
+ if (addr < type->regions[mid].base)
|
|
|
+ right = mid;
|
|
|
+ else if (addr >= (type->regions[mid].base +
|
|
|
+ type->regions[mid].size))
|
|
|
+ left = mid + 1;
|
|
|
+ else {
|
|
|
+ /* addr is within the region, so pfn + 1 is valid */
|
|
|
+ return min(pfn + 1, max_pfn);
|
|
|
+ }
|
|
|
+ } while (left < right);
|
|
|
+
|
|
|
+ return min(PHYS_PFN(type->regions[right].base), max_pfn);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* memblock_set_node - set node ID on memblock regions
|
|
|
* @base: base of area to set node ID for
|