[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 16/20] hw/ide/ahci: Decouple from PCI
From: |
Philippe Mathieu-Daudé |
Subject: |
[PULL 16/20] hw/ide/ahci: Decouple from PCI |
Date: |
Sat, 14 Dec 2024 00:30:51 +0100 |
From: Bernhard Beschow <shentey@gmail.com>
In some adhoc profiling booting Linux VMs, it's observed that ahci_irq_lower()
can be a hot path (10000+ triggers until login prompt appears). Even though the
parent device never changes, this method re-determines whether the parent device
is a PCI device or not using the rather expensive object_dynamic_cast()
function. Avoid this overhead by pushing the interrupt handling to the parent
device, essentially turning AHCIState into an "IP block".
Note that this change also frees AHCIState from the PCI dependency which wasn't
reflected in Kconfig.
Reported-by: Peter Xu <peterx@redhat.com>
Inspired-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20241212110926.23548-2-shentey@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ide/ahci-internal.h | 1 -
include/hw/ide/ahci-pci.h | 2 ++
include/hw/ide/ahci.h | 2 --
hw/ide/ahci.c | 39 ++++-----------------------------------
hw/ide/ich.c | 19 +++++++++++++++----
5 files changed, 21 insertions(+), 42 deletions(-)
diff --git a/hw/ide/ahci-internal.h b/hw/ide/ahci-internal.h
index 7e63ea23102..a318f36811c 100644
--- a/hw/ide/ahci-internal.h
+++ b/hw/ide/ahci-internal.h
@@ -25,7 +25,6 @@
#define HW_IDE_AHCI_INTERNAL_H
#include "hw/ide/ahci.h"
-#include "hw/pci/pci_device.h"
#include "ide-internal.h"
#define AHCI_MEM_BAR_SIZE 0x1000
diff --git a/include/hw/ide/ahci-pci.h b/include/hw/ide/ahci-pci.h
index c2ee6169625..face1a9a4a4 100644
--- a/include/hw/ide/ahci-pci.h
+++ b/include/hw/ide/ahci-pci.h
@@ -9,6 +9,7 @@
#include "qom/object.h"
#include "hw/ide/ahci.h"
#include "hw/pci/pci_device.h"
+#include "hw/irq.h"
#define TYPE_ICH9_AHCI "ich9-ahci"
OBJECT_DECLARE_SIMPLE_TYPE(AHCIPCIState, ICH9_AHCI)
@@ -17,6 +18,7 @@ struct AHCIPCIState {
PCIDevice parent_obj;
AHCIState ahci;
+ IRQState irq;
};
#endif
diff --git a/include/hw/ide/ahci.h b/include/hw/ide/ahci.h
index ba31e75ff9b..ac0292c634f 100644
--- a/include/hw/ide/ahci.h
+++ b/include/hw/ide/ahci.h
@@ -37,8 +37,6 @@ typedef struct AHCIControlRegs {
} AHCIControlRegs;
typedef struct AHCIState {
- DeviceState *container;
-
AHCIDevice *dev;
AHCIControlRegs control_regs;
MemoryRegion mem;
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 0eb24304eef..5836aa924bb 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -23,8 +23,6 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
-#include "hw/pci/msi.h"
-#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
@@ -34,8 +32,6 @@
#include "qemu/module.h"
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"
-#include "hw/ide/pci.h"
-#include "hw/ide/ahci-pci.h"
#include "hw/ide/ahci-sysbus.h"
#include "ahci-internal.h"
#include "ide-internal.h"
@@ -179,34 +175,6 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int
offset)
return val;
}
-static void ahci_irq_raise(AHCIState *s)
-{
- DeviceState *dev_state = s->container;
- PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
- TYPE_PCI_DEVICE);
-
- trace_ahci_irq_raise(s);
-
- if (pci_dev && msi_enabled(pci_dev)) {
- msi_notify(pci_dev, 0);
- } else {
- qemu_irq_raise(s->irq);
- }
-}
-
-static void ahci_irq_lower(AHCIState *s)
-{
- DeviceState *dev_state = s->container;
- PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
- TYPE_PCI_DEVICE);
-
- trace_ahci_irq_lower(s);
-
- if (!pci_dev || !msi_enabled(pci_dev)) {
- qemu_irq_lower(s->irq);
- }
-}
-
static void ahci_check_irq(AHCIState *s)
{
int i;
@@ -222,9 +190,11 @@ static void ahci_check_irq(AHCIState *s)
trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus);
if (s->control_regs.irqstatus &&
(s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
- ahci_irq_raise(s);
+ trace_ahci_irq_raise(s);
+ qemu_irq_raise(s->irq);
} else {
- ahci_irq_lower(s);
+ trace_ahci_irq_lower(s);
+ qemu_irq_lower(s->irq);
}
}
@@ -1608,7 +1578,6 @@ static const IDEDMAOps ahci_dma_ops = {
void ahci_init(AHCIState *s, DeviceState *qdev)
{
- s->container = qdev;
/* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s,
"ahci", AHCI_MEM_BAR_SIZE);
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index b311450c12d..c99a44df8e1 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -61,7 +61,6 @@
*/
#include "qemu/osdep.h"
-#include "hw/irq.h"
#include "hw/pci/msi.h"
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
@@ -91,6 +90,19 @@ static const VMStateDescription vmstate_ich9_ahci = {
},
};
+static void pci_ich9_ahci_update_irq(void *opaque, int irq_num, int level)
+{
+ PCIDevice *pci_dev = opaque;
+
+ if (msi_enabled(pci_dev)) {
+ if (level) {
+ msi_notify(pci_dev, 0);
+ }
+ } else {
+ pci_set_irq(pci_dev, level);
+ }
+}
+
static void pci_ich9_reset(DeviceState *dev)
{
AHCIPCIState *d = ICH9_AHCI(dev);
@@ -102,7 +114,9 @@ static void pci_ich9_ahci_init(Object *obj)
{
AHCIPCIState *d = ICH9_AHCI(obj);
+ qemu_init_irq(&d->irq, pci_ich9_ahci_update_irq, d, 0);
ahci_init(&d->ahci, DEVICE(obj));
+ d->ahci.irq = &d->irq;
}
static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
@@ -125,8 +139,6 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error
**errp)
/* XXX Software should program this register */
dev->config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */
- d->ahci.irq = pci_allocate_irq(dev);
-
pci_register_bar(dev, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO,
&d->ahci.idp);
pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -161,7 +173,6 @@ static void pci_ich9_uninit(PCIDevice *dev)
msi_uninit(dev);
ahci_uninit(&d->ahci);
- qemu_free_irq(d->ahci.irq);
}
static void ich_ahci_class_init(ObjectClass *klass, void *data)
--
2.45.2
- [PULL 05/20] hw/nvram/fw_cfg: Rename fw_cfg_add_[file]_from_generator(), (continued)
- [PULL 05/20] hw/nvram/fw_cfg: Rename fw_cfg_add_[file]_from_generator(), Philippe Mathieu-Daudé, 2024/12/13
- [PULL 08/20] hw/pci: Have PCI_BUS implement TYPE_FW_CFG_DATA_GENERATOR_INTERFACE, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 10/20] hw: Use pci_bus_add_fw_cfg_extra_pci_roots(), Philippe Mathieu-Daudé, 2024/12/13
- [PULL 09/20] hw/pci: Add pci_bus_add_fw_cfg_extra_pci_roots() helper, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 12/20] hw/net/can: clean-up unnecessary includes, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 15/20] hw/usb/hcd-xhci-pci: Indentation fix, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 11/20] hw/nvram/fw_cfg: Remove fw_cfg_add_extra_pci_roots(), Philippe Mathieu-Daudé, 2024/12/13
- [PULL 17/20] hw/ide/ahci: Extract TYPE_SYSBUS_AHCI into dedicated file, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 14/20] hw/usb/hcd-xhci-nec: Remove unused XHCINecState::flags field, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 13/20] hw/usb/msd: Add status to usb_msd_packet_complete() function, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 16/20] hw/ide/ahci: Decouple from PCI,
Philippe Mathieu-Daudé <=
- [PULL 18/20] hw/mips: Include missing 'exec/tswap.h' header, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 20/20] hw/xtensa: Include missing 'exec/tswap.h' header, Philippe Mathieu-Daudé, 2024/12/13
- [PULL 19/20] hw/sh4/r2d: Include missing 'exec/tswap.h' header, Philippe Mathieu-Daudé, 2024/12/13
- Re: [PULL 00/20] Misc HW patches for 2024-12-14, Stefan Hajnoczi, 2024/12/16