Merge tag 'pwm/for-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[linux-2.6-microblaze.git] / mm / page_owner.c
index 590c2c8..9661d53 100644 (file)
@@ -42,13 +42,7 @@ static void init_early_allocated_pages(void);
 
 static int __init early_page_owner_param(char *buf)
 {
-       if (!buf)
-               return -EINVAL;
-
-       if (strcmp(buf, "on") == 0)
-               page_owner_enabled = true;
-
-       return 0;
+       return kstrtobool(buf, &page_owner_enabled);
 }
 early_param("page_owner", early_page_owner_param);
 
@@ -104,42 +98,30 @@ static inline struct page_owner *get_page_owner(struct page_ext *page_ext)
        return (void *)page_ext + page_owner_ops.offset;
 }
 
-static inline bool check_recursive_alloc(unsigned long *entries,
-                                        unsigned int nr_entries,
-                                        unsigned long ip)
-{
-       unsigned int i;
-
-       for (i = 0; i < nr_entries; i++) {
-               if (entries[i] == ip)
-                       return true;
-       }
-       return false;
-}
-
 static noinline depot_stack_handle_t save_stack(gfp_t flags)
 {
        unsigned long entries[PAGE_OWNER_STACK_DEPTH];
        depot_stack_handle_t handle;
        unsigned int nr_entries;
 
-       nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 2);
-
        /*
-        * We need to check recursion here because our request to
-        * stackdepot could trigger memory allocation to save new
-        * entry. New memory allocation would reach here and call
-        * stack_depot_save_entries() again if we don't catch it. There is
-        * still not enough memory in stackdepot so it would try to
-        * allocate memory again and loop forever.
+        * Avoid recursion.
+        *
+        * Sometimes page metadata allocation tracking requires more
+        * memory to be allocated:
+        * - when new stack trace is saved to stack depot
+        * - when backtrace itself is calculated (ia64)
         */
-       if (check_recursive_alloc(entries, nr_entries, _RET_IP_))
+       if (current->in_page_owner)
                return dummy_handle;
+       current->in_page_owner = 1;
 
+       nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 2);
        handle = stack_depot_save(entries, nr_entries, flags);
        if (!handle)
                handle = failure_handle;
 
+       current->in_page_owner = 0;
        return handle;
 }