qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@web.de>
To: Blue Swirl <blauwirbel@gmail.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>,
	Paul Brook <paul@codesourcery.com>,
	qemu-devel@nongnu.org, Gleb Natapov <gleb@redhat.com>,
	Juan Quintela <quintela@redhat.com>
Subject: [Qemu-devel] Re: [PATCH 10/16] x86: Refactor RTC IRQ coalescing workaround
Date: Sun, 06 Jun 2010 11:06:37 +0200	[thread overview]
Message-ID: <4C0B651D.1030307@web.de> (raw)
In-Reply-To: <AANLkTin2Jok8WQ3h4puJ1f_xX2h7cZg1CIKxTM7iRzv4@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 12764 bytes --]

Blue Swirl wrote:
> On Sun, Jun 6, 2010 at 8:10 AM, Jan Kiszka <jan.kiszka@web.de> wrote:
>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>
>> Make use of the new IRQ message and report delivery results from the
>> sink to the source. As a by-product, this also adds de-coalescing
>> support to the PIC.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  hw/apic.c        |   64 +++++++++++++++++++----------------------
>>  hw/apic.h        |    9 ++----
>>  hw/i8259.c       |   16 ++++++++++-
>>  hw/ioapic.c      |   20 ++++++++++---
>>  hw/mc146818rtc.c |   83 ++++++++++++++++++++++++++++++++++-------------------
>>  hw/pc.c          |   29 ++++++++++++++++--
>>  6 files changed, 141 insertions(+), 80 deletions(-)
>>
>> diff --git a/hw/apic.c b/hw/apic.c
>> index 7fbd79b..f9587d1 100644
>> --- a/hw/apic.c
>> +++ b/hw/apic.c
>> @@ -123,10 +123,8 @@ typedef struct APICState {
>>  static int apic_io_memory;
>>  static APICState *local_apics[MAX_APICS + 1];
>>  static int last_apic_idx = 0;
>> -static int apic_irq_delivered;
>>
>> -
>> -static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
>> +static int apic_set_irq(APICState *s, int vector_num, int trigger_mode);
>>  static void apic_update_irq(APICState *s);
>>  static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
>>                                       uint8_t dest, uint8_t dest_mode);
>> @@ -239,12 +237,12 @@ void apic_deliver_pic_intr(CPUState *env, int level)
>>     }\
>>  }
>>
>> -static void apic_bus_deliver(const uint32_t *deliver_bitmask,
>> -                             uint8_t delivery_mode,
>> -                             uint8_t vector_num, uint8_t polarity,
>> -                             uint8_t trigger_mode)
>> +static int apic_bus_deliver(const uint32_t *deliver_bitmask,
>> +                            uint8_t delivery_mode, uint8_t vector_num,
>> +                            uint8_t polarity, uint8_t trigger_mode)
>>  {
>>     APICState *apic_iter;
>> +    int ret;
>>
>>     switch (delivery_mode) {
>>         case APIC_DM_LOWPRI:
>> @@ -261,11 +259,12 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask,
>>                 if (d >= 0) {
>>                     apic_iter = local_apics[d];
>>                     if (apic_iter) {
>> -                        apic_set_irq(apic_iter, vector_num, trigger_mode);
>> +                        return apic_set_irq(apic_iter, vector_num,
>> +                                            trigger_mode);
>>                     }
>>                 }
>>             }
>> -            return;
>> +            return QEMU_IRQ_MASKED;
>>
>>         case APIC_DM_FIXED:
>>             break;
>> @@ -273,34 +272,42 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask,
>>         case APIC_DM_SMI:
>>             foreach_apic(apic_iter, deliver_bitmask,
>>                 cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
>> -            return;
>> +            return QEMU_IRQ_DELIVERED;
>>
>>         case APIC_DM_NMI:
>>             foreach_apic(apic_iter, deliver_bitmask,
>>                 cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
>> -            return;
>> +            return QEMU_IRQ_DELIVERED;
>>
>>         case APIC_DM_INIT:
>>             /* normal INIT IPI sent to processors */
>>             foreach_apic(apic_iter, deliver_bitmask,
>>                          cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_INIT) );
>> -            return;
>> +            return QEMU_IRQ_DELIVERED;
>>
>>         case APIC_DM_EXTINT:
>>             /* handled in I/O APIC code */
>>             break;
>>
>>         default:
>> -            return;
>> +            return QEMU_IRQ_MASKED;
>>     }
>>
>> +    ret = QEMU_IRQ_MASKED;
>>     foreach_apic(apic_iter, deliver_bitmask,
>> -                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
>> +        if (ret == QEMU_IRQ_MASKED)
>> +            ret = QEMU_IRQ_COALESCED;
>> +        if (apic_set_irq(apic_iter, vector_num,
>> +                         trigger_mode) == QEMU_IRQ_DELIVERED) {
>> +            ret = QEMU_IRQ_DELIVERED;
>> +        }
>> +    );
>> +    return ret;
>>  }
>>
>> -void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
>> -                      uint8_t delivery_mode, uint8_t vector_num,
>> -                      uint8_t polarity, uint8_t trigger_mode)
>> +int apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
>> +                     uint8_t delivery_mode, uint8_t vector_num,
>> +                     uint8_t polarity, uint8_t trigger_mode)
>>  {
>>     uint32_t deliver_bitmask[MAX_APIC_WORDS];
>>
>> @@ -308,8 +315,8 @@ void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
>>             " polarity %d trigger_mode %d\n", __func__, dest, dest_mode,
>>             delivery_mode, vector_num, polarity, trigger_mode);
>>     apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
>> -    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
>> -                     trigger_mode);
>> +    return apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num,
>> +                            polarity, trigger_mode);
>>  }
>>
>>  void cpu_set_apic_base(CPUState *env, uint64_t val)
>> @@ -402,22 +409,10 @@ static void apic_update_irq(APICState *s)
>>     cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
>>  }
>>
>> -void apic_reset_irq_delivered(void)
>> -{
>> -    DPRINTF_C("%s: old coalescing %d\n", __func__, apic_irq_delivered);
>> -    apic_irq_delivered = 0;
>> -}
>> -
>> -int apic_get_irq_delivered(void)
>> -{
>> -    DPRINTF_C("%s: returning coalescing %d\n", __func__, apic_irq_delivered);
>> -    return apic_irq_delivered;
>> -}
>> -
>> -static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
>> +static int apic_set_irq(APICState *s, int vector_num, int trigger_mode)
>>  {
>> -    apic_irq_delivered += !get_bit(s->irr, vector_num);
>> -    DPRINTF_C("%s: coalescing %d\n", __func__, apic_irq_delivered);
>> +    int ret = get_bit(s->irr, vector_num) ? QEMU_IRQ_COALESCED
>> +                                          : QEMU_IRQ_DELIVERED;
>>
>>     set_bit(s->irr, vector_num);
>>     if (trigger_mode)
>> @@ -425,6 +420,7 @@ static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
>>     else
>>         reset_bit(s->tmr, vector_num);
>>     apic_update_irq(s);
>> +    return ret;
>>  }
>>
>>  static void apic_eoi(APICState *s)
>> diff --git a/hw/apic.h b/hw/apic.h
>> index e1954f4..738d98a 100644
>> --- a/hw/apic.h
>> +++ b/hw/apic.h
>> @@ -2,17 +2,14 @@
>>  #define APIC_H
>>
>>  typedef struct IOAPICState IOAPICState;
>> -void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
>> -                             uint8_t delivery_mode,
>> -                             uint8_t vector_num, uint8_t polarity,
>> -                             uint8_t trigger_mode);
>> +int apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
>> +                     uint8_t delivery_mode, uint8_t vector_num,
>> +                     uint8_t polarity, uint8_t trigger_mode);
>>  int apic_init(CPUState *env);
>>  int apic_accept_pic_intr(CPUState *env);
>>  void apic_deliver_pic_intr(CPUState *env, int level);
>>  int apic_get_interrupt(CPUState *env);
>>  qemu_irq *ioapic_init(void);
>> -void apic_reset_irq_delivered(void);
>> -int apic_get_irq_delivered(void);
>>
>>  int cpu_is_bsp(CPUState *env);
>>
>> diff --git a/hw/i8259.c b/hw/i8259.c
>> index f743ee8..09150c4 100644
>> --- a/hw/i8259.c
>> +++ b/hw/i8259.c
>> @@ -189,6 +189,9 @@ int64_t irq_time[16];
>>  static void i8259_set_irq(qemu_irq irq, void *opaque, int n, int level)
>>  {
>>     PicState2 *s = opaque;
>> +    PicState *pic;
>> +    int result = QEMU_IRQ_DELIVERED;
>> +    int mask;
>>
>>  #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
>>     if (level != irq_level[n]) {
>> @@ -205,8 +208,19 @@ static void i8259_set_irq(qemu_irq irq, void *opaque, int n, int level)
>>         irq_time[n] = qemu_get_clock(vm_clock);
>>     }
>>  #endif
>> -    pic_set_irq1(&s->pics[n >> 3], n & 7, level);
>> +    pic = &s->pics[n >> 3];
>> +    n &= 7;
>> +    mask = 1 << n;
>> +    if (level) {
>> +        if (pic->imr & mask) {
>> +            result = QEMU_IRQ_MASKED;
>> +        } else if (pic->irr & mask) {
>> +            result = QEMU_IRQ_COALESCED;
>> +        }
>> +    }
>> +    pic_set_irq1(pic, n, level);
>>     pic_update_irq(s);
>> +    qemu_irq_fire_delivery_cb(irq, level, result);
>>  }
>>
>>  /* acknowledge interrupt 'irq' */
>> diff --git a/hw/ioapic.c b/hw/ioapic.c
>> index d818573..b54738f 100644
>> --- a/hw/ioapic.c
>> +++ b/hw/ioapic.c
>> @@ -58,7 +58,7 @@ struct IOAPICState {
>>     uint64_t ioredtbl[IOAPIC_NUM_PINS];
>>  };
>>
>> -static void ioapic_service(IOAPICState *s)
>> +static int ioapic_service(IOAPICState *s)
>>  {
>>     uint8_t i;
>>     uint8_t trig_mode;
>> @@ -69,12 +69,16 @@ static void ioapic_service(IOAPICState *s)
>>     uint8_t dest;
>>     uint8_t dest_mode;
>>     uint8_t polarity;
>> +    int ret = QEMU_IRQ_MASKED;
>>
>>     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
>>         mask = 1 << i;
>>         if (s->irr & mask) {
>>             entry = s->ioredtbl[i];
>>             if (!(entry & IOAPIC_LVT_MASKED)) {
>> +                if (ret == QEMU_IRQ_MASKED) {
>> +                    ret = QEMU_IRQ_COALESCED;
>> +                }
>>                 trig_mode = ((entry >> 15) & 1);
>>                 dest = entry >> 56;
>>                 dest_mode = (entry >> 11) & 1;
>> @@ -87,16 +91,21 @@ static void ioapic_service(IOAPICState *s)
>>                 else
>>                     vector = entry & 0xff;
>>
>> -                apic_deliver_irq(dest, dest_mode, delivery_mode,
>> -                                 vector, polarity, trig_mode);
>> +                if (apic_deliver_irq(dest, dest_mode,
>> +                                     delivery_mode, vector, polarity,
>> +                                     trig_mode) == QEMU_IRQ_DELIVERED) {
>> +                    ret = QEMU_IRQ_DELIVERED;
>> +                }
>>             }
>>         }
>>     }
>> +    return ret;
>>  }
>>
>>  static void ioapic_set_irq(qemu_irq irq, void *opaque, int vector, int level)
>>  {
>>     IOAPICState *s = opaque;
>> +    int result = QEMU_IRQ_MASKED;
>>
>>     /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps
>>      * to GSI 2.  GSI maps to ioapic 1-1.  This is not
>> @@ -114,7 +123,7 @@ static void ioapic_set_irq(qemu_irq irq, void *opaque, int vector, int level)
>>             /* level triggered */
>>             if (level) {
>>                 s->irr |= mask;
>> -                ioapic_service(s);
>> +                result = ioapic_service(s);
>>             } else {
>>                 s->irr &= ~mask;
>>             }
>> @@ -122,10 +131,11 @@ static void ioapic_set_irq(qemu_irq irq, void *opaque, int vector, int level)
>>             /* edge triggered */
>>             if (level) {
>>                 s->irr |= mask;
>> -                ioapic_service(s);
>> +                result = ioapic_service(s);
>>             }
>>         }
>>     }
>> +    qemu_irq_fire_delivery_cb(irq, level, result);
>>  }
>>
>>  static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
>> diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
>> index c3e6a70..cbb98a4 100644
>> --- a/hw/mc146818rtc.c
>> +++ b/hw/mc146818rtc.c
>> @@ -25,7 +25,6 @@
>>  #include "qemu-timer.h"
>>  #include "sysemu.h"
>>  #include "pc.h"
>> -#include "apic.h"
>>  #include "isa.h"
>>  #include "hpet_emul.h"
>>  #include "mc146818rtc.h"
>> @@ -101,7 +100,7 @@ typedef struct RTCState {
>>     QEMUTimer *second_timer2;
>>  } RTCState;
>>
>> -static void rtc_irq_raise(qemu_irq irq)
>> +static void rtc_irq_raise(RTCState *s, IRQMsg *msg)
>>  {
>>     /* When HPET is operating in legacy mode, RTC interrupts are disabled
>>      * We block qemu_irq_raise, but not qemu_irq_lower, in case legacy
>> @@ -109,9 +108,14 @@ static void rtc_irq_raise(qemu_irq irq)
>>      * be lowered in any case
>>      */
>>  #if defined TARGET_I386
>> -    if (!hpet_in_legacy_mode())
>> +    if (hpet_in_legacy_mode()) {
>> +        if (msg) {
>> +            msg->delivery_cb(s->irq, s, -1, -1, QEMU_IRQ_MASKED);
> 
> Shouldn't you use qemu_irq_fire_delivery_cb() here?

We didn't send msg, so it is not yet associated with s->irq at this
point. Moreover, this hunk is only temporarily, removed in patch 11 again.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]

  reply	other threads:[~2010-06-06  9:06 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-06  8:10 [Qemu-devel] [PATCH 00/16] HPET cleanups, fixes, enhancements Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 01/16] hpet: Catch out-of-bounds timer access Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 02/16] hpet: Coding style cleanups and some refactorings Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 03/16] hpet: Silence warning on write to running main counter Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 04/16] hpet: Move static timer field initialization Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 05/16] hpet: Convert to qdev Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 06/16] hpet: Start/stop timer when HPET_TN_ENABLE is modified Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 07/16] monitor/QMP: Drop info hpet / query-hpet Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 08/16] Pass IRQ object on handler invocation Jan Kiszka
2010-06-12 10:31   ` [Qemu-devel] [PATCH v3 " Jan Kiszka
2010-06-06  8:10 ` [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs Jan Kiszka
2010-06-12 12:21   ` Paul Brook
2010-06-12 12:32     ` Jan Kiszka
2010-06-12 13:44     ` Blue Swirl
2010-06-12 14:15       ` Paul Brook
2010-06-12 14:35         ` Blue Swirl
2010-06-12 15:58           ` Paul Brook
2010-06-12 19:33             ` Blue Swirl
2010-06-12 20:15               ` Paul Brook
2010-06-12 20:32               ` Blue Swirl
2010-06-13  6:47                 ` Blue Swirl
2010-06-13 15:49                 ` Paul Brook
2010-06-13 18:17                   ` Blue Swirl
2010-06-13 18:39                     ` Paul Brook
2010-06-13 18:54                       ` Blue Swirl
2010-06-13 19:38                         ` Paul Brook
2010-06-13 16:34         ` Paul Brook
2010-06-13 18:04           ` Blue Swirl
2010-06-14  5:40           ` Gleb Natapov
2010-06-06  8:10 ` [Qemu-devel] [PATCH 10/16] x86: Refactor RTC IRQ coalescing workaround Jan Kiszka
2010-06-06  8:49   ` [Qemu-devel] " Blue Swirl
2010-06-06  9:06     ` Jan Kiszka [this message]
2010-06-06  8:11 ` [Qemu-devel] [PATCH 11/16] hpet/rtc: Rework RTC IRQ replacement by HPET Jan Kiszka
2010-06-06  8:53   ` [Qemu-devel] " Blue Swirl
2010-06-06  9:09     ` Jan Kiszka
2010-06-06  8:11 ` [Qemu-devel] [PATCH 12/16] hpet: Drop static state Jan Kiszka
2010-06-06  8:11 ` [Qemu-devel] [PATCH 13/16] hpet: Add support for level-triggered interrupts Jan Kiszka
2010-06-06  8:11 ` [Qemu-devel] [PATCH 14/16] vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8 Jan Kiszka
2010-06-06  8:11 ` [Qemu-devel] [PATCH 15/16] hpet: Make number of timers configurable Jan Kiszka
2010-06-06  8:11 ` [Qemu-devel] [PATCH 16/16] hpet: Add MSI support Jan Kiszka
2010-06-11 21:31   ` Paul Brook
2010-06-12 10:23     ` [Qemu-devel] [PATCH v3 " Jan Kiszka
2010-06-06  8:56 ` [Qemu-devel] Re: [PATCH 00/16] HPET cleanups, fixes, enhancements Blue Swirl
2010-06-06  9:12   ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C0B651D.1030307@web.de \
    --to=jan.kiszka@web.de \
    --cc=blauwirbel@gmail.com \
    --cc=gleb@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=paul@codesourcery.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).