]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - mm/kmemleak.c
UBUNTU: SAUCE: s390/mm: fix local TLB flushing vs. detach of an mm address space
[mirror_ubuntu-zesty-kernel.git] / mm / kmemleak.c
index 086292f7c59d1a69881068758150c2140feb8253..da343695302277208c8a933e5c3f27d0bbfe49aa 100644 (file)
@@ -19,7 +19,7 @@
  *
  *
  * For more information on the algorithm and kmemleak usage, please see
- * Documentation/kmemleak.txt.
+ * Documentation/dev-tools/kmemleak.rst.
  *
  * Notes on locking
  * ----------------
@@ -90,6 +90,8 @@
 #include <linux/cache.h>
 #include <linux/percpu.h>
 #include <linux/hardirq.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
 #include <linux/mmzone.h>
 #include <linux/slab.h>
 #include <linux/thread_info.h>
@@ -1121,6 +1123,51 @@ void __ref kmemleak_no_scan(const void *ptr)
 }
 EXPORT_SYMBOL(kmemleak_no_scan);
 
+/**
+ * kmemleak_alloc_phys - similar to kmemleak_alloc but taking a physical
+ *                      address argument
+ */
+void __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, int min_count,
+                              gfp_t gfp)
+{
+       if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
+               kmemleak_alloc(__va(phys), size, min_count, gfp);
+}
+EXPORT_SYMBOL(kmemleak_alloc_phys);
+
+/**
+ * kmemleak_free_part_phys - similar to kmemleak_free_part but taking a
+ *                          physical address argument
+ */
+void __ref kmemleak_free_part_phys(phys_addr_t phys, size_t size)
+{
+       if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
+               kmemleak_free_part(__va(phys), size);
+}
+EXPORT_SYMBOL(kmemleak_free_part_phys);
+
+/**
+ * kmemleak_not_leak_phys - similar to kmemleak_not_leak but taking a physical
+ *                         address argument
+ */
+void __ref kmemleak_not_leak_phys(phys_addr_t phys)
+{
+       if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
+               kmemleak_not_leak(__va(phys));
+}
+EXPORT_SYMBOL(kmemleak_not_leak_phys);
+
+/**
+ * kmemleak_ignore_phys - similar to kmemleak_ignore but taking a physical
+ *                       address argument
+ */
+void __ref kmemleak_ignore_phys(phys_addr_t phys)
+{
+       if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
+               kmemleak_ignore(__va(phys));
+}
+EXPORT_SYMBOL(kmemleak_ignore_phys);
+
 /*
  * Update an object's checksum and return true if it was modified.
  */
@@ -1367,6 +1414,7 @@ static void kmemleak_scan(void)
        /* data/bss scanning */
        scan_large_block(_sdata, _edata);
        scan_large_block(__bss_start, __bss_stop);
+       scan_large_block(__start_data_ro_after_init, __end_data_ro_after_init);
 
 #ifdef CONFIG_SMP
        /* per-cpu sections scanning */
@@ -1406,8 +1454,11 @@ static void kmemleak_scan(void)
 
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
-                       scan_block(task_stack_page(p), task_stack_page(p) +
-                                  THREAD_SIZE, NULL);
+                       void *stack = try_get_task_stack(p);
+                       if (stack) {
+                               scan_block(stack, stack + THREAD_SIZE, NULL);
+                               put_task_stack(p);
+                       }
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
        }