Commit ba518f4d authored by Huang Ying's avatar Huang Ying Committed by Andrew Morton

mm,swap: simplify VMA based swap readahead window calculation

Replace PFNs with addresses in readahead window calculation.  This
simplified the logic and reduce the code line number.

No functionality change is expected.

Link: https://lkml.kernel.org/r/20240531081230.310128-4-ying.huang@intel.comSigned-off-by: default avatar"Huang, Ying" <ying.huang@intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Yang Shi <shy828301@gmail.com>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Kairui Song <kasong@tencent.com>
Cc: Barry Song <v-songbaohua@oppo.com>
Cc: Chris Li <chrisl@kernel.org>
Cc: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent dce08dd2
...@@ -741,54 +741,40 @@ void exit_swap_address_space(unsigned int type) ...@@ -741,54 +741,40 @@ void exit_swap_address_space(unsigned int type)
swapper_spaces[type] = NULL; swapper_spaces[type] = NULL;
} }
static unsigned short swap_vma_ra_win(struct vm_fault *vmf, static int swap_vma_ra_win(struct vm_fault *vmf, unsigned long *start,
unsigned short *offset, unsigned long *end)
unsigned short *nr_pte)
{ {
struct vm_area_struct *vma = vmf->vma; struct vm_area_struct *vma = vmf->vma;
unsigned long ra_val; unsigned long ra_val;
unsigned long faddr, pfn, fpfn, lpfn, rpfn; unsigned long faddr, prev_faddr, left, right;
unsigned long start, end;
unsigned int max_win, hits, prev_win, win; unsigned int max_win, hits, prev_win, win;
max_win = 1 << min_t(unsigned int, READ_ONCE(page_cluster), max_win = 1 << min(READ_ONCE(page_cluster), SWAP_RA_ORDER_CEILING);
SWAP_RA_ORDER_CEILING);
if (max_win == 1) if (max_win == 1)
return 1; return 1;
faddr = vmf->address; faddr = vmf->address;
fpfn = PFN_DOWN(faddr);
ra_val = GET_SWAP_RA_VAL(vma); ra_val = GET_SWAP_RA_VAL(vma);
pfn = PFN_DOWN(SWAP_RA_ADDR(ra_val)); prev_faddr = SWAP_RA_ADDR(ra_val);
prev_win = SWAP_RA_WIN(ra_val); prev_win = SWAP_RA_WIN(ra_val);
hits = SWAP_RA_HITS(ra_val); hits = SWAP_RA_HITS(ra_val);
win = __swapin_nr_pages(pfn, fpfn, hits, max_win, prev_win); win = __swapin_nr_pages(PFN_DOWN(prev_faddr), PFN_DOWN(faddr), hits,
atomic_long_set(&vma->swap_readahead_info, max_win, prev_win);
SWAP_RA_VAL(faddr, win, 0)); atomic_long_set(&vma->swap_readahead_info, SWAP_RA_VAL(faddr, win, 0));
if (win == 1) if (win == 1)
return 1; return 1;
if (fpfn == pfn + 1) { if (faddr == prev_faddr + PAGE_SIZE)
lpfn = fpfn; left = faddr;
rpfn = fpfn + win; else if (prev_faddr == faddr + PAGE_SIZE)
} else if (pfn == fpfn + 1) { left = faddr - (win << PAGE_SHIFT) + PAGE_SIZE;
lpfn = fpfn - win + 1; else
rpfn = fpfn + 1; left = faddr - (((win - 1) / 2) << PAGE_SHIFT);
} else { right = left + (win << PAGE_SHIFT);
unsigned int left = (win - 1) / 2; if ((long)left < 0)
left = 0;
lpfn = fpfn - left; *start = max3(left, vma->vm_start, faddr & PMD_MASK);
rpfn = fpfn + win - left; *end = min3(right, vma->vm_end, (faddr & PMD_MASK) + PMD_SIZE);
}
if ((long)lpfn < 0)
lpfn = 0;
start = max3(lpfn, PFN_DOWN(vma->vm_start),
PFN_DOWN(faddr & PMD_MASK));
end = min3(rpfn, PFN_DOWN(vma->vm_end),
PFN_DOWN((faddr & PMD_MASK) + PMD_SIZE));
*nr_pte = end - start;
*offset = fpfn - start;
return win; return win;
} }
...@@ -816,22 +802,20 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask, ...@@ -816,22 +802,20 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask,
struct swap_iocb *splug = NULL; struct swap_iocb *splug = NULL;
struct folio *folio; struct folio *folio;
pte_t *pte = NULL, pentry; pte_t *pte = NULL, pentry;
unsigned long addr; int win;
unsigned long start, end, addr;
swp_entry_t entry; swp_entry_t entry;
pgoff_t ilx; pgoff_t ilx;
unsigned int i;
bool page_allocated; bool page_allocated;
unsigned short win, nr_pte, offset;
win = swap_vma_ra_win(vmf, &offset, &nr_pte); win = swap_vma_ra_win(vmf, &start, &end);
if (win == 1) if (win == 1)
goto skip; goto skip;
addr = vmf->address - offset * PAGE_SIZE; ilx = targ_ilx - PFN_DOWN(vmf->address - start);
ilx = targ_ilx - offset;
blk_start_plug(&plug); blk_start_plug(&plug);
for (i = 0; i < nr_pte; i++, ilx++, addr += PAGE_SIZE) { for (addr = start; addr < end; ilx++, addr += PAGE_SIZE) {
if (!pte++) { if (!pte++) {
pte = pte_offset_map(vmf->pmd, addr); pte = pte_offset_map(vmf->pmd, addr);
if (!pte) if (!pte)
...@@ -851,7 +835,7 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask, ...@@ -851,7 +835,7 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask,
continue; continue;
if (page_allocated) { if (page_allocated) {
swap_read_folio(folio, false, &splug); swap_read_folio(folio, false, &splug);
if (i != offset) { if (addr != vmf->address) {
folio_set_readahead(folio); folio_set_readahead(folio);
count_vm_event(SWAP_RA); count_vm_event(SWAP_RA);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment