Gabe Black wrote:
>     I'm trying to figure out why the kernel isn't unmasking an IRQ it's 
> trying to wait for, and it would really help if I could get a source and 
> disassembly listing from objdump. I've tried it with the kernel I've 
> been running, but for some reason it doesn't include any source lines. 
> If somebody knows how to get this to work please let me know.
>
> Gabe
> _______________________________________________
> m5-dev mailing list
> m5-dev@m5sim.org
> http://m5sim.org/mailman/listinfo/m5-dev
>   
Ok, I figured out what line the problem is on. It's line 675 of 
arch/x86_64/kernel/io_apic.c in function __assign_irq_vector. It looks 
like it's comparing the mask of processors that could accept the 
interrupt (I think) with the "domain" member of the irq configuration. I 
don't know what that "domain" is or why it's set. It also only seems to 
need to check the domain if old_vector is set to something, so I think 
what it's doing is checking if the irq already has a vector assigned to 
it, and if so then bailing out. Unfortunately, that means that it never 
unmasks the redirection table entry in the I/O APIC that would let the 
timer interrupt through, and then it waits for it until it dies. The 
interrupt wouldn't get through anyway because I haven't built that yet, 
but the interrupt never tries to get through because the APIC is set to 
mask it. Does anybody know what it's trying to do in that function and 
what that domain member is/is for? The function is below.

Once I get that figured out, I'll immediately be blocked by needing to 
figure out how the various APICs will communicate over the memory 
system, namely how the local APIC in the CPU will be exposed to the 
outside world. I'll also eventually need a better way of assigning APIC 
ids and figuring out what the system configuration looks like to install 
in the MP configuration table.

Gabe



static int __assign_irq_vector(int irq, cpumask_t mask)
{
    /*
     * NOTE! The local APIC isn't very good at handling
     * multiple interrupts at the same interrupt level.
     * As the interrupt level is determined by taking the
     * vector number and shifting that right by 4, we
     * want to spread these out a bit so that they don't
     * all fall in the same interrupt level.
     *
     * Also, we've got to be careful not to trash gate
     * 0x80, because int 0x80 is hm, kind of importantish. ;)
     */
    static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
    unsigned int old_vector;
    int cpu;
    struct irq_cfg *cfg;

    BUG_ON((unsigned)irq >= NR_IRQS);
    cfg = &irq_cfg[irq];

    /* Only try and allocate irqs on cpus that are present */
    cpus_and(mask, mask, cpu_online_map);

    if ((cfg->move_in_progress) || cfg->move_cleanup_count)
        return -EBUSY;

    old_vector = cfg->vector;
    if (old_vector) {
        cpumask_t tmp;
        cpus_and(tmp, cfg->domain, mask);
        if (!cpus_empty(tmp))
            return 0;
    }

    for_each_cpu_mask(cpu, mask) {
        cpumask_t domain, new_mask;
        int new_cpu;
        int vector, offset;

        domain = vector_allocation_domain(cpu);
        cpus_and(new_mask, domain, cpu_online_map);

        vector = current_vector;
        offset = current_offset;
next:
        vector += 8;
        if (vector >= FIRST_SYSTEM_VECTOR) {
            /* If we run out of vectors on large boxen, must share them. */
            offset = (offset + 1) % 8;
            vector = FIRST_DEVICE_VECTOR + offset;
        }
        if (unlikely(current_vector == vector))
            continue;
        if (vector == IA32_SYSCALL_VECTOR)
            goto next;
        for_each_cpu_mask(new_cpu, new_mask)
            if (per_cpu(vector_irq, new_cpu)[vector] != -1)
                goto next;
        /* Found one! */
        current_vector = vector;
        current_offset = offset;
        if (old_vector) {
            cfg->move_in_progress = 1;
            cfg->old_domain = cfg->domain;
        }
        for_each_cpu_mask(new_cpu, new_mask)
            per_cpu(vector_irq, new_cpu)[vector] = irq;
        cfg->vector = vector;
        cfg->domain = domain;
        return 0;
    }
    return -ENOSPC;
}

_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to