On 30 okt 2011 18:13 "Simon Goldschmidt" <goldsi...@gmx.de> wrote:
> "w...@brolinembedded.se" <w...@brolinembedded.se> wrote: > > > What if I make the Rx DMA buffer descriptor ring large enough to > > hold all POOL pbufs. At start-up all POOL pbufs are allocated and > > put in the Rx DMA ring. > > pbuf_free() is modified so that whenever a POOL pbuf is freed it is > > immediately put in the Rx DMA ring. > > > > This should improve performance, as well as simplify the ethernet > > driver a bit. > > If it works for your hardware, good enough. The modification would > probably be calling your custom free function instead of memp_free > from pbuf_free. > > However, I don't think that will work with many DMA enabled MACs: the > ones I've worked with have the RX descriptors in internal memory, so > the ring can't be made larger. And because RX packets are sometimes > buffered (i.e. TCP OOS data), you will want to have many more > PBUF_POOL pbufs than fit into your DMA ring (depending on its size and > the expected throughput, of course). > > However, I guess providing a way to change memory > allocation/deallocation to use custom functions would be a good thing > to support many different types of zero copy MACs without having to > change the lwIP code for every hardware, so I guess it's well worth a > try for your target! > > Simon > I have tested this method on my hardware and it works nicely. This is my suggestion for how it can be implemented in LwIP: In pbuf.c, function pbuf_free(), change this: /* is this a pbuf from the pool? */ if (type == PBUF_POOL) { memp_free(MEMP_PBUF_POOL, p); To this: if (type == PBUF_POOL) { if( !DMA_RING_REPLENISH( p ) ) { memp_free(MEMP_PBUF_POOL, p); } In opt.h, add this: #ifndef DMA_RING_REPLENISH #define DMA_RING_REPLENISH( p ) 0 #endif In lwipopts.h, the feature can be enabled by a define like this: #define DMA_RING_REPLENISH( p ) MAC_ReplenishRx( p ) The way it works is that whenever a PBUF_POOL is deallocated, it is first offered to the Ethernet driver via the function DMA_RING_REPLENISH(). If the Ethernet driver wants the pbuf, it returns true. If however the Ethernet driver does not want the pbuf at this time (DMA ring is already full), then the pbuf is is freed normally using memp_free(). By offering the pbuf to the Ethernet driver directly, the entire memp_free(), context switch, pbuf_alloc() sequence is bypassed, saving CPU cycles. Regards, Timmy Brolin
_______________________________________________ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users