mm, swap, get_swap_pages: use entry_size instead of cluster in parameter
authorHuang Ying <ying.huang@intel.com>
Wed, 22 Aug 2018 04:52:20 +0000 (21:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Aug 2018 17:52:44 +0000 (10:52 -0700)
As suggested by Matthew Wilcox, it is better to use "int entry_size"
instead of "bool cluster" as parameter to specify whether to operate for
huge or normal swap entries.  Because this improve the flexibility to
support other swap entry size.  And Dave Hansen thinks that this
improves code readability too.

So in this patch, the "bool cluster" parameter of get_swap_pages() is
replaced by "int entry_size".

And nr_swap_entries() trick is used to reduce the binary size when
!CONFIG_TRANSPARENT_HUGE_PAGE.

       text    data     bss     dec     hex filename
base  24215    2028     340   26583    67d7 mm/swapfile.o
head  24123    2004     340   26467    6763 mm/swapfile.o

Link: http://lkml.kernel.org/r/20180720071845.17920-7-ying.huang@intel.com
Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
Suggested-by: Matthew Wilcox <willy@infradead.org>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Daniel Jordan <daniel.m.jordan@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Shaohua Li <shli@kernel.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/swap.h
mm/swap_slots.c
mm/swapfile.c

index 1a8bd05a335ed787b29142913035eacef7c36273..8e2c11e692baf9bba6380d63888cfbf5a206cf0b 100644 (file)
@@ -447,7 +447,7 @@ extern void si_swapinfo(struct sysinfo *);
 extern swp_entry_t get_swap_page(struct page *page);
 extern void put_swap_page(struct page *page, swp_entry_t entry);
 extern swp_entry_t get_swap_page_of_type(int);
-extern int get_swap_pages(int n, bool cluster, swp_entry_t swp_entries[]);
+extern int get_swap_pages(int n, swp_entry_t swp_entries[], int entry_size);
 extern int add_swap_count_continuation(swp_entry_t, gfp_t);
 extern void swap_shmem_alloc(swp_entry_t);
 extern int swap_duplicate(swp_entry_t);
index 008ccb22fee6c3057fffa1fd3f0713767614cbfb..63a7b4563a57ee3367b8963b1219323a4d3b28c9 100644 (file)
@@ -269,8 +269,8 @@ static int refill_swap_slots_cache(struct swap_slots_cache *cache)
 
        cache->cur = 0;
        if (swap_slot_cache_active)
-               cache->nr = get_swap_pages(SWAP_SLOTS_CACHE_SIZE, false,
-                                          cache->slots);
+               cache->nr = get_swap_pages(SWAP_SLOTS_CACHE_SIZE,
+                                          cache->slots, 1);
 
        return cache->nr;
 }
@@ -316,7 +316,7 @@ swp_entry_t get_swap_page(struct page *page)
 
        if (PageTransHuge(page)) {
                if (IS_ENABLED(CONFIG_THP_SWAP))
-                       get_swap_pages(1, true, &entry);
+                       get_swap_pages(1, &entry, HPAGE_PMD_NR);
                goto out;
        }
 
@@ -350,7 +350,7 @@ repeat:
                        goto out;
        }
 
-       get_swap_pages(1, false, &entry);
+       get_swap_pages(1, &entry, 1);
 out:
        if (mem_cgroup_try_charge_swap(page, entry)) {
                put_swap_page(page, entry);
index 043645e7f0b5892ffa004cdca2d85deaecfd4674..b30dd0642ccf76bd38ceedc10235f0fabe0dbba8 100644 (file)
@@ -940,18 +940,18 @@ static unsigned long scan_swap_map(struct swap_info_struct *si,
 
 }
 
-int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[])
+int get_swap_pages(int n_goal, swp_entry_t swp_entries[], int entry_size)
 {
-       unsigned long nr_pages = cluster ? SWAPFILE_CLUSTER : 1;
+       unsigned long size = swap_entry_size(entry_size);
        struct swap_info_struct *si, *next;
        long avail_pgs;
        int n_ret = 0;
        int node;
 
        /* Only single cluster request supported */
-       WARN_ON_ONCE(n_goal > 1 && cluster);
+       WARN_ON_ONCE(n_goal > 1 && size == SWAPFILE_CLUSTER);
 
-       avail_pgs = atomic_long_read(&nr_swap_pages) / nr_pages;
+       avail_pgs = atomic_long_read(&nr_swap_pages) / size;
        if (avail_pgs <= 0)
                goto noswap;
 
@@ -961,7 +961,7 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[])
        if (n_goal > avail_pgs)
                n_goal = avail_pgs;
 
-       atomic_long_sub(n_goal * nr_pages, &nr_swap_pages);
+       atomic_long_sub(n_goal * size, &nr_swap_pages);
 
        spin_lock(&swap_avail_lock);
 
@@ -988,14 +988,14 @@ start_over:
                        spin_unlock(&si->lock);
                        goto nextsi;
                }
-               if (cluster) {
+               if (size == SWAPFILE_CLUSTER) {
                        if (!(si->flags & SWP_FILE))
                                n_ret = swap_alloc_cluster(si, swp_entries);
                } else
                        n_ret = scan_swap_map_slots(si, SWAP_HAS_CACHE,
                                                    n_goal, swp_entries);
                spin_unlock(&si->lock);
-               if (n_ret || cluster)
+               if (n_ret || size == SWAPFILE_CLUSTER)
                        goto check_out;
                pr_debug("scan_swap_map of si %d failed to find offset\n",
                        si->type);
@@ -1021,7 +1021,7 @@ nextsi:
 
 check_out:
        if (n_ret < n_goal)
-               atomic_long_add((long)(n_goal - n_ret) * nr_pages,
+               atomic_long_add((long)(n_goal - n_ret) * size,
                                &nr_swap_pages);
 noswap:
        return n_ret;