From: Avi Kivity <avi@qumranet.com>
To: linux-kernel@vger.kernel.org, kvm-devel@lists.sourceforge.net
Cc: Izik Eidus <izike@qumranet.com>
Subject: [PATCH 34/52] KVM: MMU: Selectively set PageDirty when releasing guest memory
Date: Sun, 30 Dec 2007 09:10:20 +0200 [thread overview]
Message-ID: <1198998638-22713-35-git-send-email-avi@qumranet.com> (raw)
In-Reply-To: <1198998638-22713-1-git-send-email-avi@qumranet.com>
From: Izik Eidus <izike@localhost.localdomain>
Improve dirty bit setting for pages that kvm release, until now every page
that we released we marked dirty, from now only pages that have potential
to get dirty we mark dirty.
Signed-off-by: Izik Eidus <izike@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 3 ++-
drivers/kvm/kvm_main.c | 12 +++++++++---
drivers/kvm/mmu.c | 23 +++++++++++++++--------
drivers/kvm/paging_tmpl.h | 12 ++++++------
drivers/kvm/x86.c | 2 +-
5 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 52e8018..c2acd74 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -393,7 +393,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
int user_alloc);
gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn);
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
-void kvm_release_page(struct page *page);
+void kvm_release_page_clean(struct page *page);
+void kvm_release_page_dirty(struct page *page);
int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset,
int len);
int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 9c94491..f06fa3a 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -543,13 +543,19 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
EXPORT_SYMBOL_GPL(gfn_to_page);
-void kvm_release_page(struct page *page)
+void kvm_release_page_clean(struct page *page)
+{
+ put_page(page);
+}
+EXPORT_SYMBOL_GPL(kvm_release_page_clean);
+
+void kvm_release_page_dirty(struct page *page)
{
if (!PageReserved(page))
SetPageDirty(page);
put_page(page);
}
-EXPORT_SYMBOL_GPL(kvm_release_page);
+EXPORT_SYMBOL_GPL(kvm_release_page_dirty);
static int next_segment(unsigned long len, int offset)
{
@@ -1055,7 +1061,7 @@ static struct page *kvm_vm_nopage(struct vm_area_struct *vma,
/* current->mm->mmap_sem is already held so call lockless version */
page = __gfn_to_page(kvm, pgoff);
if (is_error_page(page)) {
- kvm_release_page(page);
+ kvm_release_page_clean(page);
return NOPAGE_SIGBUS;
}
if (type != NULL)
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 8add4d5..4624f37 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -420,14 +420,18 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
struct kvm_rmap_desc *desc;
struct kvm_rmap_desc *prev_desc;
struct kvm_mmu_page *page;
+ struct page *release_page;
unsigned long *rmapp;
int i;
if (!is_rmap_pte(*spte))
return;
page = page_header(__pa(spte));
- kvm_release_page(pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >>
- PAGE_SHIFT));
+ release_page = pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT);
+ if (is_writeble_pte(*spte))
+ kvm_release_page_dirty(release_page);
+ else
+ kvm_release_page_clean(release_page);
rmapp = gfn_to_rmap(kvm, page->gfns[spte - page->spt]);
if (!*rmapp) {
printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
@@ -893,7 +897,9 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, hpa_t p)
{
int level = PT32E_ROOT_LEVEL;
hpa_t table_addr = vcpu->mmu.root_hpa;
+ struct page *page;
+ page = pfn_to_page(p >> PAGE_SHIFT);
for (; ; level--) {
u32 index = PT64_INDEX(v, level);
u64 *table;
@@ -908,7 +914,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, hpa_t p)
pte = table[index];
was_rmapped = is_rmap_pte(pte);
if (is_shadow_present_pte(pte) && is_writeble_pte(pte)) {
- kvm_release_page(pfn_to_page(p >> PAGE_SHIFT));
+ kvm_release_page_clean(page);
return 0;
}
mark_page_dirty(vcpu->kvm, v >> PAGE_SHIFT);
@@ -918,7 +924,8 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, hpa_t p)
if (!was_rmapped)
rmap_add(vcpu, &table[index], v >> PAGE_SHIFT);
else
- kvm_release_page(pfn_to_page(p >> PAGE_SHIFT));
+ kvm_release_page_clean(page);
+
return 0;
}
@@ -933,7 +940,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, hpa_t p)
1, 3, &table[index]);
if (!new_table) {
pgprintk("nonpaging_map: ENOMEM\n");
- kvm_release_page(pfn_to_page(p >> PAGE_SHIFT));
+ kvm_release_page_clean(page);
return -ENOMEM;
}
@@ -1049,8 +1056,8 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
paddr = gpa_to_hpa(vcpu->kvm, addr & PT64_BASE_ADDR_MASK);
if (is_error_hpa(paddr)) {
- kvm_release_page(pfn_to_page((paddr & PT64_BASE_ADDR_MASK)
- >> PAGE_SHIFT));
+ kvm_release_page_clean(pfn_to_page((paddr & PT64_BASE_ADDR_MASK)
+ >> PAGE_SHIFT));
return 1;
}
@@ -1580,7 +1587,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
" valid guest gva %lx\n", audit_msg, va);
page = pfn_to_page((gpa & PT64_BASE_ADDR_MASK)
>> PAGE_SHIFT);
- kvm_release_page(page);
+ kvm_release_page_clean(page);
}
}
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index 77a2b22..bf15d12 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -212,8 +212,8 @@ static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu,
if (is_error_hpa(paddr)) {
set_shadow_pte(shadow_pte,
shadow_trap_nonpresent_pte | PT_SHADOW_IO_MARK);
- kvm_release_page(pfn_to_page((paddr & PT64_BASE_ADDR_MASK)
- >> PAGE_SHIFT));
+ kvm_release_page_clean(pfn_to_page((paddr & PT64_BASE_ADDR_MASK)
+ >> PAGE_SHIFT));
return;
}
@@ -259,12 +259,12 @@ unshadowed:
page = pfn_to_page((paddr & PT64_BASE_ADDR_MASK)
>> PAGE_SHIFT);
- kvm_release_page(page);
+ kvm_release_page_clean(page);
}
}
else
- kvm_release_page(pfn_to_page((paddr & PT64_BASE_ADDR_MASK)
- >> PAGE_SHIFT));
+ kvm_release_page_clean(pfn_to_page((paddr & PT64_BASE_ADDR_MASK)
+ >> PAGE_SHIFT));
if (!ptwrite || !*ptwrite)
vcpu->last_pte_updated = shadow_pte;
}
@@ -503,7 +503,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
else
sp->spt[i] = shadow_notrap_nonpresent_pte;
kunmap_atomic(gpt, KM_USER0);
- kvm_release_page(page);
+ kvm_release_page_clean(page);
}
#undef pt_element_t
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
index 5a1b72f..6212984 100644
--- a/drivers/kvm/x86.c
+++ b/drivers/kvm/x86.c
@@ -1472,7 +1472,7 @@ static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
for (i = 0; i < ARRAY_SIZE(vcpu->pio.guest_pages); ++i)
if (vcpu->pio.guest_pages[i]) {
- kvm_release_page(vcpu->pio.guest_pages[i]);
+ kvm_release_page_dirty(vcpu->pio.guest_pages[i]);
vcpu->pio.guest_pages[i] = NULL;
}
}
--
1.5.3.7
next prev parent reply other threads:[~2007-12-30 7:20 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-30 7:09 [PATCH 00/52] KVM patch queue review for 2.6.25 merge window (part III) Avi Kivity
2007-12-30 7:09 ` [PATCH 01/52] KVM: Remove ptr comparisons to 0 Avi Kivity
2007-12-30 7:09 ` [PATCH 02/52] KVM: Remove __init attributes for kvm_init_debug and kvm_init_msr_list Avi Kivity
2007-12-30 7:09 ` [PATCH 03/52] KVM: Portability: Add two hooks to handle kvm_create and destroy vm Avi Kivity
2007-12-30 7:09 ` [PATCH 04/52] KVM: Replace 'light_exits' stat with 'host_state_reload' Avi Kivity
2007-12-30 7:09 ` [PATCH 05/52] KVM: Add fpu_reload counter Avi Kivity
2007-12-30 7:09 ` [PATCH 06/52] KVM: Add instruction emulation statistics Avi Kivity
2007-12-30 7:09 ` [PATCH 07/52] KVM: Extend stats support for VM stats Avi Kivity
2007-12-30 7:09 ` [PATCH 08/52] KVM: MMU: Add some mmu statistics Avi Kivity
2007-12-30 7:09 ` [PATCH 09/52] KVM: Make unloading of FPU state when putting vcpu arch-independent Avi Kivity
2007-12-30 7:09 ` [PATCH 10/52] KVM: Portability: Move kvm_vcpu_ioctl_get_dirty_log to arch-specific file Avi Kivity
2007-12-30 7:09 ` [PATCH 11/52] KVM: Portability: MMU initialization and teardown split Avi Kivity
2007-12-30 7:09 ` [PATCH 12/52] KVM: Portability: Move some macro definitions from kvm.h to x86.h Avi Kivity
2007-12-30 7:09 ` [PATCH 13/52] KVM: Portability: Move struct kvm_x86_ops definition " Avi Kivity
2007-12-30 7:10 ` [PATCH 14/52] KVM: Portability: Move vcpu regs enumeration " Avi Kivity
2007-12-30 7:10 ` [PATCH 15/52] KVM: Move some static inline functions out from kvm.h into x86.h Avi Kivity
2007-12-30 7:10 ` [PATCH 16/52] KVM: Portability: Move some function declarations to x86.h Avi Kivity
2007-12-30 7:10 ` [PATCH 17/52] KVM: VMX: Force seg.base == (seg.sel << 4) in real mode Avi Kivity
2007-12-30 7:10 ` [PATCH 18/52] KVM: MMU: Change guest pte access to kvm_{read,write}_guest() Avi Kivity
2007-12-30 7:10 ` [PATCH 19/52] KVM: Simplify kvm_clear_guest_page() Avi Kivity
2007-12-30 7:10 ` [PATCH 20/52] KVM: Add missing #include <asm/pgtable.h> Avi Kivity
2008-01-03 18:14 ` Adrian Bunk
2008-01-06 9:09 ` [kvm-devel] " Avi Kivity
2007-12-30 7:10 ` [PATCH 21/52] KVM: MMU: Remove unused variable Avi Kivity
2007-12-30 7:10 ` [PATCH 22/52] KVM: Remove unused "rmap_overflow" variable Avi Kivity
2007-12-30 7:10 ` [PATCH 23/52] KVM: Correct consistent typo: "destory" -> "destroy" Avi Kivity
2007-12-30 7:10 ` [PATCH 24/52] KVM: Move misplaced comment Avi Kivity
2007-12-30 7:10 ` [PATCH 25/52] KVM: Portability: Move kvm_memory_alias to asm/kvm.h Avi Kivity
2007-12-30 7:10 ` [PATCH 26/52] KVM: Portability: Move x86 pic strutctures Avi Kivity
2007-12-30 7:10 ` [PATCH 27/52] KVM: Portability: Move kvm_regs to <asm/kvm.h> Avi Kivity
2007-12-30 7:10 ` [PATCH 28/52] KVM: Portability: Move structure lapic_state " Avi Kivity
2007-12-30 7:10 ` [PATCH 29/52] KVM: Portability: Move kvm_segment & kvm_dtable structure " Avi Kivity
2007-12-30 7:10 ` [PATCH 30/52] KVM: Portability: Move kvm_sregs and msr structures " Avi Kivity
2007-12-30 7:10 ` [PATCH 31/52] KVM: Portability: Move cpuid " Avi Kivity
2007-12-30 7:10 ` [PATCH 32/52] KVM: Export include/asm-x86/kvm.h Avi Kivity
2007-12-30 7:10 ` [PATCH 33/52] KVM: MMU: Fix potential memory leak with smp real-mode Avi Kivity
2007-12-30 7:10 ` Avi Kivity [this message]
2007-12-30 7:10 ` [PATCH 35/52] KVM: x86 emulator: retire ->write_std() Avi Kivity
2007-12-30 7:10 ` [PATCH 36/52] KVM: x86 emulator: prefetch up to 15 bytes of the instruction executed Avi Kivity
2007-12-30 7:10 ` [PATCH 37/52] KVM: Recalculate mmu pages needed for every memory region change Avi Kivity
2007-12-30 7:10 ` [PATCH 38/52] KVM: Portability: Split kvm_set_memory_region() to have an arch callout Avi Kivity
2007-12-30 7:10 ` [PATCH 39/52] KVM: Split vcpu creation to avoid vcpu_load() before preemption setup Avi Kivity
2007-12-30 7:10 ` [PATCH 40/52] KVM: MMU: Implement guest page fault bypass for nonpae Avi Kivity
2007-12-30 7:10 ` [PATCH 41/52] KVM: Add statistic for remote tlb flushes Avi Kivity
2007-12-30 7:10 ` [PATCH 42/52] KVM: MMU: Avoid unnecessary remote tlb flushes when guest updates a pte Avi Kivity
2007-12-30 7:10 ` [PATCH 43/52] KVM: Don't bother the mmu if cr3 load doesn't change cr3 Avi Kivity
2007-12-30 7:10 ` [PATCH 44/52] KVM: MMU: Code cleanup Avi Kivity
2007-12-30 7:10 ` [PATCH 45/52] KVM: MMU: Introduce and use gpte_to_gfn() Avi Kivity
2007-12-30 7:10 ` [PATCH 46/52] KVM: MMU: Move pse36 handling to the guest walker Avi Kivity
2007-12-30 7:10 ` [PATCH 47/52] KVM: MMU: Remove extra gaddr parameter from set_pte_common() Avi Kivity
2007-12-30 7:10 ` [PATCH 48/52] KVM: MMU: Remove set_pde() Avi Kivity
2007-12-30 7:10 ` [PATCH 49/52] KVM: MMU: Merge set_pte() and set_pte_common() Avi Kivity
2007-12-30 7:10 ` [PATCH 50/52] KVM: MMU: Adjust page_header_update_slot() to accept a gfn instead of a gpa Avi Kivity
2007-12-30 7:10 ` [PATCH 51/52] KVM: MMU: Introduce gfn_to_gpa() Avi Kivity
2007-12-30 7:10 ` [PATCH 52/52] KVM: MMU: Simplify nonpaging_map() Avi Kivity
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=1198998638-22713-35-git-send-email-avi@qumranet.com \
--to=avi@qumranet.com \
--cc=izike@qumranet.com \
--cc=kvm-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®