[Devel,vz7.6,v2] kvm: x86: hyperv: avoid livelock in oneshot SynIC timers

Submitted by Roman Kagan on July 24, 2017, 7:33 a.m.

Details

Message ID 20170724073329.4262-1-rkagan@virtuozzo.com
State New
Series "kvm: x86: hyperv: avoid livelock in oneshot SynIC timers"
Headers show

Commit Message

Roman Kagan July 24, 2017, 7:33 a.m.
If the SynIC timer message delivery fails due to SINT message slot being
busy, there's no point to attempt starting the timer again until we're
notified of the slot being released by the guest (via EOM or EOI).

Even worse, when a oneshot timer fails to deliver its message, its
re-arming with an expiration time in the past leads to immediate retry
of the delivery, and so on, without ever letting the guest vcpu to run
and release the slot, which results in a livelock.

To avoid that, only start the timer when there's no timer message
pending delivery.  When there is, meaning the slot is busy, the
processing will be restarted upon notification from the guest that the
slot is released.

Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
(cherry picked from commit f1ff89ec4447c4e39d275a1ca3de43eed2a92745)
---
v1 -> v2:
 - actual cherry-pick from mainline kernel

 arch/x86/kvm/hyperv.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index c8efdce3e702..ab9501c2f32c 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -632,9 +632,10 @@  void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 				}
 
 				if ((stimer->config & HV_STIMER_ENABLE) &&
-				    stimer->count)
-					stimer_start(stimer);
-				else
+				    stimer->count) {
+					if (!stimer->msg_pending)
+						stimer_start(stimer);
+				} else
 					stimer_cleanup(stimer);
 			}
 		}

Comments

Konstantin Khorenko July 24, 2017, 8:36 a.m.
Once more: need this in vz7 update 5 or later?

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 07/24/2017 10:33 AM, Roman Kagan wrote:
> If the SynIC timer message delivery fails due to SINT message slot being
> busy, there's no point to attempt starting the timer again until we're
> notified of the slot being released by the guest (via EOM or EOI).
>
> Even worse, when a oneshot timer fails to deliver its message, its
> re-arming with an expiration time in the past leads to immediate retry
> of the delivery, and so on, without ever letting the guest vcpu to run
> and release the slot, which results in a livelock.
>
> To avoid that, only start the timer when there's no timer message
> pending delivery.  When there is, meaning the slot is busy, the
> processing will be restarted upon notification from the guest that the
> slot is released.
>
> Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> (cherry picked from commit f1ff89ec4447c4e39d275a1ca3de43eed2a92745)
> ---
> v1 -> v2:
>  - actual cherry-pick from mainline kernel
>
>  arch/x86/kvm/hyperv.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> index c8efdce3e702..ab9501c2f32c 100644
> --- a/arch/x86/kvm/hyperv.c
> +++ b/arch/x86/kvm/hyperv.c
> @@ -632,9 +632,10 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
>  				}
>
>  				if ((stimer->config & HV_STIMER_ENABLE) &&
> -				    stimer->count)
> -					stimer_start(stimer);
> -				else
> +				    stimer->count) {
> +					if (!stimer->msg_pending)
> +						stimer_start(stimer);
> +				} else
>  					stimer_cleanup(stimer);
>  			}
>  		}
>
Denis V. Lunev July 24, 2017, 8:41 a.m.
On 07/24/2017 11:36 AM, Konstantin Khorenko wrote:
> Once more: need this in vz7 update 5 or later?
>

update6, as written in the subject ;)

> -- 
> Best regards,
>
> Konstantin Khorenko,
> Virtuozzo Linux Kernel Team
>
> On 07/24/2017 10:33 AM, Roman Kagan wrote:
>> If the SynIC timer message delivery fails due to SINT message slot being
>> busy, there's no point to attempt starting the timer again until we're
>> notified of the slot being released by the guest (via EOM or EOI).
>>
>> Even worse, when a oneshot timer fails to deliver its message, its
>> re-arming with an expiration time in the past leads to immediate retry
>> of the delivery, and so on, without ever letting the guest vcpu to run
>> and release the slot, which results in a livelock.
>>
>> To avoid that, only start the timer when there's no timer message
>> pending delivery.  When there is, meaning the slot is busy, the
>> processing will be restarted upon notification from the guest that the
>> slot is released.
>>
>> Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
>> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
>> (cherry picked from commit f1ff89ec4447c4e39d275a1ca3de43eed2a92745)
>> ---
>> v1 -> v2:
>>  - actual cherry-pick from mainline kernel
>>
>>  arch/x86/kvm/hyperv.c | 7 ++++---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
>> index c8efdce3e702..ab9501c2f32c 100644
>> --- a/arch/x86/kvm/hyperv.c
>> +++ b/arch/x86/kvm/hyperv.c
>> @@ -632,9 +632,10 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
>>                  }
>>
>>                  if ((stimer->config & HV_STIMER_ENABLE) &&
>> -                    stimer->count)
>> -                    stimer_start(stimer);
>> -                else
>> +                    stimer->count) {
>> +                    if (!stimer->msg_pending)
>> +                        stimer_start(stimer);
>> +                } else
>>                      stimer_cleanup(stimer);
>>              }
>>          }
>>