mm: swap: drop last SWAP_MAP_SHMEM flag in batch in swap_entries_put_nr()
authorKemeng Shi <shikemeng@huaweicloud.com>
Tue, 25 Mar 2025 16:25:25 +0000 (00:25 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 12 May 2025 00:48:13 +0000 (17:48 -0700)
The SWAP_MAP_SHMEM indicates last map from shmem.  Therefore we can drop
SWAP_MAP_SHMEM in batch in similar way to drop last ref count in batch.

Link: https://lkml.kernel.org/r/20250325162528.68385-6-shikemeng@huaweicloud.com
Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
Reviewed-by: Tim Chen <tim.c.chen@linux.intel.com>
Reviewed-by: Baoquan He <bhe@redhat.com>
Cc: Kairui Song <kasong@tencent.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/swapfile.c

index f8fe507be4f3525277e79890354ee3af02ff5ec2..668684dc9efa68b366e4dff9dea3f8485cb656d6 100644 (file)
@@ -192,7 +192,7 @@ static bool swap_is_last_map(struct swap_info_struct *si,
        unsigned char *map_end = map + nr_pages;
        unsigned char count = *map;
 
-       if (swap_count(count) != 1)
+       if (swap_count(count) != 1 && swap_count(count) != SWAP_MAP_SHMEM)
                return false;
 
        while (++map < map_end) {
@@ -1487,7 +1487,10 @@ static bool swap_entries_put_nr(struct swap_info_struct *si,
        unsigned char count;
        int i;
 
-       if (nr <= 1 || swap_count(data_race(si->swap_map[offset])) != 1)
+       if (nr <= 1)
+               goto fallback;
+       count = swap_count(data_race(si->swap_map[offset]));
+       if (count != 1 && count != SWAP_MAP_SHMEM)
                goto fallback;
        /* cross into another cluster */
        if (nr > SWAPFILE_CLUSTER - offset % SWAPFILE_CLUSTER)