swapfile: get rid of volatile and avoid redundant read
authorKairui Song <kasong@tencent.com>
Mon, 19 Dec 2022 18:58:37 +0000 (02:58 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 19 Jan 2023 01:12:44 +0000 (17:12 -0800)
Patch series "Clean up and fixes for swap", v2.

This series cleans up some code paths, saves a few cycles and reduces the
object size by a bit.  It also fixes some rare race issue with statistics.

This patch (of 4):

Convert a volatile variable to more readable READ_ONCE.  And this actually
avoids the code from reading the variable twice redundantly when it races.

Link: https://lkml.kernel.org/r/20221219185840.25441-1-ryncsn@gmail.com
Link: https://lkml.kernel.org/r/20221219185840.25441-2-ryncsn@gmail.com
Signed-off-by: Kairui Song <kasong@tencent.com>
Reviewed-by: "Huang, Ying" <ying.huang@intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/swapfile.c

index 908a529..6d3f60b 100644 (file)
@@ -1835,13 +1835,13 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
        pte_t *pte;
        struct swap_info_struct *si;
        int ret = 0;
-       volatile unsigned char *swap_map;
 
        si = swap_info[type];
        pte = pte_offset_map(pmd, addr);
        do {
                struct folio *folio;
                unsigned long offset;
+               unsigned char swp_count;
 
                if (!is_swap_pte(*pte))
                        continue;
@@ -1852,7 +1852,6 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
 
                offset = swp_offset(entry);
                pte_unmap(pte);
-               swap_map = &si->swap_map[offset];
                folio = swap_cache_get_folio(entry, vma, addr);
                if (!folio) {
                        struct page *page;
@@ -1869,8 +1868,10 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
                                folio = page_folio(page);
                }
                if (!folio) {
-                       if (*swap_map == 0 || *swap_map == SWAP_MAP_BAD)
+                       swp_count = READ_ONCE(si->swap_map[offset]);
+                       if (swp_count == 0 || swp_count == SWAP_MAP_BAD)
                                goto try_next;
+
                        return -ENOMEM;
                }