Thanks for the detailed write-up, Will - very useful.

Are there defines for these things?
Ideally, if I want a payload size of N, I'd like to specify in syscfg.yml:

    MSYS_1_BLOCK_SIZE: '(N + MBUF_HEADER + PKT_HEADER + LL_OVERHEAD + ...)'

And magically have optimally-sized buffers.


On Wed, Jan 11, 2017 at 11:00 AM, will sanfilippo <wi...@runtime.io> wrote:

> Hello:
>
> Since this has come up on a number of different occasions I wanted to send
> out an email which discusses how the nimble stack uses mbufs. This will be
> a controller-centric discussion but the concepts apply to the host as well.
>
> A quick refresher on mbufs: Mynewt, and the nimble stack, use mbufs for
> networking stack packet data. A “packet” is simply a chain of mbufs with
> the first mbuf in the chain being a packet header mbuf and all others being
> “normal” mbufs. A packet header mbuf contains a mbuf header, a packet
> header and an optional user-defined header.
>
> The length of the packet (i.e. all the data contained in all the mbuf
> chains) is stored in the packet header. Each individual mbuf in the chain
> also contains a length which is the length of the data in that mbuf. The
> sum of all the mbuf data lengths = length of packet.
>
> The amount of overhead in an mbuf and its size determine the amount of
> data that can be carried in a mbuf. All mbufs have a 16-byte mbuf header.
> Packet header mbufs have an additional 8 bytes for the packet header
> structure and an optional user-data header. The nimble stack uses either an
> 8-byte or 12-byte user data header. If you turn on multi-advertising
> support, the user header is 12 bytes; otherwise it is 8 bytes. This means
> the total packet header mbuf overhead is 32 or 36 bytes.
>
> The total mbuf size is defined by the various MSYS_X_BLOCK_SIZE syscfg
> variables. Currently, there is one mbuf pool added to msys (MSYS_1) with a
> block size of 292 bytes.
>
> Controller constraints:
> The controller assumes that a certain minimum data size is available in a
> packet header mbuf. This size is equal to the largest advertising PDU, or
> 37 bytes, and must also contain the 2-byte LL PDU header (for a total of 39
> bytes). Additionally, the controller requires an additional 4 bytes at the
> start of the packet header mbuf to prepend the HCI ACL data packet header.
> This means that the minimum mbuf size that can be allocated in any msys
> mbuf pool is: packet header overhead + 4 + 39 = 75 (79 for multi-adv).
> Since memory pools are always rounded up to the nearest 4 byte boundary,
> this means that the minimum size should be 76 (or 80) bytes.
>
> For most applications that dont use large packets, setting the mbuf size
> to 80 should be fine as this will accommodate the typical BLE PDU and also
> meets the minimum requirement. If your application generally uses larger
> packets it might be benefical to allocate large mbufs as you dont lose the
> 16-byte overhead per mbuf.
>
> Finally, here is an example of how many mbufs will be used by the
> controller for received packets. This assumes multi-advertising enabled (36
> byte packet header overhead).
>
> Example 1: PDU length = 251, msys_1_block_size = 80
>
> Controller needs to store 251 + 2 = 253 total bytes.
>
> Packet header mbuf can hold 80 - 36 - 4 bytes, or 40 bytes.
> Each additional mbuf can hold 80 - 16 bytes, or 64 bytes.
> Total mbufs = 5. First mbuf holds 40 bytes, the next three hold 64 bytes
> while the final mbuf holds 21 bytes (40 + 64*3 + 21 = 253).
>
> Example 2: PDU length = 251, msys_1_block_size = 112
> Total mbufs: 3 (72 + 96 + 85)
>
>  Hope this helps.
>
>
>
>
>
>

Reply via email to