LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Ethernet driver - kernel crashes after passing a few Ethernet frames to upper layers (https://www.linuxquestions.org/questions/linux-kernel-70/ethernet-driver-kernel-crashes-after-passing-a-few-ethernet-frames-to-upper-layers-711189/)

AustinMarton 03-12-2009 06:27 PM

Ethernet driver - kernel crashes after passing a few Ethernet frames to upper layers
 
Hi there, I am _still_ working on an uClinux Ethernet driver on the NiosII on a Cyclone2. It is similar to the DM9000 driver.

I have finally got the receive function working correctly, but it seems to have an intermittent problem, after receiving a number of frames successfully, the kernel crashes.

If I remove "netif_rx(skb)" the error does not occur. Are the upper layers not handling my frames properly? Are my frames some how malformed and therefore creating a problem when the reach the higher layers of the TCP/IP stack?

In the last few trials I did, when it crashes it happens after 3, 20, 143, 14, 2, 10 packets were received. I then get the error:
Quote:

Bad page state in process 'swapper'
page:48be64e2 flags:0x41fd0000 mapping:00000000 mapcount:12477673 count:0
Trying to fix it up, but a reboot is needed
Backtrace:
Stack from 009bfe6c:<0>
<0> 00000001<0> 00840c90<0> 41fd0000<0> 00000000<0> 00be64e9<0> 00000000<0> 48be64e2<0> 00843a18<0>
<0> 00000400<0> 00c25000<0> 009af7b4<0> 00ed7a00<0> 48be64e2<0> 00843ae0<0> 00847280<0> 00000305<0>
<0> 009093e8<0> 00ed7a00<0> 009af79c<0> 009091ac<0> 00ed7a00<0> 009091cc<0> 00ed7a00<0> 009092ac<0>
<0> 00912e10<0> 009b6594<0> 009af780<0> 00000040<0> ffffe282<0> 009af768<0> 00000001<0> 009af768<0>
<0> 00912ed4<0> 009b6594<0> ffffe282<0> 009af774<0> 009af788<0> 0000012c<0> 00000000<0> 00000040<0>
<0> 009af780<0> 009130b8<0> deadbeef<0> deadbeef<0> 009ab3e8<0> 0000000a<0> 00000001<0> 009b7810<0>
Call Trace:<0>
<0> [<00815dd8>]<0> [<00815ebc>]<0> [<008161b8>]<0> [<008014a4>]<0>
<0> [<008009cc>]<0> [<00801bf4>]<0> [<00801bfc>]<0> [<009872ac>]<0>
<0> [<008000a4>]<0>
Bad page state in process 'swapper'
page:98bb0681 flags:0x00000018 mapping:00cc8408 mapcount:0 count:0
Trying to fix it up, but a reboot is needed
Backtrace:
Stack from 009bfe6c:<0>
<0> 00000001<0> 00840c90<0> 00000018<0> 00cc8408<0> 00000000<0> 00000000<0> 98bb0681<0> 00843a18<0>
<0> 00000400<0> 00c25000<0> 009af7b4<0> 00ed7a00<0> 98bb0681<0> 00843ae0<0> 00847280<0> 00000382<0>
<0> 009093e8<0> 00ed7a00<0> 009af79c<0> 009091ac<0> 00ed7a00<0> 009091cc<0> 00ed7a00<0> 009092ac<0>
<0> 00912e10<0> 009b6594<0> 009af780<0> 00000040<0> ffffe282<0> 009af768<0> 00000001<0> 009af768<0>
<0> 00912ed4<0> 009b6594<0> ffffe282<0> 009af774<0> 009af788<0> 0000012c<0> 00000000<0> 00000040
This is the basic code for my receive function with the hardware specific code removed.
Code:

void hw_rx2(struct net_device *dev)
{
        struct sk_buff *skb;
        uint8_t *rdptr;
      ...

        /* Recieve frame header */
      ...

        if ((skb = dev_alloc_skb(rxLen+2)) == NULL)        {
                printk("Cannot allocate socket buffer\n");
                goto ERROR;
        }
        skb_reserve(skb, 2);
        rdptr = (uint8_t *) skb_put(skb, rxLen+2);
       
        /* Recieve Ethernet frame */
        while (1) { /* break based on frame length, will always be in valid range */

                for (i=0;i<4;i++)        { /* Read 8 bytes of Ethernet frame. */       

                        /* READ WORD */
                        rxWord = ...

                        count++;
                        if (count > rxLen) { /* if at end of frame */
                                        goto FCS;
                        }
                        else        {
                                memcpy(rdptr, &rxWord, 16);  /* copy 2 bytes to socket buffer */
                                rdptr += 2;        /* increment pointer by 2 bytes */
                        }
                }
                while (/* Poll status register until data ready to read */)
        }

FCS:
        /* READ FRAME CHECK SEQUENCE */
      ...

        skb->csum = FCS1 + FCS2;
        dev->stats.rx_bytes += rxLen;       

        /* pass to upper layer */
        skb->protocol = eth_type_trans(skb, dev);
        netif_rx(skb);
        dev->stats.rx_packets++;       

DONE:
        /* Write to CMD_STATUS_REG to indicate the end of the frame. */
      ...
        return;
}

Any ideas?

Cheers,
Austin.


All times are GMT -5. The time now is 09:06 PM.