All of lore.kernel.org
 help / color / mirror / Atom feed
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);
 	}
 }

             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: link
Be 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.