Merge tag 's390-6.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-block.git] / mm / memblock.c
index 5a88d6d24d793807803139254b5804827251adf1..8c194d8afeecbd841b326eccdedd01cac6bf4f88 100644 (file)
@@ -734,6 +734,40 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size)
        return memblock_add_range(&memblock.memory, base, size, MAX_NUMNODES, 0);
 }
 
+/**
+ * memblock_validate_numa_coverage - check if amount of memory with
+ * no node ID assigned is less than a threshold
+ * @threshold_bytes: maximal number of pages that can have unassigned node
+ * ID (in bytes).
+ *
+ * A buggy firmware may report memory that does not belong to any node.
+ * Check if amount of such memory is below @threshold_bytes.
+ *
+ * Return: true on success, false on failure.
+ */
+bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_bytes)
+{
+       unsigned long nr_pages = 0;
+       unsigned long start_pfn, end_pfn, mem_size_mb;
+       int nid, i;
+
+       /* calculate lose page */
+       for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) {
+               if (nid == NUMA_NO_NODE)
+                       nr_pages += end_pfn - start_pfn;
+       }
+
+       if ((nr_pages << PAGE_SHIFT) >= threshold_bytes) {
+               mem_size_mb = memblock_phys_mem_size() >> 20;
+               pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n",
+                      (nr_pages << PAGE_SHIFT) >> 20, mem_size_mb);
+               return false;
+       }
+
+       return true;
+}
+
+
 /**
  * memblock_isolate_range - isolate given range into disjoint memblocks
  * @type: memblock type to isolate range for
@@ -2079,12 +2113,13 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end)
                 * Free the pages in the largest chunks alignment allows.
                 *
                 * __ffs() behaviour is undefined for 0. start == 0 is
-                * MAX_ORDER-aligned, set order to MAX_ORDER for the case.
+                * MAX_PAGE_ORDER-aligned, set order to MAX_PAGE_ORDER for
+                * the case.
                 */
                if (start)
-                       order = min_t(int, MAX_ORDER, __ffs(start));
+                       order = min_t(int, MAX_PAGE_ORDER, __ffs(start));
                else
-                       order = MAX_ORDER;
+                       order = MAX_PAGE_ORDER;
 
                while (start + (1UL << order) > end)
                        order--;