From 8868339a53e140e4273b35d15965ae2cbc440fe5 Mon Sep 17 00:00:00 2001 From: Izik Eidus <ieidus@redhat.com> Date: Tue, 2 Jun 2009 01:11:45 +0300 Subject: [PATCH 08/10] KSM: sync ksm and rhel 5.4 gup-fast. I just noticed that rhel5.4 recived gup-fast support, so ksm is needing a small change to run safe with it. Thanks. Signed-off-by: Izik Eidus <ieidus@redhat.com> Message-Id: <1243894307-17932-4-git-send-email-ieidus@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> RH-Upstream-status: not-applicable Obsoletes: <4A2169FC.5010405@redhat.com> Bugzilla: 504237 Acked-by: Marcelo Tosatti <mtosatti@redhat.com> Message-Id: <1244142579-3405-3-git-send-email-ieidus@redhat.com> Acked-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: john cooper <john.cooper@redhat.com> --- kernel/ksm/external-module-compat.h | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) diff --git a/kernel/ksm/external-module-compat.h b/kernel/ksm/external-module-compat.h index 032dc8e..b9e3726 100644 --- a/kernel/ksm/external-module-compat.h +++ b/kernel/ksm/external-module-compat.h @@ -194,6 +194,18 @@ static int page_wrprotect_one(struct page *page, struct vm_area_struct *vma, if (pte_write(*pte)) { pte_t entry; + + flush_cache_page(vma, address, pte_pfn(*pte)); + /* + * Ok, so after ptep_clear_flush will get called the pte will + * be not present, so gup-fast will become gup-slow and will + * block on the pte_lock, now, the fact that ptep_clear_flush + * will notify all the cpu, is a way to sync it with knowing + * that by the time it return gup-fast is not running in the + * middle, beacuse gup-fast run with irq_disabled. + */ + entry = ptep_clear_flush(vma, address, pte); + /* * this is needed here to balance the mapcount of the page */ @@ -205,11 +217,10 @@ static int page_wrprotect_one(struct page *page, struct vm_area_struct *vma, */ if ((page_mapcount(page) + count_offset) != page_count(page)) { *odirect_sync = 0; + set_pte_at(mm, address, pte, entry); goto out_unlock; } - flush_cache_page(vma, address, pte_pfn(*pte)); - entry = ptep_clear_flush(vma, address, pte); entry = pte_wrprotect(entry); set_pte_at(mm, address, pte, entry); BUG_ON(pte_write(entry)); -- 1.6.3.rc4.29.g8146