@@ -1103,7 +1103,7 @@ static void set_eoi_ready(void *data);
static void irq_guest_eoi_timer_fn(void *data)
{
struct irq_desc *desc = data;
- unsigned int irq = desc - irq_desc;
+ unsigned int irq = desc - irq_desc, done = 0;
irq_guest_action_t *action;
cpumask_t cpu_eoi_map;
unsigned long flags;
@@ -1115,6 +1115,16 @@ static void irq_guest_eoi_timer_fn(void
action = (irq_guest_action_t *)desc->action;
+ if ( action->eoi_timer.status >= TIMER_STATUS_in_heap )
+{//temp
+ static unsigned long cnt, thr;
+ if(++cnt > thr) {
+ thr |= cnt;
+ printk("IRQ%u: i=%u a=%d n=%u\n", irq, action->in_flight, action->ack_type, action->nr_guests);
+ }
+ goto out;
+}
+
if ( action->ack_type != ACKTYPE_NONE )
{
unsigned int i;
@@ -1122,11 +1132,29 @@ static void irq_guest_eoi_timer_fn(void
{
struct domain *d = action->guest[i];
unsigned int pirq = domain_irq_to_pirq(d, irq);
+
if ( test_and_clear_bool(pirq_info(d, pirq)->masked) )
- action->in_flight--;
+ ++done;
}
+ action->in_flight -= done;
}
+{//temp
+ static unsigned long done_cnt, done_thr;
+ static unsigned long infl_cnt, infl_thr;
+ bool log = false;
+ if(action->in_flight && ++infl_cnt > infl_thr) {
+ infl_thr |= infl_cnt;
+ log = true;
+ } else if(!done && ++done_cnt > done_thr) {
+ done_thr |= done_cnt;
+ log = true;
+ }
+ if(log)
+ printk("IRQ%u: d=%u i=%u a=%d n=%u (%06lx,%06lx)\n", irq, done, action->in_flight,
+ action->ack_type, action->nr_guests, done_cnt, infl_cnt);
+}
+//todo Instead of the below, assert that ->in_flight is zero and bail if done is zero?
if ( action->in_flight != 0 )
goto out;
@@ -1156,6 +1184,7 @@ static void __do_IRQ_guest(int irq)
int i, sp;
struct pending_eoi *peoi = this_cpu(pending_eoi);
unsigned int vector = (u8)get_irq_regs()->entry_vector;
+unsigned done = 0;//temp
if ( unlikely(action->nr_guests == 0) )
{
@@ -1167,6 +1196,9 @@ static void __do_IRQ_guest(int irq)
return;
}
+ if ( action->ack_type != ACKTYPE_NONE )
+ stop_timer(&action->eoi_timer);
+
if ( action->ack_type == ACKTYPE_EOI )
{
sp = pending_eoi_sp(peoi);
@@ -1187,6 +1219,7 @@ static void __do_IRQ_guest(int irq)
pirq = pirq_info(d, domain_irq_to_pirq(d, irq));
if ( (action->ack_type != ACKTYPE_NONE) &&
!test_and_set_bool(pirq->masked) )
+++done,//temp
action->in_flight++;
if ( !is_hvm_domain(d) || !hvm_do_IRQ_dpci(d, pirq) )
send_guest_pirq(d, pirq);
@@ -1194,10 +1227,16 @@ static void __do_IRQ_guest(int irq)
if ( action->ack_type != ACKTYPE_NONE )
{
- stop_timer(&action->eoi_timer);
migrate_timer(&action->eoi_timer, smp_processor_id());
set_timer(&action->eoi_timer, NOW() + MILLISECS(1));
}
+if(!done) {//temp
+ static unsigned long cnt, thr;
+ if(++cnt > thr) {
+ thr |= cnt;
+ printk("IRQ%d: d=0 n=%u i=%u a=%d\n", irq, action->nr_guests, action->in_flight, action->ack_type);
+ }
+}
}
/*
@@ -1457,6 +1496,8 @@ void desc_guest_eoi(struct irq_desc *des
return;
}
+ stop_timer(&action->eoi_timer);
+
if ( action->ack_type == ACKTYPE_UNMASK )
{
ASSERT(cpumask_empty(action->cpu_eoi_map));