[Prism54-devel] Oops: interrupt handler registration + rx interrupt collision
vda@port.imtp.ilyichevsk.odessa.ua
vda@port.imtp.ilyichevsk.odessa.ua
Thu, 12 Feb 2004 23:36:17 +0200
2.6.2
modprobe prism54 oopsed.
Copied from screen by hand:
driver_attach+n
bus_add_driver+n
driver_attach+n
bus_match+n
pci_device_probe+n
__pci_device_probe+n
pci_device_probe_static+n
islpci_interrupt+0 (+0: seems like a parameter on stack, not a ret addr)
prism54_probe+n
request_irq+n
islpci_interrupt+0
setup_irq+n
common_interrupt+n
do_IRQ+n (an interrupt struck us?)
handle_IRQ_event+33/60
islpci_interrupt+293/510
islpci_eth_receive+2f6/4b0
netif_rx+a4/190
netif_rx+a4/190 (second one is due to printk("(from %p)", NET_CALLER(skb)). see below)
Code: 0f 0b ..... (thats a BUG)
Here's how it happened:
islpci_eth.c
============
int
islpci_eth_receive(islpci_private *priv)
{
...
/* the device has written an Ethernet frame in the data area
* of the sk_buff without updating the structure, do it now */
index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE;
size = le16_to_cpu(control_block->rx_data_low[index].size);
skb = priv->data_low_rx[index];
...
if (discard)
dev_kfree_skb(skb);
else
netif_rx(skb); <=====================
dev.c
=====
int netif_rx(struct sk_buff *skb)
{
....
drop:
__get_cpu_var(netdev_rx_stat).dropped++;
local_irq_restore(flags);
kfree_skb(skb); <=======================
return NET_RX_DROP;
}
skbuff.c
========
void __kfree_skb(struct sk_buff *skb)
{
if (skb->list) {
printk(KERN_WARNING "Warning: kfree_skb passed an skb still "
"on a list (from %p).\n", NET_CALLER(skb));
BUG(); <===============
}