Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 3160499aacb81f6735941eb4c372d87a > files > 456

kvm-83-164.el5_5.30.src.rpm

From c0590c8b14b25ef3fd3fe9c36587a4315a0ec5d6 Mon Sep 17 00:00:00 2001
From: Izik Eidus <ieidus@redhat.com>
Date: Mon, 20 Apr 2009 19:02:03 +0300
Subject: [PATCH 05/15] ksm: fix Bug 496668 - stabilaty issue

This is fixed by just running the all is_present_pte() checks under
the mmap_sem lock down.

Signed-off-by: Izik Eidus <ieidus@redhat.com>
Message-ID: <49EC9D83.4050702@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Upstream-status: pending
Bugzilla: 500263
Acked-by: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: "Michael S. Tsirkin" <mst@redhat.com>
---
 kernel/ksm/ksm_main.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/kernel/ksm/ksm_main.c b/kernel/ksm/ksm_main.c
index c7e24a2..02c7a90 100644
--- a/kernel/ksm/ksm_main.c
+++ b/kernel/ksm/ksm_main.c
@@ -669,8 +669,8 @@ static int is_zapped_item(struct rmap_item *rmap_item,
 	struct vm_area_struct *vma;
 
 	cond_resched();
+	down_read(&rmap_item->mm->mmap_sem);
 	if (is_present_pte(rmap_item->mm, rmap_item->address)) {
-		down_read(&rmap_item->mm->mmap_sem);
 		vma = find_vma(rmap_item->mm, rmap_item->address);
 		if (vma && !vma->vm_file) {
 			BUG_ON(vma->vm_flags & VM_SHARED);
@@ -678,8 +678,8 @@ static int is_zapped_item(struct rmap_item *rmap_item,
 					     rmap_item->address,
 					     1, 0, 0, page, NULL);
 		}
-		up_read(&rmap_item->mm->mmap_sem);
 	}
+	up_read(&rmap_item->mm->mmap_sem);
 
 	if (ret != 1)
 		return 1;
@@ -824,13 +824,15 @@ static struct tree_item *unstable_tree_search_insert(struct page *page,
 		rmap_item = tree_item->rmap_item;
 		BUG_ON(!rmap_item);
 
+		down_read(&rmap_item->mm->mmap_sem);
 		/*
 		 * We dont want to swap in pages
 		 */
-		if (!is_present_pte(rmap_item->mm, rmap_item->address))
+		if (!is_present_pte(rmap_item->mm, rmap_item->address)) {
+			up_read(&rmap_item->mm->mmap_sem);
 			return NULL;
+		}
 
-		down_read(&rmap_item->mm->mmap_sem);
 		ret = get_user_pages(current, rmap_item->mm, rmap_item->address,
 				     1, 0, 0, page2, NULL);
 		up_read(&rmap_item->mm->mmap_sem);
@@ -1104,9 +1106,9 @@ static int ksm_scan_start(struct ksm_scan *ksm_scan, int scan_npages)
 		 * If the page is swapped out or in swap cache, we don't want to
 		 * scan it (it is just for performance).
 		 */
+		down_read(&slot->mm->mmap_sem);
 		if (is_present_pte(slot->mm, slot->addr +
 				   ksm_scan->page_index * PAGE_SIZE)) {
-			down_read(&slot->mm->mmap_sem);
 			val = get_user_pages(current, slot->mm, slot->addr +
 					     ksm_scan->page_index * PAGE_SIZE ,
 					      1, 0, 0, page, NULL);
@@ -1116,6 +1118,8 @@ static int ksm_scan_start(struct ksm_scan *ksm_scan, int scan_npages)
 					cmp_and_merge_page(ksm_scan, page[0]);
 				put_page(page[0]);
 			}
+		} else {
+			up_read(&slot->mm->mmap_sem);
 		}
 		scan_npages--;
 	}
-- 
1.6.3.rc4.29.g8146