diff options
| author | Sheng Yang <sheng@linux.intel.com> | 2009-04-29 22:58:42 -0400 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:32:43 -0400 |
| commit | 968a6347936f9421b5bc5358b579e811c52726bc (patch) | |
| tree | 0067fd4925db6763c701d9534e54b4b61be1712d /virt/kvm/kvm_main.c | |
| parent | 017cb99e875f2d8ff375cbb576c794b081cd0bd5 (diff) | |
KVM: No disable_irq for MSI/MSI-X interrupt on device assignment
Disable interrupt at interrupt handler and enable it when guest ack is for
the level triggered interrupt, to prevent reinjected interrupt. MSI/MSI-X don't
need it.
One possible problem is multiply same vector interrupt injected between irq
handler and scheduled work handler would be merged as one for MSI/MSI-X.
But AFAIK, the drivers handle it well.
The patch fixed the oplin card performance issue(MSI-X performance is half of
MSI/INTx).
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
| -rw-r--r-- | virt/kvm/kvm_main.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index dee321e58894..2d9bc439d9a9 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -120,7 +120,7 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) | |||
| 120 | { | 120 | { |
| 121 | struct kvm_assigned_dev_kernel *assigned_dev; | 121 | struct kvm_assigned_dev_kernel *assigned_dev; |
| 122 | struct kvm *kvm; | 122 | struct kvm *kvm; |
| 123 | int irq, i; | 123 | int i; |
| 124 | 124 | ||
| 125 | assigned_dev = container_of(work, struct kvm_assigned_dev_kernel, | 125 | assigned_dev = container_of(work, struct kvm_assigned_dev_kernel, |
| 126 | interrupt_work); | 126 | interrupt_work); |
| @@ -143,20 +143,10 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) | |||
| 143 | kvm_set_irq(assigned_dev->kvm, | 143 | kvm_set_irq(assigned_dev->kvm, |
| 144 | assigned_dev->irq_source_id, | 144 | assigned_dev->irq_source_id, |
| 145 | guest_entries[i].vector, 1); | 145 | guest_entries[i].vector, 1); |
| 146 | irq = assigned_dev->host_msix_entries[i].vector; | ||
| 147 | if (irq != 0) | ||
| 148 | enable_irq(irq); | ||
| 149 | assigned_dev->host_irq_disabled = false; | ||
| 150 | } | 146 | } |
| 151 | } else { | 147 | } else |
| 152 | kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, | 148 | kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, |
| 153 | assigned_dev->guest_irq, 1); | 149 | assigned_dev->guest_irq, 1); |
| 154 | if (assigned_dev->irq_requested_type & | ||
| 155 | KVM_DEV_IRQ_GUEST_MSI) { | ||
| 156 | enable_irq(assigned_dev->host_irq); | ||
| 157 | assigned_dev->host_irq_disabled = false; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | 150 | ||
| 161 | spin_unlock_irq(&assigned_dev->assigned_dev_lock); | 151 | spin_unlock_irq(&assigned_dev->assigned_dev_lock); |
| 162 | mutex_unlock(&assigned_dev->kvm->lock); | 152 | mutex_unlock(&assigned_dev->kvm->lock); |
| @@ -179,8 +169,10 @@ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) | |||
| 179 | 169 | ||
| 180 | schedule_work(&assigned_dev->interrupt_work); | 170 | schedule_work(&assigned_dev->interrupt_work); |
| 181 | 171 | ||
| 182 | disable_irq_nosync(irq); | 172 | if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_GUEST_INTX) { |
| 183 | assigned_dev->host_irq_disabled = true; | 173 | disable_irq_nosync(irq); |
| 174 | assigned_dev->host_irq_disabled = true; | ||
| 175 | } | ||
| 184 | 176 | ||
| 185 | out: | 177 | out: |
| 186 | spin_unlock_irqrestore(&assigned_dev->assigned_dev_lock, flags); | 178 | spin_unlock_irqrestore(&assigned_dev->assigned_dev_lock, flags); |
| @@ -417,6 +409,7 @@ static int assigned_device_enable_guest_msi(struct kvm *kvm, | |||
| 417 | { | 409 | { |
| 418 | dev->guest_irq = irq->guest_irq; | 410 | dev->guest_irq = irq->guest_irq; |
| 419 | dev->ack_notifier.gsi = -1; | 411 | dev->ack_notifier.gsi = -1; |
| 412 | dev->host_irq_disabled = false; | ||
| 420 | return 0; | 413 | return 0; |
| 421 | } | 414 | } |
| 422 | #endif | 415 | #endif |
| @@ -427,6 +420,7 @@ static int assigned_device_enable_guest_msix(struct kvm *kvm, | |||
| 427 | { | 420 | { |
| 428 | dev->guest_irq = irq->guest_irq; | 421 | dev->guest_irq = irq->guest_irq; |
| 429 | dev->ack_notifier.gsi = -1; | 422 | dev->ack_notifier.gsi = -1; |
| 423 | dev->host_irq_disabled = false; | ||
| 430 | return 0; | 424 | return 0; |
| 431 | } | 425 | } |
| 432 | #endif | 426 | #endif |
