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

Commit 93d17715 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds
Browse files

ksm: three remove_rmap_item_from_tree cleanups



1. remove_rmap_item_from_tree() is called as a precaution from
   various places: don't dirty the rmap_item cacheline unnecessarily,
   just mask the flags out of the address when they have been set.

2. First get_next_rmap_item() removes an unstable rmap_item from its tree,
   then shortly afterwards cmp_and_merge_page() removes a stable rmap_item
   from its tree: it's easier just to do both at once (but definitely keep
   the BUG_ON(age > 1) which guards against a future omission).

3. When cmp_and_merge_page() moves an rmap_item from unstable to stable
   tree, it does its own rb_erase() and accounting: that's better
   expressed by remove_rmap_item_from_tree().

Signed-off-by: default avatarHugh Dickins <hugh.dickins@tiscali.co.uk>
Cc: Izik Eidus <ieidus@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 338fde90
Loading
Loading
Loading
Loading
+6 −11
Original line number Diff line number Diff line
@@ -453,6 +453,7 @@ static void remove_rmap_item_from_tree(struct rmap_item *rmap_item)
		}

		rmap_item->next = NULL;
		rmap_item->address &= PAGE_MASK;

	} else if (rmap_item->address & NODE_FLAG) {
		unsigned char age;
@@ -467,10 +468,10 @@ static void remove_rmap_item_from_tree(struct rmap_item *rmap_item)
		BUG_ON(age > 1);
		if (!age)
			rb_erase(&rmap_item->node, &root_unstable_tree);
		ksm_pages_unshared--;
	}

		ksm_pages_unshared--;
		rmap_item->address &= PAGE_MASK;
	}

	cond_resched();		/* we're called from many long loops */
}
@@ -1086,7 +1087,6 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
	unsigned int checksum;
	int err;

	if (in_stable_tree(rmap_item))
	remove_rmap_item_from_tree(rmap_item);

	/* We first start with searching the page inside the stable tree */
@@ -1143,9 +1143,7 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
		 * tree, and insert it instead as new node in the stable tree.
		 */
		if (!err) {
			rb_erase(&tree_rmap_item->node, &root_unstable_tree);
			tree_rmap_item->address &= ~NODE_FLAG;
			ksm_pages_unshared--;
			remove_rmap_item_from_tree(tree_rmap_item);

			/*
			 * If we fail to insert the page into the stable tree,
@@ -1174,11 +1172,8 @@ static struct rmap_item *get_next_rmap_item(struct mm_slot *mm_slot,

	while (cur != &mm_slot->rmap_list) {
		rmap_item = list_entry(cur, struct rmap_item, link);
		if ((rmap_item->address & PAGE_MASK) == addr) {
			if (!in_stable_tree(rmap_item))
				remove_rmap_item_from_tree(rmap_item);
		if ((rmap_item->address & PAGE_MASK) == addr)
			return rmap_item;
		}
		if (rmap_item->address > addr)
			break;
		cur = cur->next;