Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aaa96242 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mm: fix the race between swapin_readahead and SWP_SYNCHRONOUS_IO path"

parents d06a1f65 e3231594
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -3078,6 +3078,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
	struct page *page = NULL, *swapcache;
	struct mem_cgroup *memcg;
	swp_entry_t entry;
	struct swap_info_struct *si;
	bool skip_swapcache = false;
	pte_t pte;
	int locked;
	int exclusive = 0;
@@ -3119,15 +3121,24 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)


	delayacct_set_flag(DELAYACCT_PF_SWAPIN);

	/*
	 * lookup_swap_cache below can fail and before the SWP_SYNCHRONOUS_IO
	 * check is made, another process can populate the swapcache, delete
	 * the swap entry and decrement the swap count. So decide on taking
	 * the SWP_SYNCHRONOUS_IO path before the lookup. In the event of the
	 * race described, the victim process will find a swap_count > 1
	 * and can then take the readahead path instead of SWP_SYNCHRONOUS_IO.
	 */
	si = swp_swap_info(entry);
	if (si->flags & SWP_SYNCHRONOUS_IO && __swap_count(si, entry) == 1)
		skip_swapcache = true;

	page = lookup_swap_cache(entry, vma, vmf->address);
	swapcache = page;

	if (!page) {
		struct swap_info_struct *si = swp_swap_info(entry);

		if (si->flags & SWP_SYNCHRONOUS_IO &&
				__swap_count(si, entry) == 1) {
			/* skip swapcache */
		if (skip_swapcache) {
			page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
							vmf->address);
			if (page) {