]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - mm/ksm.c
UBUNTU: Ubuntu-4.13.0-45.50
[mirror_ubuntu-artful-kernel.git] / mm / ksm.c
index 4dc92f138786988c4ef0f9d371ff8a48b2e6e905..15e751fabab05c9fc57c0618a8a2e79540b00667 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1038,7 +1038,8 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
                goto out_unlock;
 
        if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) ||
-           (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte))) {
+           (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte)) ||
+                                               mm_tlb_flush_pending(mm)) {
                pte_t entry;
 
                swapped = PageSwapCache(page);
@@ -1989,6 +1990,7 @@ static void stable_tree_append(struct rmap_item *rmap_item,
  */
 static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
 {
+       struct mm_struct *mm = rmap_item->mm;
        struct rmap_item *tree_rmap_item;
        struct page *tree_page = NULL;
        struct stable_node *stable_node;
@@ -2061,9 +2063,11 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
        if (ksm_use_zero_pages && (checksum == zero_checksum)) {
                struct vm_area_struct *vma;
 
-               vma = find_mergeable_vma(rmap_item->mm, rmap_item->address);
+               down_read(&mm->mmap_sem);
+               vma = find_mergeable_vma(mm, rmap_item->address);
                err = try_to_merge_one_page(vma, page,
                                            ZERO_PAGE(rmap_item->address));
+               up_read(&mm->mmap_sem);
                /*
                 * In case of failure, the page was not really empty, so we
                 * need to continue. Otherwise we're done.
@@ -2331,8 +2335,12 @@ static int ksm_scan_thread(void *nothing)
                try_to_freeze();
 
                if (ksmd_should_run()) {
-                       schedule_timeout_interruptible(
-                               msecs_to_jiffies(ksm_thread_sleep_millisecs));
+                       if (ksm_thread_sleep_millisecs >= 1000)
+                               schedule_timeout_interruptible(
+                                       msecs_to_jiffies(round_jiffies_relative(ksm_thread_sleep_millisecs)));
+                       else
+                               schedule_timeout_interruptible(
+                                       msecs_to_jiffies(ksm_thread_sleep_millisecs));
                } else {
                        wait_event_freezable(ksm_thread_wait,
                                ksmd_should_run() || kthread_should_stop());