lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-devel] How to estimate heap memory usage (TCP case)


From: narke
Subject: Re: [lwip-devel] How to estimate heap memory usage (TCP case)
Date: Wed, 14 Mar 2012 01:13:51 +0800

On 13 March 2012 15:58, Simon Goldschmidt <address@hidden> wrote:
> narke <address@hidden> wrote:
>> > Keep in mind that to the MSS, various protocol headers plus struct pbuf
>> is also allocated from the heap. That alone would require at least
>> ~5.9KByte heap.
>>
>> Thanks for your reply Simon.  Did you get the number 5.9KB from my
>> TCP_MSS value?  How did you calculate this magic number?
>
> I wrote 'at least' because I'm not absolutely sure this is correct. However, 
> my calculation was:
>
> - TCP_MSS is 1388 and TCP_SND_BUF is 4 * TCP_MSS
> - When using full segments (every segment has 1388 bytes of TCP data in it), 
> you can thus send 4 segments
> - Every segment has TCP headers (20 bytes), IPv4 headers (20 bytes) and 
> ethernet headers (14 or 16 bytes) plus the pbuf struct (which is 16 bytes on 
> most platforms) Add memory alignment to that (e.g. 8 bytes worst case for 
> MEM_ALIGNMENT==4) and you have 80 bytes overhead per segment.
> -> 4 segments (1388 bytes + 80 bytes overhead) = 5872 bytes
>
> However, since you turned off nagle, you might end up with many small 
> segments sent out, so you have to add 80 bytes for all those small segments, 
> not for every TCP_MSS bytes.
>
>> > Without using TCP_OVERSIZE, every write gets its own pbuf, so if you
>> call tcp_write with a size != MSS, you risk losing another 72 byte for every
>> call of tcp_write that doesn't start a new segment. Added to that, the heap
>> needs its own organization structures, so you cannot allocate the full byte
>> count configured with MEM_SIZE.
>>
>> I am not quite understand the TCP_OVERSIZE.  My current setting is
>> TCP_OVERSIZE = TCP_MSS. What does it mean?
>
> That doesn't really make sense with nagle disabled. TCP_OVERSIZE assumes that 
> nagle is enabled (the default) so most segments sent out will have the size 
> of MSS. Now the old code created a pbuf for every call to tcp_write, which 
> resulted in a linked list of pbufs per segment when calling tcp_write with 
> small chunks of data. TCP_OVERSIZE instead allocates a pbuf of the configured 
> size (TCP_MSS in your case) and fills in data into that single pbuf over 
> multiple calls of tcp_write. It tracks the usage and trunkates the pbuf on 
> sending if it isn't full. That way, we avoid pbuf chains with nagle enabled.
>
> However, with nagle disabled, this results in every single segment you send 
> out taking ~1468 bytes (1388+80) off the heap (and remember with nagle 
> disabled, every call to tcp_output leads to sending everything in 
> pcb->unsent). So with nagle disabled, I'd set TCP_OVERSIZE to 0.
>
>> What's
>> the idea TCP_OVERSIZE setting to archive minimum memory use without
>> worrying about my segment get fragmented?
>
> Now I don't understand what you mean by a fragmented segment, but the best 
> way to ensure a segment only consists of one single pbuf while still not 
> wasting memory is to only call tcp_write once per segment (so that would mean 
> you have to gather all necessary data in an extra buffer before passing it to 
> lwIP).
>
>> Yes, this I understand. I will separably count my other mem_alloc() uses.
>
> Also, make sure you don't use PBUF_RAM for RX pbufs - use PBUF_POOL instead.
>


Many thanks for the answer, now I better understand what you said.
Only one question:  how to make sure I was using PBUF_POOL instead of
PBUF_RAM for rx pbufs?  And, why it makes difference?  Thanks.


-- 
Life is the only flaw in an otherwise perfect nonexistence
    -- Schopenhauer

narke
public key at http://subkeys.pgp.net:11371 (address@hidden)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]