Skip to content
  • Paolo Bonzini's avatar
    cf0f7cf9
    KVM: use KVM_CAP_IMMEDIATE_EXIT · cf0f7cf9
    Paolo Bonzini authored
    
    
    The purpose of the KVM_SET_SIGNAL_MASK API is to let userspace "kick"
    a VCPU out of KVM_RUN through a POSIX signal.  A signal is attached
    to a dummy signal handler; by blocking the signal outside KVM_RUN and
    unblocking it inside, this possible race is closed:
    
              VCPU thread                     service thread
       --------------------------------------------------------------
            check flag
                                              set flag
                                              raise signal
            (signal handler does nothing)
            KVM_RUN
    
    However, one issue with KVM_SET_SIGNAL_MASK is that it has to take
    tsk->sighand->siglock on every KVM_RUN.  This lock is often on a
    remote NUMA node, because it is on the node of a thread's creator.
    Taking this lock can be very expensive if there are many userspace
    exits (as is the case for SMP Windows VMs without Hyper-V reference
    time counter).
    
    KVM_CAP_IMMEDIATE_EXIT provides an alternative, where the flag is
    placed directly in kvm_run so that KVM can see it:
    
              VCPU thread                     service thread
       --------------------------------------------------------------
                                              raise signal
            signal handler
              set run->immediate_exit
            KVM_RUN
              check run->immediate_exit
    
    The previous patches changed QEMU so that the only blocked signal is
    SIG_IPI, so we can now stop using KVM_SET_SIGNAL_MASK and sigtimedwait
    if KVM_CAP_IMMEDIATE_EXIT is available.
    
    On a 14-VCPU guest, an "inl" operation goes down from 30k to 6k on
    an unlocked (no BQL) MemoryRegion, or from 30k to 15k if the BQL
    is involved.
    
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    cf0f7cf9
    KVM: use KVM_CAP_IMMEDIATE_EXIT
    Paolo Bonzini authored
    
    
    The purpose of the KVM_SET_SIGNAL_MASK API is to let userspace "kick"
    a VCPU out of KVM_RUN through a POSIX signal.  A signal is attached
    to a dummy signal handler; by blocking the signal outside KVM_RUN and
    unblocking it inside, this possible race is closed:
    
              VCPU thread                     service thread
       --------------------------------------------------------------
            check flag
                                              set flag
                                              raise signal
            (signal handler does nothing)
            KVM_RUN
    
    However, one issue with KVM_SET_SIGNAL_MASK is that it has to take
    tsk->sighand->siglock on every KVM_RUN.  This lock is often on a
    remote NUMA node, because it is on the node of a thread's creator.
    Taking this lock can be very expensive if there are many userspace
    exits (as is the case for SMP Windows VMs without Hyper-V reference
    time counter).
    
    KVM_CAP_IMMEDIATE_EXIT provides an alternative, where the flag is
    placed directly in kvm_run so that KVM can see it:
    
              VCPU thread                     service thread
       --------------------------------------------------------------
                                              raise signal
            signal handler
              set run->immediate_exit
            KVM_RUN
              check run->immediate_exit
    
    The previous patches changed QEMU so that the only blocked signal is
    SIG_IPI, so we can now stop using KVM_SET_SIGNAL_MASK and sigtimedwait
    if KVM_CAP_IMMEDIATE_EXIT is available.
    
    On a 14-VCPU guest, an "inl" operation goes down from 30k to 6k on
    an unlocked (no BQL) MemoryRegion, or from 30k to 15k if the BQL
    is involved.
    
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Loading