From: Russell King <rmk+lkml@arm.linux.org.uk>
To: Meelis Roos <mroos@linux.ee>
Cc: alan@lxorguk.ukuu.org.uk, linux-kernel@vger.kernel.org
Subject: Re: Serial: bug in 8250.c when handling PCI or other level triggers
Date: Wed, 21 Dec 2005 22:15:16 +0000 [thread overview]
Message-ID: <20051221221516.GK1736@flint.arm.linux.org.uk> (raw)
In-Reply-To: <Pine.SOC.4.61.0512212221310.651@math.ut.ee>
On Wed, Dec 21, 2005 at 10:33:37PM +0200, Meelis Roos wrote:
> >Hmm, possibly, but could you apply this patch and provide the resulting
> >messages please? It'll probably cause some character loss when it
> >decides to dump some debugging.
>
> Here is the full dmesg with it, from ICH2. First messages are from
> serial port initialisation and the last ones are from running minicom at
> 9600 as thje console for a cisco.
Urm, this is silly. Lets look at the first instance.
> lp0: ECP mode
> serial8250: too much work for irq4
> serial8250: port c0452c80(0)
> 0: jif=00000000 type=00 num=00 iir=00 lsr=00 => iir=00 lsr=00
> ...
> 29: jif=00000000 type=00 num=00 iir=00 lsr=00 => iir=00 lsr=00
> 30: jif=fffef262 type=00 num=00 iir=01 lsr=00 => iir=01 lsr=00
This is the first interrupt we apparantly recieved. We start with
end = NULL, l = i->head, and pass_counter starts off at zero (as
can be seen in the num line above.)
up = list_entry(l, struct uart_8250_port, list);
iir = serial_in(up, UART_IIR);
The IIR for the device reports 0x01 (IIR_NO_INT set) so no interrupt
was pending, so:
if (!(iir & UART_IIR_NO_INT)) {
} else if (end == NULL)
end = l;
we set our end marker to this port and move on to the next port.
l = l->next;
Since we only have one port open on this IRQ, l is equal to l->next
so this has no effect.
if (l == i->head && pass_counter++ > PASS_LIMIT) {
since l is still equal to i->head, we increment the pass counter.
} while (l != end);
We set end = l above. Given the comments above, that means that l
_is_ equal to end, so we should exit this loop.
> 31: jif=fffef262 type=00 num=01 iir=01 lsr=60 => iir=01 lsr=60
However, strangely we don't exit the loop, but we go around for
another go - since we can see num=1 here, which means pass_counter
is now '1'.
In addition, what's weirder is that iir is still saying NO_INT,
yet we seem to have taken a completely different path through
the code since the LSR value is now set. This is only set in the
other branch of the if statement, inside serial8250_handle_port().
> 32: jif=fffef262 type=00 num=02 iir=01 lsr=60 => iir=01 lsr=60
And we go again... and again...
> 62: jif=fffef262 type=00 num=20 iir=01 lsr=60 => iir=01 lsr=60
> 63: jif=fffef262 type=00 num=21 iir=01 lsr=60 => iir=01 lsr=60
until we hit the PASS_LIMIT and produce this dump.
The rest of the dumps show a very similar situation. To me, it
looks like your machine is _not_ doing what the C code is telling
it to do. Compiler bug maybe?
> serial8250: too much work for irq4
> serial8250: port c0452c80(0)
> 0: jif=fffef262 type=00 num=06 iir=01 lsr=60 => iir=01 lsr=60
> 1: jif=fffef262 type=00 num=07 iir=01 lsr=60 => iir=01 lsr=60
> 2: jif=fffef262 type=00 num=08 iir=01 lsr=60 => iir=01 lsr=60
> 3: jif=fffef262 type=00 num=09 iir=01 lsr=60 => iir=01 lsr=60
> 4: jif=fffef262 type=00 num=0a iir=01 lsr=60 => iir=01 lsr=60
> 5: jif=fffef262 type=00 num=0b iir=01 lsr=60 => iir=01 lsr=60
> 6: jif=fffef262 type=00 num=0c iir=01 lsr=60 => iir=01 lsr=60
> 7: jif=fffef262 type=00 num=0d iir=01 lsr=60 => iir=01 lsr=60
> 8: jif=fffef262 type=00 num=0e iir=01 lsr=60 => iir=01 lsr=60
> 9: jif=fffef262 type=00 num=0f iir=01 lsr=60 => iir=01 lsr=60
> 10: jif=fffef262 type=00 num=10 iir=01 lsr=60 => iir=01 lsr=60
> 11: jif=fffef262 type=00 num=11 iir=01 lsr=60 => iir=01 lsr=60
> 12: jif=fffef262 type=00 num=12 iir=01 lsr=60 => iir=01 lsr=60
> 13: jif=fffef262 type=00 num=13 iir=01 lsr=60 => iir=01 lsr=60
> 14: jif=fffef262 type=00 num=14 iir=01 lsr=60 => iir=01 lsr=60
> 15: jif=fffef262 type=00 num=15 iir=01 lsr=60 => iir=01 lsr=60
> 16: jif=fffef262 type=00 num=16 iir=01 lsr=60 => iir=01 lsr=60
> 17: jif=fffef262 type=00 num=17 iir=01 lsr=60 => iir=01 lsr=60
> 18: jif=fffef262 type=00 num=18 iir=01 lsr=60 => iir=01 lsr=60
> 19: jif=fffef262 type=00 num=19 iir=01 lsr=60 => iir=01 lsr=60
> 20: jif=fffef262 type=00 num=1a iir=01 lsr=60 => iir=01 lsr=60
> 21: jif=fffef262 type=00 num=1b iir=01 lsr=60 => iir=01 lsr=60
> 22: jif=fffef262 type=00 num=1c iir=01 lsr=60 => iir=01 lsr=60
> 23: jif=fffef262 type=00 num=1d iir=01 lsr=60 => iir=01 lsr=60
> 24: jif=fffef262 type=00 num=1e iir=01 lsr=60 => iir=01 lsr=60
> 25: jif=fffef262 type=00 num=1f iir=01 lsr=60 => iir=01 lsr=60
> 26: jif=fffef262 type=00 num=20 iir=01 lsr=60 => iir=01 lsr=60
> 27: jif=fffef262 type=00 num=21 iir=01 lsr=60 => iir=01 lsr=60
> 28: jif=fffef2c8 type=00 num=00 iir=c2 lsr=60 => iir=c1 lsr=60
Ah, a real interrupt for once - a transmit interrupt which we
service, and then...
> 29: jif=fffef2c8 type=00 num=01 iir=c1 lsr=00 => iir=c1 lsr=00
recheck the interrupt status and then exit as we should always
do. Why this is any different from the previous one I've no
idea... so maybe it can't be a compiler bug...
Unless the compiler is messing up the initialiser for:
struct list_head *l, *end = NULL;
Could you try placing a:
BUG_ON(end != NULL);
between:
spin_lock(&i->lock);
and:
l = i->head;
in serial8250_interrupt please?
If that doesn't trigger, then I'm all out of ideas.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
next prev parent reply other threads:[~2005-12-21 22:15 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-12-14 15:23 Serial: bug in 8250.c when handling PCI or other level triggers Alan Cox
2005-12-14 16:07 ` Meelis Roos
2005-12-14 17:24 ` Russell King
2005-12-14 18:43 ` Meelis Roos
2005-12-21 15:24 ` Russell King
2005-12-21 20:33 ` Meelis Roos
2005-12-21 22:15 ` Russell King [this message]
2005-12-22 10:35 ` Meelis Roos
2005-12-22 13:07 ` Russell King
2005-12-22 13:19 ` Meelis Roos
2005-12-23 9:20 ` Meelis Roos
2005-12-23 9:33 ` Russell King
2005-12-23 10:05 ` Meelis Roos
2005-12-23 10:41 ` Russell King
2005-12-27 13:54 ` Meelis Roos
2005-12-28 19:55 ` Russell King
2005-12-29 8:11 ` Meelis Roos
2006-01-08 23:24 ` Antonio Vargas
2006-01-09 8:54 ` Russell King
2005-12-14 22:29 ` Alan Cox
2005-12-15 19:00 ` Stuart MacDonald
2005-12-14 16:55 ` Russell King
2005-12-14 19:08 ` Alan Cox
2005-12-14 19:55 ` Russell King
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=20051221221516.GK1736@flint.arm.linux.org.uk \
--to=rmk+lkml@arm.linux.org.uk \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=mroos@linux.ee \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.