Merge tag 'devdax-for-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
[sfrench/cifs-2.6.git] / kernel / resource.c
index e81b17b53fa53aa025ccb8f12c236158cb2e61b2..92190f62ebc53438b7da8fcd2845c7590f002e03 100644 (file)
@@ -382,7 +382,7 @@ static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
                                 int (*func)(struct resource *, void *))
 {
        struct resource res;
-       int ret = -1;
+       int ret = -EINVAL;
 
        while (start < end &&
               !find_next_iomem_res(start, end, flags, desc, first_lvl, &res)) {
@@ -452,6 +452,9 @@ int walk_mem_res(u64 start, u64 end, void *arg,
  * This function calls the @func callback against all memory ranges of type
  * System RAM which are marked as IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY.
  * It is to be used only for System RAM.
+ *
+ * This will find System RAM ranges that are children of top-level resources
+ * in addition to top-level System RAM resources.
  */
 int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
                          void *arg, int (*func)(unsigned long, unsigned long, void *))
@@ -460,14 +463,14 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
        unsigned long flags;
        struct resource res;
        unsigned long pfn, end_pfn;
-       int ret = -1;
+       int ret = -EINVAL;
 
        start = (u64) start_pfn << PAGE_SHIFT;
        end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
        flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
        while (start < end &&
               !find_next_iomem_res(start, end, flags, IORES_DESC_NONE,
-                                   true, &res)) {
+                                   false, &res)) {
                pfn = (res.start + PAGE_SIZE - 1) >> PAGE_SHIFT;
                end_pfn = (res.end + 1) >> PAGE_SHIFT;
                if (end_pfn > pfn)
@@ -1128,6 +1131,15 @@ struct resource * __request_region(struct resource *parent,
                conflict = __request_resource(parent, res);
                if (!conflict)
                        break;
+               /*
+                * mm/hmm.c reserves physical addresses which then
+                * become unavailable to other users.  Conflicts are
+                * not expected.  Warn to aid debugging if encountered.
+                */
+               if (conflict->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY) {
+                       pr_warn("Unaddressable device %s %pR conflicts with %pR",
+                               conflict->name, conflict, res);
+               }
                if (conflict != parent) {
                        if (!(conflict->flags & IORESOURCE_BUSY)) {
                                parent = conflict;