Unverified Commit dc052c8e authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!9131 mm: swap: fix race between free_swap_and_cache() and swapoff()

parents 33906cb8 1d94cc34
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -1373,6 +1373,11 @@ static unsigned char __swap_entry_free_locked(struct swap_info_struct *p,
}

/*
 * Note that when only holding the PTL, swapoff might succeed immediately
 * after freeing a swap entry. Therefore, immediately after
 * __swap_entry_free(), the swap info might become stale and should not
 * be touched without a prior get_swap_device().
 *
 * Check whether swap entry is valid in the swap device.  If so,
 * return pointer to swap_info_struct, and keep the swap entry valid
 * via preventing the swap device from being swapoff, until
@@ -1899,13 +1904,19 @@ int free_swap_and_cache(swp_entry_t entry)
	if (non_swap_entry(entry))
		return 1;

	p = _swap_info_get(entry);
	p = get_swap_device(entry);
	if (p) {
		if (WARN_ON(data_race(!p->swap_map[swp_offset(entry)]))) {
			put_swap_device(p);
			return 0;
		}

		count = __swap_entry_free(p, entry);
		if (count == SWAP_HAS_CACHE &&
		    !swap_page_trans_huge_swapped(p, entry))
			__try_to_reclaim_swap(p, swp_offset(entry),
					      TTRS_UNMAPPED | TTRS_FULL);
		put_swap_device(p);
	}
	return p != NULL;
}