lkml.org 
[lkml]   [2007]   [Aug]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: 2.6.20->2.6.21 - networking dies after random time

    * Marcin Ślusarz <marcin.slusarz@gmail.com> wrote:

    > 2007/7/31, Jarek Poplawski <jarkao2@o2.pl>:
    > > Marcin,
    > >
    > > I see you're quite busy, but if after testing this next Ingo's patch
    > > you are alive yet, maybe you could try one more "idea"? No patch this
    > > time, but if you could try this after adding boot option "noirqdebug"
    > > (I'd like to be sure it's not about timinig after all).
    > It didn't change anything. Network card still timed out.

    please try Jarek's second patch too - there was a missing unmask.

    Ingo

    -------------->
    Subject: genirq: fix simple and fasteoi irq handlers
    From: Jarek Poplawski <jarkao2@o2.pl>

    After the "genirq: do not mask interrupts by default" patch interrupts
    should be disabled not immediately upon request, but after they happen.
    But, handle_simple_irq() and handle_fasteoi_irq() can skip this once or
    more if an irq is just serviced (IRQ_INPROGRESS), possibly disrupting a
    driver's work.

    The main reason of problems here, pointing the broken patch and making
    the first patch which can fix this was done by Marcin Slusarz.
    Additional test patches of Thomas Gleixner and Ingo Molnar tested by
    Marcin Slusarz helped to narrow possible reasons even more. Thanks.

    PS: this patch fixes only one evident error here, but there could be
    more places affected by above-mentioned change in irq handling.

    PS 2:
    After rethinking, IMHO, there are two most probable scenarios here:

    1. After hw resend there could be a conflict between retriggered
    edge type irq and the next level type one: e.g. if this level type
    irq (io_apic is enabled then) is triggered while retriggered irq is
    serviced (IRQ_INPROGRESS) there is goto out with eoi, and probably
    the next such levels are triggered and looping, so probably kind of
    flood in io_apic until this retriggered edge service has ended.
    2. There is something wrong with ioapic_retrigger_irq (less probable
    because this should be probably seen with 'normal' edge retriggers,
    but on the other hand, they could be less common).

    So, if there is #1, this fixed patch should work.

    But, since level types don't need this retriggers too much I think
    this "don't mask interrupts by default" idea should be rethinked:
    is there enough gain to risk such hard to diagnose errors?

    So, IMHO, there should be at least possibility to turn this off for
    level types in config (it should be a visible option, so people could
    find & try this before writing for help or changing a network card).


    Signed-off-by: Jarek Poplawski <jarkao2@o2.pl>

    ---

    diff -Nurp 2.6.23-rc1-/kernel/irq/chip.c 2.6.23-rc1/kernel/irq/chip.c
    --- 2.6.23-rc1-/kernel/irq/chip.c 2007-07-09 01:32:17.000000000 +0200
    +++ 2.6.23-rc1/kernel/irq/chip.c 2007-08-05 21:49:46.000000000 +0200
    @@ -295,12 +295,11 @@ handle_simple_irq(unsigned int irq, stru

    spin_lock(&desc->lock);

    - if (unlikely(desc->status & IRQ_INPROGRESS))
    - goto out_unlock;
    kstat_cpu(cpu).irqs[irq]++;

    action = desc->action;
    - if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
    + if (unlikely(!action || (desc->status & (IRQ_INPROGRESS |
    + IRQ_DISABLED)))) {
    if (desc->chip->mask)
    desc->chip->mask(irq);
    desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
    @@ -318,6 +317,8 @@ handle_simple_irq(unsigned int irq, stru

    spin_lock(&desc->lock);
    desc->status &= ~IRQ_INPROGRESS;
    + if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
    + desc->chip->unmask(irq);
    out_unlock:
    spin_unlock(&desc->lock);
    }
    @@ -392,18 +393,16 @@ handle_fasteoi_irq(unsigned int irq, str

    spin_lock(&desc->lock);

    - if (unlikely(desc->status & IRQ_INPROGRESS))
    - goto out;
    -
    desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
    kstat_cpu(cpu).irqs[irq]++;

    /*
    - * If its disabled or no action available
    + * If it's running, disabled or no action available
    * then mask it and get out of here:
    */
    action = desc->action;
    - if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
    + if (unlikely(!action || (desc->status & (IRQ_INPROGRESS |
    + IRQ_DISABLED)))) {
    desc->status |= IRQ_PENDING;
    if (desc->chip->mask)
    desc->chip->mask(irq);
    @@ -420,6 +419,8 @@ handle_fasteoi_irq(unsigned int irq, str

    spin_lock(&desc->lock);
    desc->status &= ~IRQ_INPROGRESS;
    + if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
    + desc->chip->unmask(irq);
    out:
    desc->chip->eoi(irq);

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-08-06 09:05    [W:2.441 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site