diff options
author | Igor Mammedov <imammedo@redhat.com> | 2014-12-01 17:29:25 +0000 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-12-04 15:29:10 +0100 |
commit | d4ae84a02bc65cec29608bc417a969fc2ec75449 (patch) | |
tree | fdf2e5f189783ca5a47407c5a64dbea7f243e86a | |
parent | 7f379cff11fb9e00e0ff9eff8fbc39ddfd4b1bec (diff) |
kvm: search_memslots: add simple LRU memslot caching
In typical guest boot workload only 2-3 memslots are used
extensively, and at that it's mostly the same memslot
lookup operation.
Adding LRU cache improves average lookup time from
46 to 28 cycles (~40%) for this workload.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | include/linux/kvm_host.h | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 231dd9472226..1a371447fd45 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -353,6 +353,7 @@ struct kvm_memslots { struct kvm_memory_slot memslots[KVM_MEM_SLOTS_NUM]; /* The mapping table from slot id to the index in memslots[]. */ short id_to_index[KVM_MEM_SLOTS_NUM]; + atomic_t lru_slot; }; struct kvm { @@ -790,12 +791,19 @@ static inline void kvm_guest_exit(void) static inline struct kvm_memory_slot * search_memslots(struct kvm_memslots *slots, gfn_t gfn) { - struct kvm_memory_slot *memslot; + int slot = atomic_read(&slots->lru_slot); + struct kvm_memory_slot *memslot = &slots->memslots[slot]; + + if (gfn >= memslot->base_gfn && + gfn < memslot->base_gfn + memslot->npages) + return memslot; kvm_for_each_memslot(memslot, slots) if (gfn >= memslot->base_gfn && - gfn < memslot->base_gfn + memslot->npages) + gfn < memslot->base_gfn + memslot->npages) { + atomic_set(&slots->lru_slot, memslot - slots->memslots); return memslot; + } return NULL; } |