Merge tag 'for-5.9/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/devic...
[linux-2.6-microblaze.git] / mm / shuffle.c
index 44406d9..9b5cd4b 100644 (file)
 #include "shuffle.h"
 
 DEFINE_STATIC_KEY_FALSE(page_alloc_shuffle_key);
-static unsigned long shuffle_state __ro_after_init;
-
-/*
- * Depending on the architecture, module parameter parsing may run
- * before, or after the cache detection. SHUFFLE_FORCE_DISABLE prevents,
- * or reverts the enabling of the shuffle implementation. SHUFFLE_ENABLE
- * attempts to turn on the implementation, but aborts if it finds
- * SHUFFLE_FORCE_DISABLE already set.
- */
-__meminit void page_alloc_shuffle(enum mm_shuffle_ctl ctl)
-{
-       if (ctl == SHUFFLE_FORCE_DISABLE)
-               set_bit(SHUFFLE_FORCE_DISABLE, &shuffle_state);
-
-       if (test_bit(SHUFFLE_FORCE_DISABLE, &shuffle_state)) {
-               if (test_and_clear_bit(SHUFFLE_ENABLE, &shuffle_state))
-                       static_branch_disable(&page_alloc_shuffle_key);
-       } else if (ctl == SHUFFLE_ENABLE
-                       && !test_and_set_bit(SHUFFLE_ENABLE, &shuffle_state))
-               static_branch_enable(&page_alloc_shuffle_key);
-}
 
 static bool shuffle_param;
 static int shuffle_show(char *buffer, const struct kernel_param *kp)
 {
-       return sprintf(buffer, "%c\n", test_bit(SHUFFLE_ENABLE, &shuffle_state)
-                       ? 'Y' : 'N');
+       return sprintf(buffer, "%c\n", shuffle_param ? 'Y' : 'N');
 }
 
 static __meminit int shuffle_store(const char *val,
@@ -47,9 +25,7 @@ static __meminit int shuffle_store(const char *val,
        if (rc < 0)
                return rc;
        if (shuffle_param)
-               page_alloc_shuffle(SHUFFLE_ENABLE);
-       else
-               page_alloc_shuffle(SHUFFLE_FORCE_DISABLE);
+               static_branch_enable(&page_alloc_shuffle_key);
        return 0;
 }
 module_param_call(shuffle, shuffle_store, shuffle_show, &shuffle_param, 0400);
@@ -58,25 +34,25 @@ module_param_call(shuffle, shuffle_store, shuffle_show, &shuffle_param, 0400);
  * For two pages to be swapped in the shuffle, they must be free (on a
  * 'free_area' lru), have the same order, and have the same migratetype.
  */
-static struct page * __meminit shuffle_valid_page(unsigned long pfn, int order)
+static struct page * __meminit shuffle_valid_page(struct zone *zone,
+                                                 unsigned long pfn, int order)
 {
-       struct page *page;
+       struct page *page = pfn_to_online_page(pfn);
 
        /*
         * Given we're dealing with randomly selected pfns in a zone we
         * need to ask questions like...
         */
 
-       /* ...is the pfn even in the memmap? */
-       if (!pfn_valid_within(pfn))
+       /* ... is the page managed by the buddy? */
+       if (!page)
                return NULL;
 
-       /* ...is the pfn in a present section or a hole? */
-       if (!pfn_in_present_section(pfn))
+       /* ... is the page assigned to the same zone? */
+       if (page_zone(page) != zone)
                return NULL;
 
        /* ...is the page free and currently on a free_area list? */
-       page = pfn_to_page(pfn);
        if (!PageBuddy(page))
                return NULL;
 
@@ -123,7 +99,7 @@ void __meminit __shuffle_zone(struct zone *z)
                 * page_j randomly selected in the span @zone_start_pfn to
                 * @spanned_pages.
                 */
-               page_i = shuffle_valid_page(i, order);
+               page_i = shuffle_valid_page(z, i, order);
                if (!page_i)
                        continue;
 
@@ -137,7 +113,7 @@ void __meminit __shuffle_zone(struct zone *z)
                        j = z->zone_start_pfn +
                                ALIGN_DOWN(get_random_long() % z->spanned_pages,
                                                order_pages);
-                       page_j = shuffle_valid_page(j, order);
+                       page_j = shuffle_valid_page(z, j, order);
                        if (page_j && page_j != page_i)
                                break;
                }