* [PATCH 4/5] add 2nd stage page fault handling during live migration
@ 2014-04-17 1:34 Mario Smarduch
2014-04-17 8:17 ` Marc Zyngier
0 siblings, 1 reply; 3+ messages in thread
From: Mario Smarduch @ 2014-04-17 1:34 UTC (permalink / raw)
To: kvmarm@lists.cs.columbia.edu, Marc Zyngier,
christoffer.dall@linaro.org
Cc: kvm@vger.kernel.org, 이정석,
정성진
Additional logic to handle second stage page faults during migration. Primarily
page faults are prevented from creating huge pages.
Signed-off-by: Mario Smarduch <m.smarduch@samsung.com>
---
arch/arm/kvm/mmu.c | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 47bec1c..ebec33c 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -839,6 +839,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
struct vm_area_struct *vma;
pfn_t pfn;
+ bool migration_active;
write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu));
if (fault_status == FSC_PERM && !write_fault) {
@@ -890,12 +891,22 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
return -EFAULT;
spin_lock(&kvm->mmu_lock);
+ /* place inside lock to prevent race condition when whole VM is being
+ * write proteced initially, prevent pmd update if it's split up.
+ */
+ migration_active = vcpu->kvm->arch.migration_in_progress;
+
if (mmu_notifier_retry(kvm, mmu_seq))
goto out_unlock;
- if (!hugetlb && !force_pte)
+
+ /* During migration don't rebuild huge pages */
+ if (!hugetlb && !force_pte && !migration_active)
hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa);
- if (hugetlb) {
+ /* Steer away from installing PMDs if migrating, migration failed,
+ * or this an initial page fault. Migrating huge pages is too slow.
+ */
+ if (!migration_active && hugetlb) {
pmd_t new_pmd = pfn_pmd(pfn, PAGE_S2);
new_pmd = pmd_mkhuge(new_pmd);
if (writable) {
@@ -907,6 +918,22 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
} else {
pte_t new_pte = pfn_pte(pfn, PAGE_S2);
if (writable) {
+ /* First convert huge page pfn to normal 4k page pfn,
+ * while migration is in progress.
+ * Second in migration mode and rare case where
+ * splitting of huge pages fails check if pmd is
+ * mapping a huge page if it is then clear it so
+ * stage2_set_pte() can map in a small page.
+ */
+ if (migration_active && hugetlb) {
+ pmd_t *pmd;
+ pfn += (fault_ipa >> PAGE_SHIFT) &
+ (PTRS_PER_PMD-1);
+ new_pte = pfn_pte(pfn, PAGE_S2);
+ pmd = stage2_get_pmd(kvm, NULL, fault_ipa);
+ if (pmd && kvm_pmd_huge(*pmd))
+ clear_pmd_entry(kvm, pmd, fault_ipa);
+ }
kvm_set_s2pte_writable(&new_pte);
kvm_set_pfn_dirty(pfn);
}
@@ -914,6 +941,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, false);
}
+ if (writable)
+ mark_page_dirty(kvm, gfn);
out_unlock:
spin_unlock(&kvm->mmu_lock);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 4/5] add 2nd stage page fault handling during live migration
2014-04-17 1:34 [PATCH 4/5] add 2nd stage page fault handling during live migration Mario Smarduch
@ 2014-04-17 8:17 ` Marc Zyngier
2014-04-18 19:45 ` Mario Smarduch
0 siblings, 1 reply; 3+ messages in thread
From: Marc Zyngier @ 2014-04-17 8:17 UTC (permalink / raw)
To: Mario Smarduch
Cc: kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org,
kvm@vger.kernel.org, 이정석,
정성진
On Thu, Apr 17 2014 at 2:34:39 am BST, Mario Smarduch <m.smarduch@samsung.com> wrote:
> Additional logic to handle second stage page faults during migration. Primarily
> page faults are prevented from creating huge pages.
>
>
> Signed-off-by: Mario Smarduch <m.smarduch@samsung.com>
> ---
> arch/arm/kvm/mmu.c | 33 +++++++++++++++++++++++++++++++--
> 1 file changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index 47bec1c..ebec33c 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -839,6 +839,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
> struct vm_area_struct *vma;
> pfn_t pfn;
> + bool migration_active;
>
> write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu));
> if (fault_status == FSC_PERM && !write_fault) {
> @@ -890,12 +891,22 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> return -EFAULT;
>
> spin_lock(&kvm->mmu_lock);
> + /* place inside lock to prevent race condition when whole VM is being
> + * write proteced initially, prevent pmd update if it's split up.
> + */
> + migration_active = vcpu->kvm->arch.migration_in_progress;
> +
> if (mmu_notifier_retry(kvm, mmu_seq))
> goto out_unlock;
> - if (!hugetlb && !force_pte)
> +
> + /* During migration don't rebuild huge pages */
> + if (!hugetlb && !force_pte && !migration_active)
> hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa);
>
> - if (hugetlb) {
> + /* Steer away from installing PMDs if migrating, migration failed,
> + * or this an initial page fault. Migrating huge pages is too slow.
> + */
> + if (!migration_active && hugetlb) {
> pmd_t new_pmd = pfn_pmd(pfn, PAGE_S2);
> new_pmd = pmd_mkhuge(new_pmd);
> if (writable) {
> @@ -907,6 +918,22 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> } else {
> pte_t new_pte = pfn_pte(pfn, PAGE_S2);
> if (writable) {
> + /* First convert huge page pfn to normal 4k page pfn,
> + * while migration is in progress.
> + * Second in migration mode and rare case where
> + * splitting of huge pages fails check if pmd is
> + * mapping a huge page if it is then clear it so
> + * stage2_set_pte() can map in a small page.
> + */
> + if (migration_active && hugetlb) {
> + pmd_t *pmd;
> + pfn += (fault_ipa >> PAGE_SHIFT) &
> + (PTRS_PER_PMD-1);
Shouldn't that be "pfn += pte_index(fault_addr);"?
> + new_pte = pfn_pte(pfn, PAGE_S2);
> + pmd = stage2_get_pmd(kvm, NULL, fault_ipa);
> + if (pmd && kvm_pmd_huge(*pmd))
> + clear_pmd_entry(kvm, pmd, fault_ipa);
> + }
> kvm_set_s2pte_writable(&new_pte);
> kvm_set_pfn_dirty(pfn);
> }
> @@ -914,6 +941,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, false);
> }
>
> + if (writable)
Shouldn't that be done only when migration is active?
> + mark_page_dirty(kvm, gfn);
>
> out_unlock:
> spin_unlock(&kvm->mmu_lock);
--
Jazz is not dead. It just smells funny.
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [PATCH 4/5] add 2nd stage page fault handling during live migration
2014-04-17 8:17 ` Marc Zyngier
@ 2014-04-18 19:45 ` Mario Smarduch
0 siblings, 0 replies; 3+ messages in thread
From: Mario Smarduch @ 2014-04-18 19:45 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org,
kvm@vger.kernel.org, 이정석,
정성진
Hi Marc,
> + if (migration_active && hugetlb) {
> + pmd_t *pmd;
> + pfn += (fault_ipa >> PAGE_SHIFT) &
> + (PTRS_PER_PMD-1);
MZ> Shouldn't that be "pfn += pte_index(fault_addr);"?
I'll change much cleaner.
> }
>
> + if (writable)
MZ> Shouldn't that be done only when migration is active?
Convention in other architectures is call it anytime page is dirty, the function
checks if dirty map is allocated if not it returns.
> + mark_page_dirty(kvm, gfn);
>
> out_unlock:
> spin_unlock(&kvm->mmu_lock);
--
Jazz is not dead. It just smells funny.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-04-18 19:45 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-17 1:34 [PATCH 4/5] add 2nd stage page fault handling during live migration Mario Smarduch
2014-04-17 8:17 ` Marc Zyngier
2014-04-18 19:45 ` Mario Smarduch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox