From: Maxim Patlasov <mpatlasov@virtuozzo.com> To: pbonzini@redhat.com Cc: kvm@vger.kernel.org, linux-nvdimm@lists.01.org, gleb@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, devel@openvz.org Subject: [PATCH] kvm: do not SetPageDirty from kvm_set_pfn_dirty for file mappings Date: Thu, 11 Feb 2016 10:13:29 -0800 [thread overview] Message-ID: <20160211181306.7864.44244.stgit@maxim-thinkpad> (raw) The patch solves the following problem: file system specific routines involved in ordinary routine writeback process BUG_ON page_buffers() because a page goes to writeback without buffer-heads attached. The way how kvm_set_pfn_dirty calls SetPageDirty works only for anon mappings. For file mappings it is obviously incorrect - there page_mkwrite must be called. It's not easy to add page_mkwrite call to kvm_set_pfn_dirty because there is no universal way to find vma by pfn. But actually SetPageDirty may be simply skipped in those cases. Below is a justification. When guest modifies the content of a page with file mapping, kernel kvm makes the page dirty by the following call-path: vmx_handle_exit -> handle_ept_violation -> __get_user_pages -> page_mkwrite -> SetPageDirty Since then, the page is dirty from both guest and host point of view. Then the host makes writeback and marks the page as write-protected. So any further write from the guest triggers call-path above again. So, for file mappings, it's not possible to have new data written to a page inside the guest w/o corresponding SetPageDirty on the host. This makes explicit SetPageDirty from kvm_set_pfn_dirty redundant. Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com> --- virt/kvm/kvm_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a11cfd2..5a7d3fa 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1582,7 +1582,8 @@ void kvm_set_pfn_dirty(kvm_pfn_t pfn) if (!kvm_is_reserved_pfn(pfn)) { struct page *page = pfn_to_page(pfn); - if (!PageReserved(page)) + if (!PageReserved(page) && + (!page->mapping || PageAnon(page))) SetPageDirty(page); } } -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Maxim Patlasov <mpatlasov@virtuozzo.com> To: pbonzini@redhat.com Cc: kvm@vger.kernel.org, linux-nvdimm@ml01.01.org, gleb@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, devel@openvz.org Subject: [PATCH] kvm: do not SetPageDirty from kvm_set_pfn_dirty for file mappings Date: Thu, 11 Feb 2016 10:13:29 -0800 [thread overview] Message-ID: <20160211181306.7864.44244.stgit@maxim-thinkpad> (raw) The patch solves the following problem: file system specific routines involved in ordinary routine writeback process BUG_ON page_buffers() because a page goes to writeback without buffer-heads attached. The way how kvm_set_pfn_dirty calls SetPageDirty works only for anon mappings. For file mappings it is obviously incorrect - there page_mkwrite must be called. It's not easy to add page_mkwrite call to kvm_set_pfn_dirty because there is no universal way to find vma by pfn. But actually SetPageDirty may be simply skipped in those cases. Below is a justification. When guest modifies the content of a page with file mapping, kernel kvm makes the page dirty by the following call-path: vmx_handle_exit -> handle_ept_violation -> __get_user_pages -> page_mkwrite -> SetPageDirty Since then, the page is dirty from both guest and host point of view. Then the host makes writeback and marks the page as write-protected. So any further write from the guest triggers call-path above again. So, for file mappings, it's not possible to have new data written to a page inside the guest w/o corresponding SetPageDirty on the host. This makes explicit SetPageDirty from kvm_set_pfn_dirty redundant. Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com> --- virt/kvm/kvm_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a11cfd2..5a7d3fa 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1582,7 +1582,8 @@ void kvm_set_pfn_dirty(kvm_pfn_t pfn) if (!kvm_is_reserved_pfn(pfn)) { struct page *page = pfn_to_page(pfn); - if (!PageReserved(page)) + if (!PageReserved(page) && + (!page->mapping || PageAnon(page))) SetPageDirty(page); } }
next reply other threads:[~2016-02-11 18:13 UTC|newest] Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-02-11 18:13 Maxim Patlasov [this message] 2016-02-11 18:13 ` [PATCH] kvm: do not SetPageDirty from kvm_set_pfn_dirty for file mappings Maxim Patlasov 2016-02-12 13:48 ` Dmitry Monakhov 2016-02-12 13:48 ` Dmitry Monakhov 2016-02-12 18:12 ` Maxim Patlasov 2016-02-12 18:12 ` Maxim Patlasov 2016-02-12 18:12 ` Maxim Patlasov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20160211181306.7864.44244.stgit@maxim-thinkpad \ --to=mpatlasov@virtuozzo.com \ --cc=devel@openvz.org \ --cc=gleb@kernel.org \ --cc=kvm@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=linux-nvdimm@lists.01.org \ --cc=pbonzini@redhat.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.