netdev
[Top] [All Lists]

Re: fealnx oopses

To: Jeff Garzik <jgarzik@xxxxxxxxx>, Francois Romieu <romieu@xxxxxxxxxxxxx>
Subject: Re: fealnx oopses
From: Denis Vlasenko <vda@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 27 Mar 2004 23:28:51 +0200
Cc: Andreas Henriksson <andreas@xxxxxxxxxxxx>, netdev@xxxxxxxxxxx
In-reply-to: <4064BB35.4050301@xxxxxxxxx>
References: <200403261214.58127.vda@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> <20040326233514.B26347@xxxxxxxxxxxxxxxxxxxxxxxxxx> <4064BB35.4050301@xxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: KMail/1.5.4
On Saturday 27 March 2004 01:22, Jeff Garzik wrote:
> Francois Romieu wrote:
> > Denis Vlasenko <vda@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> :
> > [...]
> >
> >>Yes. But on x86 a++ is atomic vs interrupts - it's a single instruction
> >>and interrupts happen on instruction boundaries only.
> >
> > Do you realize that you are saying that the CPU can atomically increment
> > an integer which sits _in memory_ ?
>
> Sure you can...
>
> But start_tx() has two variables free_tx_count and
> really_tx_count, and about six or seven places those are used.
>
> And this comment...
>
> > I can. The problem is, I cannot reproduce oops _without_ patch,
> > and this renders testing useless.
>
> Sounds like it fixes the problem, to me.
>
>       Jeff

Okay I can reproduce it now. 16 Mb of RAM and underclock to 125 MHz
did the trick ;)

Sorry Jeff your patch does not fix my problem.
I also verified that it happens this way:
(1) rx skb is processed and freed
(2) allocation failure for new skb
(3) next rx intr occurs, cur_rx->skbuff still == NULL
(4) oops

I modified code as follows and I did see all these printk()s
in sequence:

                        } else {
                                if(np->cur_rx->skbuff == NULL)
(3)                                     printk(KERN_ERR "vda: 
np->cur_rx->skbuff == NULL!\n"); //vda
(4)                             skb_put(skb = np->cur_rx->skbuff, pkt_len);
(1)                             np->cur_rx->skbuff = NULL;
                                if (np->really_rx_count == RX_RING_SIZE)
                                        np->lack_rxbuf = np->cur_rx;
                                --np->really_rx_count;
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
                        dev->last_rx = jiffies;
                        np->stats.rx_packets++;
                        np->stats.rx_bytes += pkt_len;
                }

                if (np->cur_rx->skbuff == NULL) {
                        struct sk_buff *skb;

                        skb = dev_alloc_skb(np->rx_buf_sz);

                        if (skb != NULL) {
                                skb->dev = dev; /* Mark as being used by this 
device. */
                                np->cur_rx->buffer = 
pci_map_single(np->pci_dev, skb->tail,
                                        np->rx_buf_sz, PCI_DMA_FROMDEVICE);
                                np->cur_rx->skbuff = skb;
                                ++np->really_rx_count;
                        } else { //vda
(2)                             printk(KERN_ERR "vda: low on mem, cannot 
allocate skb!\n");
                        }
                }
--
vda


<Prev in Thread] Current Thread [Next in Thread>