All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Liuqiming (John)" <john.liuqiming@huawei.com>
To: "Zhang, Yang Z" <yang.z.zhang@intel.com>,
	"Hanweidong (Randy)" <hanweidong@huawei.com>,
	Jan Beulich <JBeulich@suse.com>
Cc: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>,
	"Zhangwei (FF)" <zw.zhang@huawei.com>
Subject: Re: [PATCH] Remove a set operation for VCPU_KICK_SOFTIRQ when post interrupt to vm.
Date: Thu, 24 Sep 2015 10:41:08 +0800	[thread overview]
Message-ID: <560362C4.4050500@huawei.com> (raw)
In-Reply-To: <A9667DDFB95DB7438FA9D7D576C3D87E0ADB6311@SHSMSX104.ccr.corp.intel.com>

On 2015/9/23 21:41, Zhang, Yang Z wrote:
> Hanweidong (Randy) wrote on 2015-09-23:
>>
>> Zhang, Yang Z wrote on ent: 2015年9月23日 11:51:
>>> VCPU_KICK_SOFTIRQ when post interrupt to vm.
>>>
>>> Zhang, Yang Z wrote on 2015-09-08:
>>>> Liuqiming (John) wrote on 2015-09-08:
>>>>> Ok, I will try to explain, correct me if I got anything wrong:
>>>>>
>>>>> The problem here is not interrupts lost but interrupts not
>>>>> delivered in time.
>>>>>
>>>>> there are basically two path to inject an interrupt into VM  (or
>>>>> vCPU to another vCPU):
>>>>> Path 1, the traditional way:
>>>>>         1) set bit  in vlapic IRR field which represent an interrupt,
>>>>>         then kick vcpu 2) a VCPU_KICK_SOFTIRQ softirq raised 3) if
>>>>>         VCPU_KICK_SOFTIRQ bit not set, then set it, otherwise
>>>>> return
>>> and
>>>>>         do nothing 4) send an EVENT_CHECK_VECTOR IPI  to target
>> vcpu
>>> 5)
>>>>>         target vcpu will VMEXIT due to
>>>>> EXIT_REASON_EXTERNAL_INTERRUPT
>>> 6)
>>>>>         the interrupt handler basically do nothing 7) interrupt in IRR
>>>>>         will be evaluated 8) VCPU_KICK_SOFTIRQ will be cleared when
>>>>>         do_softirq 9) there will be an interrupt inject into vcpu when
>>>>>         VMENTRY Path 2, the Posted-interrupt way (current logic):
>>>>> 1)
>>> set
>>>>>         bit in posted-interrupt descriptor which represent an
>>>>>         interrupt 2) if VCPU_KICK_SOFTIRQ bit not set, then set it,
>>>>>         otherwise return and do nothing 3) send an
>>>>>         POSTED_INTR_NOTIFICATION_VECTOR IPI to target vcpu 4) if
>>>>>         target vcpu in non-ROOT mode it will receive the interrupt
>>>>> immediately otherwise interrupt will be injected when VMENTRY
>>>>>
>>>>> As the first operation in both path is setting a interrupt
>>>>> represent bit, so no interrupts will lost.
>>>>>
>>>>> The issue is:
>>>>> in path 2, the first interrupt will cause VCPU_KICK_SOFTIRQ set
>>>>> to 1, and unless a VMEXIT occured or somewhere called do_softirq
>>>>> directly, VCPU_KICK_SOFTIRQ will not cleared, that will make the
>>>>> later interrupts injection  ignored at step 2), which will delay
>>>>> irq handler process in VM.
>>>>>
>>>>> And because path 2 set VCPU_KICK_SOFTIRQ to 1, the kick vcpu
>>>>> logic in path 1 will also return in step 3), which make this vcpu
>>>>> only can handle interrupt when some other reason cause VMEXIT.
>>>> Nice catch! But without set the softirq, the interrupt delivery also
>>>> will be delay. Look at the code in vmx_do_vmentry:
>>>>
>>>> cli
>>>>          <---------------the virtual interrupt occurs here will be
>>>> delay. Because there is no softirq pending and the following
>>>> posted interrupt may consumed by another running VCPU, so the
>>>> target VCPU will not aware there is pending virtual interrupt before next vmexit.
>>>> cmp  %ecx,(%rdx,%rax,1)
>>>> jnz  .Lvmx_process_softirqs
>>>>
>>>> I need more time to think it.
>>> Hi Qiming,
>>>
>>> Can you help to take a look at this patch? Also, if possible, please
>>> help to do a testing since I don't have machine to test it. Thanks
>>> very much.
>>>
>>> diff --git a/xen/arch/x86/hvm/vmx/entry.S
>>> b/xen/arch/x86/hvm/vmx/entry.S index 664ed83..1ebb5d0 100644
>>> --- a/xen/arch/x86/hvm/vmx/entry.S
>>> +++ b/xen/arch/x86/hvm/vmx/entry.S
>>> @@ -77,6 +77,9 @@ UNLIKELY_START(ne, realmode)
>>>           call vmx_enter_realmode
>>>   UNLIKELY_END(realmode)
>>> +        bt   $0,VCPU_vmx_pi_ctrl(%rbx)
>>> +        jc   .Lvmx_do_vmentry
>>> +
>>>           mov  %rsp,%rdi
>>>           call vmx_vmenter_helper
>>>           mov  VCPU_hvm_guest_cr2(%rbx),%rax diff --git
>>> a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index
>>> e0e9e75..315ce65 100644
>>> --- a/xen/arch/x86/hvm/vmx/vmx.c
>>> +++ b/xen/arch/x86/hvm/vmx/vmx.c
>>> @@ -1678,8 +1678,9 @@ static void
>>> __vmx_deliver_posted_interrupt(struct
>>> vcpu *v)
>>>       {
>>>           unsigned int cpu = v->processor;
>>> -        if ( !test_and_set_bit(VCPU_KICK_SOFTIRQ,
>>> &softirq_pending(cpu))
>>> -             && (cpu != smp_processor_id()) )
>>> +        if ( !test_bit(VCPU_KICK_SOFTIRQ, &softirq_pending(cpu))
>>> +             && pi_test_on(&v->arch.hvm_vmx.pi_desc)
>> Why need pi_test_on() here?
> on bit is cleared means the interrupt is consumed by target VCPU already. So there is no need to send the PI.
>
> Best regards,
> Yang
>
Hi Yang,

I had a question about the "outstanding-notification" bit 
(POSTED_INTR_ON)  handling.
It's not very clear in Intel manual. From what I learned, this bit is 
set by software
when send an interrupt to vcpu and cleared by hardware when interrupt 
delivered, right?

from the source code, there is a test_and_set op for this bit in 
function vmx_deliver_posted_intr,

else if ( !pi_test_and_set_on(&v->arch.hvm_vmx.pi_desc) )
     {
         __vmx_deliver_posted_interrupt(v);
         return;
     }

so when we enter __vmx_deliver_posted_interrupt to send ipi, this bit is 
already set on, the "pi_test_on" code is meaningless.

And another thought, the clear bit action performed only when you send a 
ipi to physical cpu or sync_pir_to_irr,
there has a chance the bit is set on and physical cpu not receive a ipi, 
for example

1) [CPU1] vcpu kicked and VCPU_KICK_SOFTIRQ is set
2) [CPU1] find the highest irr where call sync_pir_to_irr to clear 
POSTED_INTR_ON
3) [CPU2] a posted interrupt delivered to CPU1, it will set 
POSTED_INTR_ON on
4) [CPU2] in __vmx_deliver_posted_interrupt will test VCPU_KICK_SOFTIRQ 
on CPU1 which is set by 1), so no ipi sent

At this point, CPU1's POSTED_INTR_ON is on but not interrupt is 
received. and until next kick on CPU1,
CPU1 will not allow posted interrupt get in.

In my opinion, if we want best performance, it should just remove the 
VCPU_KICK_SOFTIRQ test in posted-interrupt function,
or at least we should change the order of test VCPU_KICK_SOFTIRQ and 
test POSTED_INTR_ON





_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

  reply	other threads:[~2015-09-24  2:43 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1441637175-18070-1-git-send-email-john.liuqiming@huawei.com>
2015-09-07 14:24 ` [PATCH] Remove a set operation for VCPU_KICK_SOFTIRQ when post interrupt to vm Liuqiming (John)
2015-09-07 14:45   ` Jan Beulich
2015-09-08  0:39     ` Hanweidong (Randy)
2015-09-08  2:46       ` Zhang, Yang Z
2015-09-08  4:07         ` Liuqiming (John)
2015-09-08  8:10           ` Zhang, Yang Z
2015-09-08  8:49             ` Jan Beulich
2015-09-18  0:29           ` Zhang, Yang Z
2015-09-18  5:30             ` Jan Beulich
2015-09-18 11:40               ` Zhang, Yang Z
2015-09-18 11:44                 ` Andrew Cooper
2015-09-18 11:50                   ` Zhang, Yang Z
2015-09-18 12:56                     ` Dario Faggioli
2015-09-23  3:50           ` Zhang, Yang Z
2015-09-23  7:42             ` Jan Beulich
2015-09-23  9:08               ` George Dunlap
2015-09-23  9:18                 ` Zhang, Yang Z
2015-09-23 10:01                   ` George Dunlap
2015-09-23  9:21                 ` Jan Beulich
2015-09-23  9:15               ` Zhang, Yang Z
2015-09-23  9:31                 ` Jan Beulich
2015-09-23 13:02                   ` Zhang, Yang Z
2015-09-23 13:38             ` Hanweidong (Randy)
2015-09-23 13:41               ` Zhang, Yang Z
2015-09-24  2:41                 ` Liuqiming (John) [this message]
2015-09-24  3:25                   ` Zhang, Yang Z
2015-09-24  7:07                     ` Liuqiming (John)
2015-09-24  8:07                       ` Zhang, Yang Z
2015-10-10  6:32                       ` Zhang, Yang Z
2015-10-10  9:55                         ` Liuqiming (John)
2015-11-10  1:15                           ` Zhang, Yang Z

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=560362C4.4050500@huawei.com \
    --to=john.liuqiming@huawei.com \
    --cc=JBeulich@suse.com \
    --cc=hanweidong@huawei.com \
    --cc=xen-devel@lists.xenproject.org \
    --cc=yang.z.zhang@intel.com \
    --cc=zw.zhang@huawei.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.