Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1247643 > unrolled thread
| Started by | Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> |
|---|---|
| First post | 2015-10-15 12:30 +0200 |
| Last post | 2015-10-15 12:40 +0200 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH 0/5] KVM: x86: MMU: Eliminate extra memory slot searches in page fault handlers Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> - 2015-10-15 12:30 +0200
[PATCH 2/5] KVM: x86: MMU: Simplify force_pt_level calculation code in FNAME(page_fault)() Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> - 2015-10-15 12:30 +0200
[PATCH 4/5] KVM: x86: MMU: Remove mapping_level_dirty_bitmap() Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> - 2015-10-15 12:40 +0200
Re: [PATCH 4/5] KVM: x86: MMU: Remove mapping_level_dirty_bitmap() Paolo Bonzini <pbonzini@redhat.com> - 2015-10-15 17:40 +0200
[PATCH 5/5] KVM: x86: MMU: Eliminate an extra memory slot search in mapping_level() Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> - 2015-10-15 12:40 +0200
| From | Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> |
|---|---|
| Date | 2015-10-15 12:30 +0200 |
| Subject | [PATCH 0/5] KVM: x86: MMU: Eliminate extra memory slot searches in page fault handlers |
| Message-ID | <qjNXj-3zl-5@gated-at.bofh.it> |
In page fault handlers, both mapping_level_dirty_bitmap() and mapping_level() do a memory slot search, binary search, through kvm_vcpu_gfn_to_memslot(), which may not be negligible especially for virtual machines with many memory slots. With a bit of cleanup effort, the patch set reduces this overhead. [PATCH 1/5] KVM: x86: MMU: Make force_pt_level bool [PATCH 2/5] KVM: x86: MMU: Simplify force_pt_level calculation code in FNAME(page_fault)() [PATCH 3/5] KVM: x86: MMU: Merge mapping_level_dirty_bitmap() into mapping_level() [PATCH 4/5] KVM: x86: MMU: Remove mapping_level_dirty_bitmap() [PATCH 5/5] KVM: x86: MMU: Eliminate an extra memory slot search in mapping_level() Takuya -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> |
|---|---|
| Date | 2015-10-15 12:30 +0200 |
| Subject | [PATCH 2/5] KVM: x86: MMU: Simplify force_pt_level calculation code in FNAME(page_fault)() |
| Message-ID | <qjNXk-3zl-27@gated-at.bofh.it> |
| In reply to | #1247643 |
As a bonus, an extra memory slot search can be eliminated when
is_self_change_mapping is true.
Signed-off-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>
---
arch/x86/kvm/paging_tmpl.h | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 07f1a4e..8ebc3a5 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -743,15 +743,14 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
is_self_change_mapping = FNAME(is_self_change_mapping)(vcpu,
&walker, user_fault, &vcpu->arch.write_fault_to_shadow_pgtable);
- if (walker.level >= PT_DIRECTORY_LEVEL)
- force_pt_level = mapping_level_dirty_bitmap(vcpu, walker.gfn)
- || is_self_change_mapping;
- else
+ if (walker.level >= PT_DIRECTORY_LEVEL && !is_self_change_mapping) {
+ force_pt_level = mapping_level_dirty_bitmap(vcpu, walker.gfn);
+ if (!force_pt_level) {
+ level = min(walker.level, mapping_level(vcpu, walker.gfn));
+ walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
+ }
+ } else
force_pt_level = true;
- if (!force_pt_level) {
- level = min(walker.level, mapping_level(vcpu, walker.gfn));
- walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
- }
mmu_seq = vcpu->kvm->mmu_notifier_seq;
smp_rmb();
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> |
|---|---|
| Date | 2015-10-15 12:40 +0200 |
| Subject | [PATCH 4/5] KVM: x86: MMU: Remove mapping_level_dirty_bitmap() |
| Message-ID | <qjO70-3Ld-13@gated-at.bofh.it> |
| In reply to | #1247643 |
Now that it has only one caller, and its name is not so helpful for
readers, just remove it.
Signed-off-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>
---
arch/x86/kvm/mmu.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 890cd69..78a3d08 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -851,6 +851,14 @@ static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
return ret;
}
+static inline bool memslot_invalid(struct kvm_memory_slot *slot)
+{
+ if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
+ return true;
+
+ return false;
+}
+
static struct kvm_memory_slot *
gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn,
bool no_dirty_log)
@@ -858,25 +866,22 @@ gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn,
struct kvm_memory_slot *slot;
slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
- if (!slot || slot->flags & KVM_MEMSLOT_INVALID ||
- (no_dirty_log && slot->dirty_bitmap))
+ if (memslot_invalid(slot) || (no_dirty_log && slot->dirty_bitmap))
slot = NULL;
return slot;
}
-static bool mapping_level_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t large_gfn)
-{
- return !gfn_to_memslot_dirty_bitmap(vcpu, large_gfn, true);
-}
-
static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn,
bool *force_pt_level)
{
int host_level, level, max_level;
+ struct kvm_memory_slot *slot;
+
+ slot = kvm_vcpu_gfn_to_memslot(vcpu, large_gfn);
if (likely(!*force_pt_level))
- *force_pt_level = mapping_level_dirty_bitmap(vcpu, large_gfn);
+ *force_pt_level = memslot_invalid(slot) || slot->dirty_bitmap;
if (unlikely(*force_pt_level))
return PT_PAGE_TABLE_LEVEL;
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2015-10-15 17:40 +0200 |
| Subject | Re: [PATCH 4/5] KVM: x86: MMU: Remove mapping_level_dirty_bitmap() |
| Message-ID | <qjSNk-2aP-33@gated-at.bofh.it> |
| In reply to | #1247651 |
On 15/10/2015 12:43, Takuya Yoshikawa wrote:
> +static inline bool memslot_invalid(struct kvm_memory_slot *slot)
Can you make this function memslot_valid_for_gpte(struct kvm_memory_slot
*slot, bool no_dirty_log), and have it return
slot && !(slot->flags & KVM_MEMSLOT_INVALID) &&
(!no_dirty_log || !slot->dirty_bitmap)
? If gfn_to_memslot_dirty_bitmap and mapping_level call the same
function, it helps highlighting the similarity between them. Your
optimization loses that similarity in the name, but I think we can bring
it back somehow.
Otherwise, the patches are great. Thanks!
Paolo
> +{
> + if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
> + return true;
> +
> + return false;
> +}
> +
> static struct kvm_memory_slot *
> gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn,
> bool no_dirty_log)
> @@ -858,25 +866,22 @@ gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn,
> struct kvm_memory_slot *slot;
>
> slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
> - if (!slot || slot->flags & KVM_MEMSLOT_INVALID ||
> - (no_dirty_log && slot->dirty_bitmap))
> + if (memslot_invalid(slot) || (no_dirty_log && slot->dirty_bitmap))
> slot = NULL;
>
> return slot;
> }
>
> -static bool mapping_level_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t large_gfn)
> -{
> - return !gfn_to_memslot_dirty_bitmap(vcpu, large_gfn, true);
> -}
> -
> static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn,
> bool *force_pt_level)
> {
> int host_level, level, max_level;
> + struct kvm_memory_slot *slot;
> +
> + slot = kvm_vcpu_gfn_to_memslot(vcpu, large_gfn);
>
> if (likely(!*force_pt_level))
> - *force_pt_level = mapping_level_dirty_bitmap(vcpu, large_gfn);
> + *force_pt_level = memslot_invalid(slot) || slot->dirty_bitmap;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> |
|---|---|
| Date | 2015-10-15 12:40 +0200 |
| Subject | [PATCH 5/5] KVM: x86: MMU: Eliminate an extra memory slot search in mapping_level() |
| Message-ID | <qjO71-3Ld-33@gated-at.bofh.it> |
| In reply to | #1247643 |
Calling kvm_vcpu_gfn_to_memslot() twice in mapping_level() should be
avoided since getting a slot by binary search may not be negligible,
especially for virtual machines with many memory slots.
Signed-off-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>
---
arch/x86/kvm/mmu.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 78a3d08..8d285dc 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -818,14 +818,11 @@ static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
kvm->arch.indirect_shadow_pages--;
}
-static int has_wrprotected_page(struct kvm_vcpu *vcpu,
- gfn_t gfn,
- int level)
+static int __has_wrprotected_page(gfn_t gfn, int level,
+ struct kvm_memory_slot *slot)
{
- struct kvm_memory_slot *slot;
struct kvm_lpage_info *linfo;
- slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
if (slot) {
linfo = lpage_info_slot(gfn, slot, level);
return linfo->write_count;
@@ -834,6 +831,14 @@ static int has_wrprotected_page(struct kvm_vcpu *vcpu,
return 1;
}
+static int has_wrprotected_page(struct kvm_vcpu *vcpu, gfn_t gfn, int level)
+{
+ struct kvm_memory_slot *slot;
+
+ slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
+ return __has_wrprotected_page(gfn, level, slot);
+}
+
static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
{
unsigned long page_size;
@@ -893,7 +898,7 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn,
max_level = min(kvm_x86_ops->get_lpage_level(), host_level);
for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level)
- if (has_wrprotected_page(vcpu, large_gfn, level))
+ if (__has_wrprotected_page(large_gfn, level, slot))
break;
return level - 1;
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web