Adjust the parameters to i8259_stat_update_irq() to allow passing in pointers to the irq_count and irq_level arrays, and then move the arrays into the corresponding i8259 PIC and KVM PIC devices.
Doing this allows the statistics capture logic in i8259_set_irq() that handles incoming cascading interrupts to be removed. Signed-off-by: Mark Cave-Ayland <[email protected]> --- include/hw/intc/i8259.h | 3 --- include/hw/isa/i8259_internal.h | 3 ++- hw/i386/kvm/i8259.c | 20 +++++++++++++++-- hw/intc/i8259.c | 40 ++++++++++++++++++++++----------- hw/intc/i8259_common.c | 21 +++++------------ 5 files changed, 52 insertions(+), 35 deletions(-) diff --git a/include/hw/intc/i8259.h b/include/hw/intc/i8259.h index 4922f88d5b..42d6f992ac 100644 --- a/include/hw/intc/i8259.h +++ b/include/hw/intc/i8259.h @@ -20,9 +20,6 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq_in); qemu_irq *kvm_i8259_init(ISABus *bus); int pic_get_output(I8259PICState *s); int pic_read_irq(I8259PICState *s); -bool i8259_pic_get_statistics(InterruptStatsProvider *obj, - uint64_t **irq_counts, - unsigned int *nb_irqs); void i8259_pic_print_info(InterruptStatsProvider *obj, GString *buf); #endif diff --git a/include/hw/isa/i8259_internal.h b/include/hw/isa/i8259_internal.h index 2807409eff..e0002843a1 100644 --- a/include/hw/isa/i8259_internal.h +++ b/include/hw/isa/i8259_internal.h @@ -70,6 +70,7 @@ struct I8259CommonState { }; void i8259_common_reset(I8259CommonState *cs); -void i8259_stat_update_irq(int irq, int level); +void i8259_stat_update_irq(uint64_t *irq_levels, int *irq_counts, + int irq, int level); #endif /* QEMU_I8259_INTERNAL_H */ diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c index b56e4fced4..3e65b243cf 100644 --- a/hw/i386/kvm/i8259.c +++ b/hw/i386/kvm/i8259.c @@ -45,6 +45,9 @@ struct KVMI8259PICState { ISABus *isabus; KVMI8259State i8259[2]; + + int irq_level[ISA_NUM_IRQS]; + uint64_t irq_count[ISA_NUM_IRQS]; }; OBJECT_DECLARE_SIMPLE_TYPE(KVMI8259PICState, KVM_I8259_PIC) @@ -117,6 +120,18 @@ static void kvm_i8259_put(I8259CommonState *cs) } } +static bool kvm_i8259_pic_get_statistics(InterruptStatsProvider *obj, + uint64_t **irq_counts, + unsigned int *nb_irqs) +{ + KVMI8259PICState *s = KVM_I8259_PIC(obj); + + *irq_counts = s->irq_count; + *nb_irqs = ARRAY_SIZE(s->irq_count); + + return true; +} + static void kvm_i8259_reset(DeviceState *dev) { I8259CommonState *cs = I8259_COMMON(dev); @@ -129,9 +144,10 @@ static void kvm_i8259_reset(DeviceState *dev) static void kvm_pic_set_irq(void *opaque, int irq, int level) { + KVMI8259PICState *s = opaque; int delivered; - i8259_stat_update_irq(irq, level); + i8259_stat_update_irq(s->irq_count, s->irq_level, irq, level); delivered = kvm_set_irq(kvm_state, irq, level); kvm_report_irq_delivered(delivered); } @@ -227,7 +243,7 @@ static void kvm_i8259_pic_class_init(ObjectClass *klass, const void *data) dc->realize = kvm_i8259_pic_realize; device_class_set_props(dc, kvm_i8259_pic_properties); - ic->get_statistics = i8259_pic_get_statistics; + ic->get_statistics = kvm_i8259_pic_get_statistics; ic->print_info = i8259_pic_print_info; /* * Reason: must be wired to the ISA bus via the "bus" property diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index 7c9ce2315a..8b1dd57849 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c @@ -64,14 +64,16 @@ struct I8259PICState { ISABus *isabus; IRQState i8259_primary_out_irq; I8259State i8259[2]; + + int irq_level[ISA_NUM_IRQS]; + uint64_t irq_count[ISA_NUM_IRQS]; +#ifdef DEBUG_IRQ_LATENCY + int64_t irq_time[ISA_NUM_IRQS]; +#endif }; OBJECT_DECLARE_SIMPLE_TYPE(I8259PICState, I8259_PIC) - -#ifdef DEBUG_IRQ_LATENCY -static int64_t irq_time[16]; -#endif I8259PICState *isa_pic; /* return the highest priority found in mask (highest = smallest @@ -138,16 +140,8 @@ static void i8259_set_irq(void *opaque, int irq, int level) { I8259CommonState *cs = opaque; int mask = 1 << irq; - int irq_index = cs->master ? irq : irq + 8; trace_i8259_set_irq(cs->master, irq, level); - i8259_stat_update_irq(irq_index, level); - -#ifdef DEBUG_IRQ_LATENCY - if (level) { - irq_time[irq_index] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - } -#endif if (cs->ltim || (cs->elcr & mask)) { /* level triggered */ @@ -224,7 +218,7 @@ int pic_read_irq(I8259PICState *s) printf("IRQ%d latency=%0.3fus\n", irq, (double)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - - irq_time[irq]) * 1000000.0 / NANOSECONDS_PER_SECOND); + s->irq_time[irq]) * 1000000.0 / NANOSECONDS_PER_SECOND); #endif trace_pic_interrupt(irq, intno); @@ -456,10 +450,30 @@ static void i8259_class_init(ObjectClass *klass, const void *data) } +static bool i8259_pic_get_statistics(InterruptStatsProvider *obj, + uint64_t **irq_counts, + unsigned int *nb_irqs) +{ + I8259PICState *s = I8259_PIC(obj); + + *irq_counts = s->irq_count; + *nb_irqs = ARRAY_SIZE(s->irq_count); + + return true; +} + static void i8259_pic_set_irq(void *opaque, int n, int level) { I8259PICState *s = opaque; + i8259_stat_update_irq(s->irq_count, s->irq_level, n, level); + +#ifdef DEBUG_IRQ_LATENCY + if (level) { + s->irq_time[n] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + } +#endif + qemu_set_irq(s->pass_irqs[n], level); } diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c index 684290fb2d..3bafd81ea7 100644 --- a/hw/intc/i8259_common.c +++ b/hw/intc/i8259_common.c @@ -30,8 +30,6 @@ #include "migration/vmstate.h" #include "qapi/error.h" -static int irq_level[16]; -static uint64_t irq_count[16]; void i8259_common_reset(I8259CommonState *cs) { @@ -89,26 +87,17 @@ static void i8259_common_realize(DeviceState *dev, Error **errp) qdev_set_legacy_instance_id(dev, cs->iobase, 1); } -void i8259_stat_update_irq(int irq, int level) +void i8259_stat_update_irq(uint64_t *irq_counts, int *irq_levels, + int irq, int level) { - if (level != irq_level[irq]) { - irq_level[irq] = level; + if (level != irq_levels[irq]) { + irq_levels[irq] = level; if (level == 1) { - irq_count[irq]++; + irq_counts[irq]++; } } } -bool i8259_pic_get_statistics(InterruptStatsProvider *obj, - uint64_t **irq_counts, - unsigned int *nb_irqs) -{ - *irq_counts = irq_count; - *nb_irqs = ARRAY_SIZE(irq_count); - - return true; -} - void i8259_pic_print_info(InterruptStatsProvider *obj, GString *buf) { /* No information for i8259-based PICs */ -- 2.43.0
