lkml.org 
[lkml]   [2015]   [Dec]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH v2 1/2] KVM: x86: Use vector-hashing to deliver lowest-priority interrupts
From
Date
On 2015/12/21 9:50, Wu, Feng wrote:
>
>
>> -----Original Message-----
>> From: Yang Zhang [mailto:yang.zhang.wz@gmail.com]
>> Sent: Monday, December 21, 2015 9:46 AM
>> To: Wu, Feng <feng.wu@intel.com>; pbonzini@redhat.com;
>> rkrcmar@redhat.com
>> Cc: kvm@vger.kernel.org; linux-kernel@vger.kernel.org
>> Subject: Re: [PATCH v2 1/2] KVM: x86: Use vector-hashing to deliver lowest-
>> priority interrupts
>>
>> On 2015/12/16 9:37, Feng Wu wrote:
>>> Use vector-hashing to deliver lowest-priority interrupts, As an
>>> example, modern Intel CPUs in server platform use this method to
>>> handle lowest-priority interrupts.
>>>
>>> Signed-off-by: Feng Wu <feng.wu@intel.com>
>>> ---
>>> arch/x86/kvm/irq_comm.c | 27 ++++++++++++++++++-----
>>> arch/x86/kvm/lapic.c | 57
>> ++++++++++++++++++++++++++++++++++++++++---------
>>> arch/x86/kvm/lapic.h | 2 ++
>>> arch/x86/kvm/x86.c | 9 ++++++++
>>> arch/x86/kvm/x86.h | 1 +
>>> 5 files changed, 81 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
>>> index 84b96d3..c8c5f61 100644
>>> --- a/arch/x86/kvm/irq_comm.c
>>> +++ b/arch/x86/kvm/irq_comm.c
>>> @@ -32,6 +32,7 @@
>>> #include "ioapic.h"
>>>
>>> #include "lapic.h"
>>> +#include "x86.h"
>>>
>>> static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
>>> struct kvm *kvm, int irq_source_id, int level,
>>> @@ -53,8 +54,10 @@ static int kvm_set_ioapic_irq(struct
>> kvm_kernel_irq_routing_entry *e,
>>> int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
>>> struct kvm_lapic_irq *irq, unsigned long *dest_map)
>>> {
>>> - int i, r = -1;
>>> + int i, r = -1, idx = 0;
>>> struct kvm_vcpu *vcpu, *lowest = NULL;
>>> + unsigned long dest_vcpu_bitmap[BITS_TO_LONGS(KVM_MAX_VCPUS)];
>>> + unsigned int dest_vcpus = 0;
>>>
>>> if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
>>> kvm_lowest_prio_delivery(irq)) {
>>> @@ -65,6 +68,8 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct
>> kvm_lapic *src,
>>> if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r, dest_map))
>>> return r;
>>>
>>> + memset(dest_vcpu_bitmap, 0, sizeof(dest_vcpu_bitmap));
>>> +
>>> kvm_for_each_vcpu(i, vcpu, kvm) {
>>> if (!kvm_apic_present(vcpu))
>>> continue;
>>> @@ -78,13 +83,25 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct
>> kvm_lapic *src,
>>> r = 0;
>>> r += kvm_apic_set_irq(vcpu, irq, dest_map);
>>> } else if (kvm_lapic_enabled(vcpu)) {
>>> - if (!lowest)
>>> - lowest = vcpu;
>>> - else if (kvm_apic_compare_prio(vcpu, lowest) < 0)
>>> - lowest = vcpu;
>>> + if (!kvm_vector_hashing_enabled()) {
>>> + if (!lowest)
>>> + lowest = vcpu;
>>> + else if (kvm_apic_compare_prio(vcpu, lowest) <
>> 0)
>>> + lowest = vcpu;
>>> + } else {
>>> + __set_bit(vcpu->vcpu_id, dest_vcpu_bitmap);
>>> + dest_vcpus++;
>>> + }
>>> }
>>> }
>>>
>>> + if (dest_vcpus != 0) {
>>> + idx = kvm_vector_2_index(irq->vector, dest_vcpus,
>>> + dest_vcpu_bitmap, KVM_MAX_VCPUS);
>>> +
>>> + lowest = kvm_get_vcpu(kvm, idx - 1);
>>> + }
>>> +
>>> if (lowest)
>>> r = kvm_apic_set_irq(lowest, irq, dest_map);
>>>
>>> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
>>> index ecd4ea1..e29001f 100644
>>> --- a/arch/x86/kvm/lapic.c
>>> +++ b/arch/x86/kvm/lapic.c
>>> @@ -678,6 +678,22 @@ bool kvm_apic_match_dest(struct kvm_vcpu *vcpu,
>> struct kvm_lapic *source,
>>> }
>>> }
>>>
>>> +int kvm_vector_2_index(u32 vector, u32 dest_vcpus,
>>> + const unsigned long *bitmap, u32 bitmap_size)
>>> +{
>>> + u32 mod;
>>> + int i, idx = 0;
>>> +
>>> + mod = vector % dest_vcpus;
>>> +
>>> + for (i = 0; i <= mod; i++) {
>>> + idx = find_next_bit(bitmap, bitmap_size, idx) + 1;
>>> + BUG_ON(idx > bitmap_size);
>>> + }
>>> +
>>> + return idx;
>>> +}
>>> +
>>> bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
>>> struct kvm_lapic_irq *irq, int *r, unsigned long *dest_map)
>>> {
>>> @@ -731,17 +747,38 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm
>> *kvm, struct kvm_lapic *src,
>>> dst = map->logical_map[cid];
>>>
>>> if (kvm_lowest_prio_delivery(irq)) {
>>> - int l = -1;
>>> - for_each_set_bit(i, &bitmap, 16) {
>>> - if (!dst[i])
>>> - continue;
>>> - if (l < 0)
>>> - l = i;
>>> - else if (kvm_apic_compare_prio(dst[i]->vcpu,
>> dst[l]->vcpu) < 0)
>>> - l = i;
>>> + if (!kvm_vector_hashing_enabled()) {
>>> + int l = -1;
>>> + for_each_set_bit(i, &bitmap, 16) {
>>> + if (!dst[i])
>>> + continue;
>>> + if (l < 0)
>>> + l = i;
>>> + else if (kvm_apic_compare_prio(dst[i]-
>>> vcpu, dst[l]->vcpu) < 0)
>>> + l = i;
>>> + }
>>> + bitmap = (l >= 0) ? 1 << l : 0;
>>> + } else {
>>> + int idx = 0;
>>> + unsigned int dest_vcpus = 0;
>>> +
>>> + for_each_set_bit(i, &bitmap, 16) {
>>> + if (!dst[i]
>> && !kvm_lapic_enabled(dst[i]->vcpu)) {
>>
>> It should be or(||) not and (&&).
>
> Oh, you are right! My negligence! Thanks for pointing this out, Yang!

btw, i think the kvm_lapic_enabled check is wrong here? Why need it here?

>
> Thanks,
> Feng
>


--
best regards
yang


\
 
 \ /
  Last update: 2015-12-21 03:21    [W:0.127 / U:0.256 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site