[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Xen-devel] Using xen-unstable, dom0 hangs during boot



> -----Original Message-----
On 02/25/2010 02:18 PM, Nadolski, Ed wrote:
> I'm running Fedora 12 (kernel 2.6.31.5-127.fc12.x86_64) on a Dell T7500 Xeon 
> with VT-x and VT-d. After building xen-unstable and rebooting, the dom0 Linux 
> hangs a few seconds after it gets control from Xen, and I have to power-cycle 
> to recover.   Here are the last messages before it hangs:
>
> [    2.766882] loop: module loaded
> [    2.767736] input: Macintosh mouse button emulation as 
> /devices/virtual/input/input2
> [    2.769396] xen_set_ioapic_routing: irq 20 gsi 20 vector 20 ioapic 0 pin 
> 20 triggering 1 polarity 1
> [    2.770342] achi 0000:00:1f.2: PCI INT C ->  GSI 20 (level, low) ->  IRQ 20
> [    2.771158] ahci 0000:00:1f.2: AHCI 0001.0200 32 slots 6 ports 3 Gbps 0x27 
> impl SATA mode
> [    2.772078] ahci 0000:00:1f.2: flags: 64bit ncq sntf led clo pio ems
> <<hangs at this point>>



I've added a bunch of trace prints. With serial ports enabled for trace 
capture, the hang actually occurs earlier than the ahci code above. It now 
occurs during the serial8250_config_port() function in the 8250/16650 serial 
driver initialization. There is a call to probe_irq_on(), which calls 
msleep(20), but the msleep() never returns.  (see below)

If I hit the power button on the front panel, it generates an interrupt that 
forces the msleep() to return.  Also, if I replace the msleep(20) with 
mdelay(20), the code does not hang at that point.  (In either case, the code 
does hang again a short while later.)

I'm not too familiar with kernel internals - what could cause the msleep() not 
to return?  Possibly an interrupt gets missed, or is not getting unmasked?

Thanks again,
Ed


/root/xen/xen-unstable.hg/linux-2.6-pvops.git/kernel/irq/autoprobe.c:

/**
 *      probe_irq_on    - begin an interrupt autodetect
 *
 *      Commence probing for an interrupt. The interrupts are scanned
 *      and a mask of potential interrupt lines is returned.
 *
 */
unsigned long probe_irq_on(void)
{
        struct irq_desc *desc;
        unsigned long mask = 0;
        unsigned int status;
        int i;

        /*
         * quiesce the kernel, or at least the asynchronous portion
         */
        async_synchronize_full();
        mutex_lock(&probing_active);
        /*
         * something may have generated an irq long ago and we want to
         * flush such a longstanding irq before considering it as spurious.
         */
        for_each_irq_desc_reverse(i, desc) {
                spin_lock_irq(&desc->lock);
                if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
                        /*
                         * An old-style architecture might still have
                         * the handle_bad_irq handler there:
                         */
                        compat_irq_chip_set_default_handler(desc);

                        /*
                         * Some chips need to know about probing in
                         * progress:
                         */
                        if (desc->chip->set_type)
                                desc->chip->set_type(i, IRQ_TYPE_PROBE);
                        desc->chip->startup(i);
                }
                spin_unlock_irq(&desc->lock);
        }

        /* Wait for longstanding interrupts to trigger. */
        msleep(20);  <==  NEVER RETURNS (until power button is hit)

        /*
         * enable any unassigned irqs
         * (we must startup again here because if a longstanding irq
         * happened in the previous stage, it may have masked itself)
         */
        for_each_irq_desc_reverse(i, desc) {
                spin_lock_irq(&desc->lock);
                if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
                        desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
                        if (desc->chip->startup(i))
                                desc->status |= IRQ_PENDING;
                }
                spin_unlock_irq(&desc->lock);
        }

        /*
         * Wait for spurious interrupts to trigger
         */
        msleep(100);  <== ALSO HANGS HERE AND NEVER RETURNS until power button 
is hit.

        /*
         * Now filter out any obviously spurious interrupts
         */
        for_each_irq_desc(i, desc) {
                spin_lock_irq(&desc->lock);
                status = desc->status;

                if (status & IRQ_AUTODETECT) {
                        /* It triggered already - consider it spurious. */
                        if (!(status & IRQ_WAITING)) {
                                desc->status = status & ~IRQ_AUTODETECT;
                                desc->chip->shutdown(i);
                        } else
                                if (i < 32)
                                        mask |= 1 << i;
                }
                spin_unlock_irq(&desc->lock);
        }

        return mask;
}
EXPORT_SYMBOL(probe_irq_on);



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.