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

Commit bc7c6b9d authored by Minchan Kim's avatar Minchan Kim Committed by TARKZiM
Browse files

mm: Enhance per process reclaim to consider shared pages



Some pages could be shared by several processes. (ex, libc)
In case of that, it's too bad to reclaim them from the beginnig.

This patch causes VM to keep them on memory until last task
try to reclaim them so shared pages will be reclaimed only if
all of task has gone swapping out.

This feature doesn't handle non-linear mapping on ramfs because
it's very time-consuming and doesn't make sure of reclaiming and
not common.

Change-Id: I7e5f34f2e947f5db6d405867fe2ad34863ca40f7
Signed-off-by: default avatarSangseok Lee <sangseok.lee@lge.com>
Signed-off-by: default avatarMinchan Kim <minchan@kernel.org>
Patch-mainline: linux-mm @ 9 May 2013 16:21:27
[vinmenon@codeaurora.org: trivial merge conflict fixes]
Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent 8b713415
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1243,7 +1243,7 @@ cont:
			break;
	}
	pte_unmap_unlock(pte - 1, ptl);
	reclaim_pages_from_list(&page_list);
	reclaim_pages_from_list(&page_list, vma);
	if (addr != end)
		goto cont;

+4 −2
Original line number Diff line number Diff line
@@ -75,7 +75,8 @@ struct page *ksm_might_need_to_copy(struct page *page,

int page_referenced_ksm(struct page *page,
			struct mem_cgroup *memcg, unsigned long *vm_flags);
int try_to_unmap_ksm(struct page *page, enum ttu_flags flags);
int try_to_unmap_ksm(struct page *page,
			enum ttu_flags flags, struct vm_area_struct *vma);
int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *,
		  struct vm_area_struct *, unsigned long, void *), void *arg);
void ksm_migrate_page(struct page *newpage, struct page *oldpage);
@@ -115,7 +116,8 @@ static inline int page_referenced_ksm(struct page *page,
	return 0;
}

static inline int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
static inline int try_to_unmap_ksm(struct page *page,
			enum ttu_flags flags, struct vm_area_struct *target_vma)
{
	return 0;
}
+5 −3
Original line number Diff line number Diff line
@@ -12,7 +12,8 @@

extern int isolate_lru_page(struct page *page);
extern void putback_lru_page(struct page *page);
extern unsigned long reclaim_pages_from_list(struct list_head *page_list);
extern unsigned long reclaim_pages_from_list(struct list_head *page_list,
					     struct vm_area_struct *vma);

/*
 * The anon_vma heads a list of private "related" vmas, to scan if
@@ -192,7 +193,8 @@ int page_referenced_one(struct page *, struct vm_area_struct *,

#define TTU_ACTION(x) ((x) & TTU_ACTION_MASK)

int try_to_unmap(struct page *, enum ttu_flags flags);
int try_to_unmap(struct page *, enum ttu_flags flags,
			struct vm_area_struct *vma);
int try_to_unmap_one(struct page *, struct vm_area_struct *,
			unsigned long address, enum ttu_flags flags);

@@ -259,7 +261,7 @@ static inline int page_referenced(struct page *page, int is_locked,
	return 0;
}

#define try_to_unmap(page, refs) SWAP_FAIL
#define try_to_unmap(page, refs, vma) SWAP_FAIL

static inline int page_mkclean(struct page *page)
{
+0 −2
Original line number Diff line number Diff line
@@ -284,10 +284,8 @@ static inline void mlock_migrate_page(struct page *newpage, struct page *page)

extern pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma);

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
extern unsigned long vma_address(struct page *page,
				 struct vm_area_struct *vma);
#endif
#else /* !CONFIG_MMU */
static inline int mlocked_vma_newpage(struct vm_area_struct *v, struct page *p)
{
+8 −1
Original line number Diff line number Diff line
@@ -2004,7 +2004,8 @@ out:
	return referenced;
}

int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
int try_to_unmap_ksm(struct page *page, enum ttu_flags flags,
			struct vm_area_struct *target_vma)
{
	struct stable_node *stable_node;
	struct rmap_item *rmap_item;
@@ -2017,6 +2018,12 @@ int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
	stable_node = page_stable_node(page);
	if (!stable_node)
		return SWAP_FAIL;

	if (target_vma) {
		unsigned long address = vma_address(page, target_vma);
		ret = try_to_unmap_one(page, target_vma, address, flags);
		goto out;
	}
again:
	hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) {
		struct anon_vma *anon_vma = rmap_item->anon_vma;
Loading