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

Commit c2e43a22 authored by Laura Abbott's avatar Laura Abbott Committed by Prasad Sodagudi
Browse files

fs: fuse: Workaround for CMA migration



The FUSE file system may hold references to pages for long
periods of time, preventing migration from occurring. If a CMA
page is used here, CMA allocations may fail. Work around this
by swapping out a CMA page for a non-CMA page when working with
the FUSE file system.

Change-Id: Id763ea833ee125c8732ae3759ec9e20d94aa8424
Signed-off-by: default avatarLaura Abbott <lauraa@codeaurora.org>
Signed-off-by: default avatarPrasad Sodagudi <psodagud@codeaurora.org>
parent 630fdcc6
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -900,6 +900,41 @@ static int fuse_readpages_fill(void *_data, struct page *page)
		return -EIO;
	}

#ifdef CONFIG_CMA
	if (is_cma_pageblock(page)) {
		struct page *oldpage = page, *newpage;
		int err;

		/* make sure that old page is not free in-between the calls */
		page_cache_get(oldpage);

		newpage = alloc_page(GFP_HIGHUSER);
		if (!newpage) {
			page_cache_release(oldpage);
			return -ENOMEM;
		}

		err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL);
		if (err) {
			__free_page(newpage);
			page_cache_release(oldpage);
			return err;
		}

		/*
		 * Decrement the count on new page to make page cache the only
		 * owner of it
		 */
		lock_page(newpage);
		put_page(newpage);

		/* finally release the old page and swap pointers */
		unlock_page(oldpage);
		page_cache_release(oldpage);
		page = newpage;
	}
#endif

	page_cache_get(page);
	req->pages[req->num_pages] = page;
	req->page_descs[req->num_pages].length = PAGE_SIZE;