ae23c9
From 6bbba130993de09d0623eafe648b978351cb49f9 Mon Sep 17 00:00:00 2001
ae23c9
From: Xiao Wang <jasowang@redhat.com>
ae23c9
Date: Thu, 16 Aug 2018 08:17:07 +0100
ae23c9
Subject: [PATCH 2/4] e1000e: Prevent MSI/MSI-X storms
ae23c9
ae23c9
RH-Author: Xiao Wang <jasowang@redhat.com>
ae23c9
Message-id: <1534407427-44794-3-git-send-email-jasowang@redhat.com>
ae23c9
Patchwork-id: 81853
ae23c9
O-Subject: [RHEL-8.0 qemu-kvm PATCH 2/2] e1000e: Prevent MSI/MSI-X storms
ae23c9
Bugzilla: 1596024
ae23c9
RH-Acked-by: wexu@redhat.com
ae23c9
RH-Acked-by: Thomas Huth <thuth@redhat.com>
ae23c9
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
ae23c9
ae23c9
From: Jan Kiszka <jan.kiszka@siemens.com>
ae23c9
ae23c9
Only signal MSI/MSI-X events on rising edges. So far we re-triggered the
ae23c9
interrupt sources even if the guest did no consumed the pending one,
ae23c9
easily causing interrupt storms.
ae23c9
ae23c9
Issue was observable with Linux 4.16 e1000e driver when MSI-X was used.
ae23c9
Vector 2 was causing interrupt storms after the driver activated the
ae23c9
device.
ae23c9
ae23c9
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
ae23c9
Signed-off-by: Jason Wang <jasowang@redhat.com>
ae23c9
(cherry picked from commit 4712c158c5276fd3c401152f4bb5c3fccf185946)
ae23c9
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ae23c9
---
ae23c9
 hw/net/e1000e_core.c | 11 +++++++++++
ae23c9
 hw/net/e1000e_core.h |  2 ++
ae23c9
 2 files changed, 13 insertions(+)
ae23c9
ae23c9
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
ae23c9
index 9504891..2a221c2 100644
ae23c9
--- a/hw/net/e1000e_core.c
ae23c9
+++ b/hw/net/e1000e_core.c
ae23c9
@@ -2023,6 +2023,7 @@ e1000e_msix_notify_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg)
ae23c9
     effective_eiac = core->mac[EIAC] & cause;
ae23c9
 
ae23c9
     core->mac[ICR] &= ~effective_eiac;
ae23c9
+    core->msi_causes_pending &= ~effective_eiac;
ae23c9
 
ae23c9
     if (!(core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
ae23c9
         core->mac[IMS] &= ~effective_eiac;
ae23c9
@@ -2119,6 +2120,13 @@ e1000e_send_msi(E1000ECore *core, bool msix)
ae23c9
 {
ae23c9
     uint32_t causes = core->mac[ICR] & core->mac[IMS] & ~E1000_ICR_ASSERTED;
ae23c9
 
ae23c9
+    core->msi_causes_pending &= causes;
ae23c9
+    causes ^= core->msi_causes_pending;
ae23c9
+    if (causes == 0) {
ae23c9
+        return;
ae23c9
+    }
ae23c9
+    core->msi_causes_pending |= causes;
ae23c9
+
ae23c9
     if (msix) {
ae23c9
         e1000e_msix_notify(core, causes);
ae23c9
     } else {
ae23c9
@@ -2156,6 +2164,9 @@ e1000e_update_interrupt_state(E1000ECore *core)
ae23c9
     core->mac[ICS] = core->mac[ICR];
ae23c9
 
ae23c9
     interrupts_pending = (core->mac[IMS] & core->mac[ICR]) ? true : false;
ae23c9
+    if (!interrupts_pending) {
ae23c9
+        core->msi_causes_pending = 0;
ae23c9
+    }
ae23c9
 
ae23c9
     trace_e1000e_irq_pending_interrupts(core->mac[ICR] & core->mac[IMS],
ae23c9
                                         core->mac[ICR], core->mac[IMS]);
ae23c9
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
ae23c9
index 7d8ff41..63a1551 100644
ae23c9
--- a/hw/net/e1000e_core.h
ae23c9
+++ b/hw/net/e1000e_core.h
ae23c9
@@ -109,6 +109,8 @@ struct E1000Core {
ae23c9
     NICState *owner_nic;
ae23c9
     PCIDevice *owner;
ae23c9
     void (*owner_start_recv)(PCIDevice *d);
ae23c9
+
ae23c9
+    uint32_t msi_causes_pending;
ae23c9
 };
ae23c9
 
ae23c9
 void
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9