[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(); <===============
        }