Ring buffer overflow and LAN91C111 ethernet driver - VxWorks

This is a discussion on Ring buffer overflow and LAN91C111 ethernet driver - VxWorks ; Hi Forum, Thanks for your hardwork. I am working on vxworks 5.5.1, tornado 2.2.1 and CPU SH5571. And my network driver is SMSC LAN91C111 ethernet controller. Actully i am checking my target system that how it responds when ring buffer ...

+ Reply to Thread
Results 1 to 7 of 7

Thread: Ring buffer overflow and LAN91C111 ethernet driver

  1. Ring buffer overflow and LAN91C111 ethernet driver

    Hi Forum,

    Thanks for your hardwork.

    I am working on vxworks 5.5.1, tornado 2.2.1 and CPU SH5571.
    And my network driver is SMSC LAN91C111 ethernet controller.
    Actully i am checking my target system that how it responds
    when ring buffer overflow error is occured.

    In order to generate ring buffer overflow, i reduced the size of
    the size of the ring buffer from 85 to 40. And then i pinged 60000
    bytes
    of data to my target vxworks system.

    From the above condition, i can able to generate ring buffer overflow
    error message. And below are observations of the behaviour of my
    target system,

    1. All the network task running in my target system is delayed.(FTP,
    PING...)
    2. tNettask shows PEND state(but do not suspends)
    3. ping shows request timed out.

    And in my terminal, i use to get around 85(85 only is the main
    problem) ring buffer
    overflow messege like below

    "0xd2b704c (tNetTask): panic: netJobAdd: ring buffer overflow!"


    As stated above, ring buffer overflow message generates approximatly
    around 85 times,
    and stops generating.

    In order to know why error message stopped, i checked the source code,
    and below are
    the observations,

    1. i use to get error in driver receive routine.(Because
    netClusterGet() function
    in driver receive routine returns NULL).

    2. RX_ABORT bit in RCR register is set.

    3. Recieve interrupt continues to occur which inturn calls driver
    receive routine continously.

    From the above observation, i understood that data is not coming to
    the driver,
    though receive function is called as receive interrupt generated.
    (I mean receive interrupt do not stops, but data is dropped in the
    chip level)

    Hence to confirm the above, i refferd the datasheet of SMSC driver.
    But there was no sufficent
    information regarding the flow of rejecting the receving data.

    Can anybody please tell me what exactly the process occur in hardware
    in general or specific to SMSC driver.
    (i.e data handling in hardware or DMA etc in general or specific to
    the SMSC driver)

    Or else if i am entirely wrong with my observation, if you had come
    across this situation,
    please tell me why the ring buffer overflow message stops after
    sometime.

    Thanks in Advance

  2. Re: Ring buffer overflow and LAN91C111 ethernet driver

    On Mar 25, 12:02 am, sant...@gmail.com wrote:
    > Hi Forum,
    >
    > Thanks for your hardwork.
    >
    > I am working on vxworks 5.5.1, tornado 2.2.1 and CPU SH5571.
    > And my network driver is SMSC LAN91C111 ethernet controller.


    Err.... no. Your network _controller_ is the SMSC LAN91C111. Your
    network driver is.... unknown. It could be one that Wind River ships,
    or it could be one you wrote yourself. You should tell us.

    > Actully i am checking my target system that how it responds
    > when ring buffer overflow error is occured.
    >
    > In order to generate ring buffer overflow, i reduced the size of
    > the size of the ring buffer from 85 to 40. And then i pinged 60000
    > bytes
    > of data to my target vxworks system.
    >
    > From the above condition, i can able to generate ring buffer overflow
    > error message. And below are observations of the behaviour of my
    > target system,
    >
    > 1. All the network task running in my target system is delayed.(FTP,
    > PING...)
    > 2. tNettask shows PEND state(but do not suspends)
    > 3. ping shows request timed out.
    >
    > And in my terminal, i use to get around 85(85 only is the main
    > problem) ring buffer
    > overflow messege like below
    >
    > "0xd2b704c (tNetTask): panic: netJobAdd: ring buffer overflow!"
    >
    > As stated above, ring buffer overflow message generates approximatly
    > around 85 times,
    > and stops generating.
    >
    > In order to know why error message stopped, i checked the source code,
    > and below are
    > the observations,
    >
    > 1. i use to get error in driver receive routine.(Because
    > netClusterGet() function
    > in driver receive routine returns NULL).
    >
    > 2. RX_ABORT bit in RCR register is set.
    >
    > 3. Recieve interrupt continues to occur which inturn calls driver
    > receive routine continously.
    >
    > From the above observation, i understood that data is not coming to
    > the driver,
    > though receive function is called as receive interrupt generated.
    > (I mean receive interrupt do not stops, but data is dropped in the
    > chip level)
    >
    > Hence to confirm the above, i refferd the datasheet of SMSC driver.
    > But there was no sufficent
    > information regarding the flow of rejecting the receving data.
    >
    > Can anybody please tell me what exactly the process occur in hardware
    > in general or specific to SMSC driver.
    > (i.e data handling in hardware or DMA etc in general or specific to
    > the SMSC driver)
    >
    > Or else if i am entirely wrong with my observation, if you had come
    > across this situation,
    > please tell me why the ring buffer overflow message stops after
    > sometime.
    >
    > Thanks in Advance


    A ring buffer overrun error like this usually indicates that the
    driver is not guarding its calls to netJobAdd() correctly.

    Note: the ring being overflowed here is the internal netJob ring used
    by netJobAdd() and tNetTask. It's created using rngLib. It has
    nothing to do with any DMA descriptor rings. In fact, the SMSC 91C111
    is not a DMA-based device. I think it defaults to 50 entries.

    For any given piece of work that the driver needs to do in tNetTask,
    it should only execute one instance of netJobAdd(). For example, if
    the chip receives a burst of 10 ethernet frames, you only need to do a
    netJobAdd() once, on the first RX interrupt that occurs. At that
    point, the driver should mask off the interrupt and set a flag to
    indicate that the driver's RX handler routine has been scheduled to
    run in tNetTask. Allowing subsequent interrupts to occur and calling
    netJobAdd() again and again is pointless: the RX handler should scoop
    out however many frames are waiting in the chip and only when the
    receiver has been fully drained should it turn the RX interrupt back
    on and allow the ISR to call netJobAdd() again.

    Repeatedly calling netJobAdd() too frequently is a) unnecessary,
    because it only takes one call to netJobAdd() to wake up tNetTask, and
    b) can eventually consume all of the entries in the netJob ring and
    subsequent calls to netJobAdd() to fail.

    The SMSC 91C111 chip is very simple and does not implement DMA: it's a
    programmed I/O device only. It also has a very small register space,
    and the driver must use register bank switching in some cases. If I
    remember right, it has a total of 8K of internal SRAM, which can be
    divided up among the receiver and transmitter. However, since the CPU
    must copy received frames directly out of the SRAM using 16-bit
    register accesses only, it is very easy to overrun the receiver when
    operating in 100Mbps mode: the CPU simply can't drain the RX memory
    fast enough to keep up with the incoming traffic. At 10Mbps, it seems
    to work ok though. All of this makes using the chip a little tricky.

    Anyway, a properly written driver should _never_ generate a netJob
    ring buffer overflow. If you write your driver as conservatively as as
    possible, you can get your code to use only one netJobAdd() (in the
    ISR) to dispatch a task level handler to deal with all events. At
    worst, you might have one for RX events, one for TX events and one for
    errors. In no case should you ever have more than one job outstanding
    for any given event. So for example, in the latter case, you should
    never have more than at most 3 netJobs pending. That is, you should
    never schedule a second RX netJob until you know the first one has
    completed, and never schedule a second TX netJob until the first is
    completed, and so on. If you stick to this scheme, you will never
    overflow the ring (unless you add many ethernet ports to your system,
    because then each one will need 3 netJobs -- at this point, you may
    need to make the ring larger).

    -Bill

  3. Re: Ring buffer overflow and LAN91C111 ethernet driver

    Hi Bill,

    Thanks for your kind reply.
    My network driver is the modified version of Linux SMC91111.c.
    Some of the modified things are,
    1. During each receive interrupt, my receivehandle routine is called through netjobadd. And ISR routine is as you explained above(i.e masking).
    2. End driver with mux interface support.
    3. using clusters for data transmission.

    >For example, if the chip receives a burst of 10 ethernet frames, you only >need to do a netJobAdd() once...

    When i debug my source code,
    1. On each receive interrupt my ISR calls netJobAdd through which my handlereceive routine runs at tNetTask.
    For example, when i pinged 60000 bytes data from PC to the target deivce,
    for each ping, netJobAdd function is being called around 42 times.

    And regarding my actual problem, i.e.( "netjobadd:ring buffer overflow" message stops occuring after sometime).

    Below are few observations during ringbuffer overflow error while pinging 60000 bytes(netjobadd ring buffer size is set to 40),

    1. Ring buffer overflow message occurs around 85 times.
    2. netClusterGet() function returns NULL.
    3. pClBuf->pClNext pointer becomes NULL in clusterGet function.
    4. Number of free clusters member variable "clNumFree" goes to 0.
    5. When stopped pinging, number of restored clusters i.e clNumFree shows only 43.
    i.e Actuall Number of clusters - number of ring buffer overflow messages = clNumFree
    ⇒128 - 85 = 43
    6. mbufShow, netStackSysPoolShow shows many clusters are still free.
    7. when i restart the target system, all returns to normal state.

    As per the above observations, when ring buffer overflow occurs clusters once used are not getting freed.
    In normal operation, i confirmed that clusters are getting freed continously.

    Please tell me or guide me, why the clusters are not getting freed.
    Or what are the other things, should i check to know why the clusters are not getting freed.

  4. Re: Ring buffer overflow and LAN91C111 ethernet driver

    Hi Bill,

    Thanks for your kind reply.
    My network driver is the modified version of Linux SMC91111.c.
    Some of the modified things are,
    1. During each receive interrupt, my receivehandle routine is called
    through netjobadd. And ISR routine is as you explained above(i.e
    masking).
    2. End driver with mux interface support.
    3. using clusters for data transmission.

    >For example, if the chip receives a burst of 10 ethernet frames, you only >need to do a netJobAdd() once...


    When i debug my source code,
    1. On each receive interrupt my ISR calls netJobAdd through which my
    handlereceive routine runs at tNetTask.
    For example, when i pinged 60000 bytes data from PC to the target
    deivce,
    for each ping, netJobAdd function is being called around 42 times.

    And regarding my actual problem, i.e.( "netjobadd:ring buffer
    overflow" message stops occuring after sometime).

    Below are few observations during ringbuffer overflow error while
    pinging 60000 bytes(netjobadd ring buffer size is set to 40),

    1. Ring buffer overflow message occurs around 85 times.
    2. netClusterGet() function returns NULL.
    3. pClBuf->pClNext pointer becomes NULL in clusterGet function.
    4. Number of free clusters member variable "clNumFree" goes to 0.
    5. When stopped pinging, number of restored clusters i.e clNumFree
    shows only 43.
    i.e Actuall Number of clusters - number of ring buffer overflow
    messages = clNumFree
    =>128 - 85 = 43
    6. mbufShow, netStackSysPoolShow shows many clusters are still free.
    7. when i restart the target system, all returns to normal state.

    As per the above observations, when ring buffer overflow occurs
    clusters once used are not getting freed.
    In normal operation, i confirmed that clusters are getting freed
    continously.

    Please tell me or guide me, why the clusters are not getting freed.
    Or what are the other things, should i check to know why the clusters
    are not getting freed.

  5. Re: Ring buffer overflow and LAN91C111 ethernet driver

    On Apr 1, 9:19 pm, sant...@gmail.com wrote:
    > Hi Bill,
    >
    > Thanks for your kind reply.
    > My network driver is the modified version of Linux SMC91111.c.
    > Some of the modified things are,
    > 1. During each receive interrupt, my receivehandle routine is called
    > through netjobadd. And ISR routine is as you explained above(i.e
    > masking).
    > 2. End driver with mux interface support.
    > 3. using clusters for data transmission.
    >
    > >For example, if the chip receives a burst of 10 ethernet frames, you only >need to do a netJobAdd() once...

    >
    > When i debug my source code,
    > 1. On each receive interrupt my ISR calls netJobAdd through which my
    > handlereceive routine runs at tNetTask.
    > For example, when i pinged 60000 bytes data from PC to the target
    > deivce,
    > for each ping, netJobAdd function is being called around 42 times.


    Well, that could be a problem. Remember what I said: you don't want to
    keep calling netJobAdd() when you already know tNetTask has been
    scheduled to do some work, and you should mask off the RX interrupt
    until you know the task level RX handler has completed. For the SMSC
    91C111, which requires programmed I/O, the logic would be something
    like this:

    void smscRx
    (
    SMSC_DRV_CTRL * pDrvCtrl;
    )
    {

    /* Check to see if packets are waiting in the chip's SRAM. */

    while (chipRxRamNotEmpty(pDrvCtrl) == TRUE)
    {
    /* Allocate an mBlk tuple */
    pMblk = netTupleGet (pDrvCtrl->endObj.pNetPool, ... );
    /* Find out the size of the current packet */
    pktlen = getSizeOfPkt (pDrvCtrl);
    /* Copy the frame data from the SRAM into the mBlk */
    copyPktFromChip(pDrvCtrl, pMblk->m_data, pktLen);
    /* Set up the required parts of the mBlk header */
    pMblk->m_len = pMblk->m_pkthdr.len = pktlen;
    pMblk->m_flags = M_PKTHDR|M_EXT;
    /* Give the frame to the MUX. */
    END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);
    /*
    * Tell the chip we've completed handling this packet. This
    will
    * tell the 91C111 to that the SRAM currently occupied by this
    * frame is now free to be used by subsequent frames. It
    should
    * also advance the chip's packet pointer to the next frame.
    */
    releasePktMemoryInChip (pDrvCtrl);
    }

    pDrvCtrl->rxPending = FALSE;
    reEnableRxInterrupts (pDrvCtrl);

    return;
    }

    void smscInt
    (
    SMC_DRV_CTRL * pDrvCtrl;
    )
    {

    status = readInterruptStatusRegister (pDrvCtrl);

    if (pDrvCtrl->rxPending == FALSE && status & SMSC_RX_EVENTS)
    {
    pDrvCtrl->rxPending == TRUE;
    maskOffRxInterrupts (pDrvCtrl);
    netJobAdd ((FUNCPTR *)smscRx, (int)pDrvCtrl, 0, 0, 0, 0);
    }

    return;
    }

    Note what happens here: as soon as we get an RX interrupt, we fix it
    so that a) no more RX interrupts can occur, and b) we set rxPending to
    TRUE. (In theory, just turning off the RX interrupt should suffice; we
    use the rxPending flag as an extra safety mearsure.) This should
    guarantee that we don't call netJobAdd() again until the smscRx()
    routine has finished grabbing as many frames from the RX SRAM as
    possible. This prevents you from submitting too many netJobAdd()s.

    Basically, you want to avoid the case where you call netJobAdd(), and
    then another interrupt occurs before tNetTask even gets to run,
    causing the ISR to call netJobAdd() again. It's okay if you do:

    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();
    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();
    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();
    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();
    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();
    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();
    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();

    It is _not_ ok if you end up with:

    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    ISR-> netJobAdd(smscRx(), ...);
    tNetTask -> smscRx();

    This is bad, because you could end up calling netJobAdd() too many
    times, at which point you will overflow the job ring. Once that
    happens, you will start losing events: subsequent netJobAdd() calls
    will fail, and other interrupts may go unserviced.

    > And regarding my actual problem, i.e.( "netjobadd:ring buffer
    > overflow" message stops occuring after sometime).
    >
    > Below are few observations during ringbuffer overflow error while
    > pinging 60000 bytes(netjobadd ring buffer size is set to 40),


    Remember what I said in my previous e-mail: the SMSC 91C111 only has
    8K of internal RAM. When I worked with this chip (also on an SH
    board), I found that the CPU could not drain the SRAM fast enough at
    100Mbps speeds. RX overrun errors were very common. You can recover
    from the RX errors, but you will still be dropping frames. This
    problem did not occur at 10Mbps speeds, so I rigged the driver to
    default to always negotiate a 10Mbps link.

    > 1. Ring buffer overflow message occurs around 85 times.
    > 2. netClusterGet() function returns NULL.
    > 3. pClBuf->pClNext pointer becomes NULL in clusterGet function.
    > 4. Number of free clusters member variable "clNumFree" goes to 0.
    > 5. When stopped pinging, number of restored clusters i.e clNumFree
    > shows only 43.
    > i.e Actuall Number of clusters - number of ring buffer overflow
    > messages = clNumFree
    > =>128 - 85 = 43
    > 6. mbufShow, netStackSysPoolShow shows many clusters are still free.
    > 7. when i restart the target system, all returns to normal state.


    First of all, forget about calling netMBlkGet(), netClBlkGet() and
    netClusterGet() separately. Just have your driver create a buffer pool
    and call netTupleGet(). It will construct a complete mBlk tuple for
    you. (The one benefit to this is that it makes the code a little
    simpler.)

    Second, one thing that's not clear here is just where you're
    allocating your RX buffers from. The fact that you mention
    netStackSysPoolShow() suggests to me that you're trying to allocate
    them from the TCP/IP stack's own pools. Don't do that. You can have
    your driver create its own private buffer pool with netPoolInit().
    These mBlks can be loaned to the stack and will be returned when the
    stack finishes with them.

    Third, you should probably have the driver create a pool with at least
    64 mBlk tuples. The number of mBlks available has some bearing on
    fragmentation limits: with a fragmented IP packet, the stack will hold
    onto all fragments until the whole packet is reassembled. Exactly how
    much fragmentation where will be is a function of your particular
    application. If you really expect 64K IP packets, then you should
    allocate enough buffers to handle 42 fragments (or more, if you expect
    a lot of traffic).

    Fourth, even in the case where the driver doesn't have enough buffers
    to handle extreme fragmentation, it should still recover. That is,
    even in the case where netTupleGet() in the smscRX() handler fails, or
    in the case of the chip signalling an RX overrun error (all SRAM was
    exhausted), the driver should not crash, or fall out of sync with the
    chip, or leak buffers. It is expected that you might drop a frame on
    receive occasionally. That's ok. But even so, the driver should
    continue to work.

    > As per the above observations, when ring buffer overflow occurs
    > clusters once used are not getting freed.
    > In normal operation, i confirmed that clusters are getting freed
    > continously.
    >
    > Please tell me or guide me, why the clusters are not getting freed.
    > Or what are the other things, should i check to know why the clusters
    > are not getting freed.


    My guess is that your driver is providing the TCP/IP stack with only
    some of the fragments in your 60000 byte ICMP packet, and the TCP/IP
    stack is waiting for the rest to arrive. The TCP/IP code knows there
    should be a total of 42 fragments (based on the information in the IP
    header of the first packet), so now it is waiting for all 42 fragments
    to arrive. But your driver was unable to receive all 42 fragments.
    Maybe it only handled 20 of them. The TCP/IP stack must hold onto
    those 20 buffers until the last 22 fragments arrive, or until the
    reassembly timeout expires.

    You can test this to see if my theory is correct:

    - Rerun your ping test
    - Check the number of free buffers to see if some are missing
    - At the VxWorks target shell prompt, do the following:

    -> ip_drain()

    - Check the number of free buffers again. If the buffers were being
    held in the reassembly queue,
    calling the ip_drain() function should force the stack to release
    them. (ip_drain() is the function
    called by the reassembly timer handler; basically, you are fooling
    the stack into thinking the
    timer has expired early.)

    -Bill

  6. Re: Ring buffer overflow and LAN91C111 ethernet driver

    Hi Bill,

    Thank you very much for your kind reply and detailed explaination.
    I really need it veru much..

    >Second, one thing that's not clear here is just where you're
    >allocating your RX buffers from. The fact that you mention
    >netStackSysPoolShow() suggests to me that you're trying to allocate
    >them from the TCP/IP stack's own pools. Don't do that. You can have
    >your driver create its own private buffer pool with netPoolInit().
    >These mBlks can be loaned to the stack and will be returned when the
    >stack finishes with them.


    I am creating drivers own buffer pool using netPoolInit().

    Below is the Sample of the memory initialization code.Where i am
    initializing the
    network pool with 128Mblks.

    M_CL_CONFIG smc91cMclBlkConfig = /* network mbuf configuration table
    */
    {
    /*
    no. mBlks no. clBlks memArea memSize
    ----------- ---------- ------- -------
    */
    0, 0, NULL, 0
    };

    CL_DESC smc91cClDescTbl [] = /* network cluster pool configuration
    table */
    {
    /*
    clusterSize num memArea memSize
    ----------- ---- ------- -------
    */
    {ETHERMTU + EH_SIZE + 2, 0, NULL, 0}
    };

    memoryInit(){

    smc91cClDescTbl[0].clNum = 128;
    smc91cClDescTbl[0].clSize = MEM_ROUND_UP( 2048 + pDrvCtrl-
    >offset );

    smc91cMclBlkConfig.mBlkNum = smc91cClDescTbl[0].clNum;
    smc91cMclBlkConfig.clBlkNum = smc91cClDescTbl[0].clNum;

    /* Calculate the total memory for all the M-Blks and CL-Blks. */

    /* Calculate the memory size of all the clusters. */

    /* Allocate the memory for the clusters from cache safe memory. */

    /* Initialize the memory pool. */

    if (netPoolInit(pDrvCtrl->end.pNetPool, &smc91cMclBlkConfig,
    &smc91cClDescTbl[0], smc91cClDescTblNumEnt,
    NULL) == ERROR)
    {
    return (ERROR);
    }
    }

    And my netStackDataPoolShow or mbufShow shows as below,

    -> mbufShow
    type number
    --------- ------
    FREE : 397
    DATA : 3
    HEADER : 0
    SOCKET : 0
    PCB : 0
    RTABLE : 0
    HTABLE : 0
    ATABLE : 0
    SONAME : 0
    ZOMBIE : 0
    SOOPTS : 0
    FTABLE : 0
    RIGHTS : 0
    IFADDR : 0
    CONTROL : 0
    OOBDATA : 0
    IPMOPTS : 0
    IPMADDR : 0
    IFMADDR : 0
    MRTABLE : 0
    TOTAL : 400
    number of mbufs: 400
    number of times failed to find space: 0
    number of times waited for space: 0
    number of times drained protocols for space: 0
    __________________
    CLUSTER POOL TABLE
    __________________________________________________ _____________________________
    size clusters free usage
    -------------------------------------------------------------------------------
    64 100 99 153
    128 100 99 312
    256 40 40 0
    512 40 40 0
    1024 25 25 0
    2048 25 25 0
    -------------------------------------------------------------------------------


    >Fourth, even in the case where the driver doesn't have enough buffers
    >to handle extreme fragmentation, it should still recover. That is,
    >even in the case where netTupleGet() in the smscRX() handler fails, or
    >in the case of the chip signalling an RX overrun error (all SRAM was
    >exhausted), the driver should not crash, or fall out of sync with the
    >chip, or leak buffers. It is expected that you might drop a frame on
    >receive occasionally. That's ok. But even so, the driver should
    >continue to work.


    My driver is not crashing at any stage.

    >- Rerun your ping test
    >- Check the number of free buffers to see if some are missing
    >- At the VxWorks target shell prompt, do the following:



    >-> ip_drain()



    >- Check the number of free buffers again. If the buffers were being
    >held in the reassembly queue,
    > calling the ip_drain() function should force the stack to release
    >them. (ip_drain() is the function
    > called by the reassembly timer handler; basically, you are fooling
    >the stack into thinking the
    > timer has expired early.)


    I tried by running ip_drain in shell prompt,
    It only frees my 64 size clusters but not 128 size clusters as below.
    But clNumFree i.e number of free clusters is still 0(Initial value is
    128).

    mbufShow
    type number
    --------- ------
    FREE : 227
    DATA : 87
    HEADER : 85
    SOCKET : 0
    PCB : 0
    RTABLE : 0
    HTABLE : 0
    ATABLE : 0
    SONAME : 0
    ZOMBIE : 0
    SOOPTS : 0
    FTABLE : 1
    RIGHTS : 0
    IFADDR : 0
    CONTROL : 0
    OOBDATA : 0
    IPMOPTS : 0
    IPMADDR : 0
    IFMADDR : 0
    MRTABLE : 0
    TOTAL : 400
    number of mbufs: 400
    number of times failed to find space: 0
    number of times waited for space: 0
    number of times drained protocols for space: 0
    __________________
    CLUSTER POOL TABLE
    __________________________________________________ _____________________________
    size clusters free usage
    -------------------------------------------------------------------------------
    64 100 99 698
    128 100 38 3917
    256 40 16 24
    512 40 40 0
    1024 25 25 0
    2048 25 25 0
    -------------------------------------------------------------------------------

  7. Re: Ring buffer overflow and LAN91C111 ethernet driver

    On Apr 4, 2:44 am, sant...@gmail.com wrote:
    > Hi Bill,
    >
    > Thank you very much for your kind reply and detailed explaination.
    > I really need it veru much..
    >
    > >Second, one thing that's not clear here is just where you're
    > >allocating your RX buffers from. The fact that you mention
    > >netStackSysPoolShow() suggests to me that you're trying to allocate
    > >them from the TCP/IP stack's own pools. Don't do that. You can have
    > >your driver create its own private buffer pool with netPoolInit().
    > >These mBlks can be loaned to the stack and will be returned when the
    > >stack finishes with them.

    >
    > I am creating drivers own buffer pool using netPoolInit().


    Then you should be using netPoolShow() to look at it, instead of using
    mbufShow(). All mbufShow() does is show you the TCP/IP stack's
    internal data pool. This is not your driver's pool. You should not be
    concerned with the stack's internal memory usage: you should be
    concerned with your driver's buffer usage.

    To see your driver's buffer usage, you need to do:

    netPoolShow (pDrvCtrl->end.pNetPool);

    You can have your driver print the address of its netPool when it
    starts so that you can call netPoolShow() on it from the target shell,
    or just add a debug routine to your driver to do this.

    [...]

    > >Fourth, even in the case where the driver doesn't have enough buffers
    > >to handle extreme fragmentation, it should still recover. That is,
    > >even in the case where netTupleGet() in the smscRX() handler fails, or
    > >in the case of the chip signalling an RX overrun error (all SRAM was
    > >exhausted), the driver should not crash, or fall out of sync with the
    > >chip, or leak buffers. It is expected that you might drop a frame on
    > >receive occasionally. That's ok. But even so, the driver should
    > >continue to work.

    >
    > My driver is not crashing at any stage.


    Oh yes it is: you're triggering a netJob ring overflow. Like I've been
    trying desperately to tell you, this indicates a serious bug in your
    driver.

    > >- Rerun your ping test
    > >- Check the number of free buffers to see if some are missing
    > >- At the VxWorks target shell prompt, do the following:
    > >-> ip_drain()
    > >- Check the number of free buffers again. If the buffers were being
    > >held in the reassembly queue,
    > > calling the ip_drain() function should force the stack to release
    > >them. (ip_drain() is the function
    > > called by the reassembly timer handler; basically, you are fooling
    > >the stack into thinking the
    > > timer has expired early.)

    >
    > I tried by running ip_drain in shell prompt,
    > It only frees my 64 size clusters but not 128 size clusters as below.
    > But clNumFree i.e number of free clusters is still 0(Initial value is
    > 128).


    I could not see in your output where "number of free clusters is still
    0." Again, you are looking at the wrong information: mbufShow() does
    not show you the buffer pool from your driver; it shows you the TCP/IP
    stack's internal buffer pool.

    -Bill

+ Reply to Thread