Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm, swap: simplify swap table sanity range check

The newly introduced helper, which checks bad slots and emptiness of a
cluster, can cover the older sanity check just fine, with a more rigorous
condition check. So merge them.

Link: https://lkml.kernel.org/r/20260218-swap-table-p3-v3-8-f4e34be021a7@tencent.com
Signed-off-by: Kairui Song <kasong@tencent.com>
Acked-by: Chris Li <chrisl@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kairui Song <ryncsn@gmail.com>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: kernel test robot <lkp@intel.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Nhat Pham <nphamcs@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Kairui Song and committed by
Andrew Morton
5dc533f7 1307442b

+9 -26
+9 -26
mm/swapfile.c
··· 459 459 * One special case is that bad slots can't be freed, so check the number of 460 460 * bad slots for swapoff, and non-swapoff path must never free bad slots. 461 461 */ 462 - static void swap_cluster_assert_empty(struct swap_cluster_info *ci, bool swapoff) 462 + static void swap_cluster_assert_empty(struct swap_cluster_info *ci, 463 + unsigned int ci_off, unsigned int nr, 464 + bool swapoff) 463 465 { 464 - unsigned int ci_off = 0, ci_end = SWAPFILE_CLUSTER; 466 + unsigned int ci_end = ci_off + nr; 465 467 unsigned long swp_tb; 466 468 int bad_slots = 0; 467 469 ··· 590 588 591 589 static void __free_cluster(struct swap_info_struct *si, struct swap_cluster_info *ci) 592 590 { 593 - swap_cluster_assert_empty(ci, false); 591 + swap_cluster_assert_empty(ci, 0, SWAPFILE_CLUSTER, false); 594 592 swap_cluster_free_table(ci); 595 593 move_cluster(si, ci, &si->free_clusters, CLUSTER_FLAG_FREE); 596 594 ci->order = 0; ··· 900 898 return true; 901 899 } 902 900 903 - /* 904 - * Currently, the swap table is not used for count tracking, just 905 - * do a sanity check here to ensure nothing leaked, so the swap 906 - * table should be empty upon freeing. 907 - */ 908 - static void swap_cluster_assert_table_empty(struct swap_cluster_info *ci, 909 - unsigned int start, unsigned int nr) 910 - { 911 - unsigned int ci_off = start % SWAPFILE_CLUSTER; 912 - unsigned int ci_end = ci_off + nr; 913 - unsigned long swp_tb; 914 - 915 - if (IS_ENABLED(CONFIG_DEBUG_VM)) { 916 - do { 917 - swp_tb = __swap_table_get(ci, ci_off); 918 - VM_WARN_ON_ONCE(!swp_tb_is_null(swp_tb)); 919 - } while (++ci_off < ci_end); 920 - } 921 - } 922 - 923 901 static bool cluster_alloc_range(struct swap_info_struct *si, 924 902 struct swap_cluster_info *ci, 925 903 struct folio *folio, ··· 925 943 if (likely(folio)) { 926 944 order = folio_order(folio); 927 945 nr_pages = 1 << order; 946 + swap_cluster_assert_empty(ci, offset % SWAPFILE_CLUSTER, nr_pages, false); 928 947 __swap_cache_add_folio(ci, folio, swp_entry(si->type, offset)); 929 948 } else if (IS_ENABLED(CONFIG_HIBERNATION)) { 930 949 order = 0; 931 950 nr_pages = 1; 932 951 WARN_ON_ONCE(si->swap_map[offset]); 933 952 si->swap_map[offset] = 1; 934 - swap_cluster_assert_table_empty(ci, offset, 1); 953 + swap_cluster_assert_empty(ci, offset % SWAPFILE_CLUSTER, 1, false); 935 954 } else { 936 955 /* Allocation without folio is only possible with hibernation */ 937 956 WARN_ON_ONCE(1); ··· 1751 1768 1752 1769 mem_cgroup_uncharge_swap(entry, nr_pages); 1753 1770 swap_range_free(si, offset, nr_pages); 1754 - swap_cluster_assert_table_empty(ci, offset, nr_pages); 1771 + swap_cluster_assert_empty(ci, offset % SWAPFILE_CLUSTER, nr_pages, false); 1755 1772 1756 1773 if (!ci->count) 1757 1774 free_cluster(si, ci); ··· 2763 2780 /* Cluster with bad marks count will have a remaining table */ 2764 2781 spin_lock(&ci->lock); 2765 2782 if (rcu_dereference_protected(ci->table, true)) { 2766 - swap_cluster_assert_empty(ci, true); 2783 + swap_cluster_assert_empty(ci, 0, SWAPFILE_CLUSTER, true); 2767 2784 swap_cluster_free_table(ci); 2768 2785 } 2769 2786 spin_unlock(&ci->lock);