That is a good question. I should let Chris answer this one as he knows for 
sure. I suspect you will have a chain of mbufs but I would have to look over 
the code to be sure.


> On Jan 19, 2017, at 3:46 AM, Simon Ratner <si...@proxy.co> wrote:
> 
> Hi Will,
> 
> A related question: how does this map to large ATT_MTU and fragmented
> packets at the L2CAP level (assuming no data length extension)? Does each
> fragment get its own mbuf, which are then chained together, or does the
> entire packet get reassembled into a single mbuf if there is room?
> 
> 
> 
> On Wed, Jan 11, 2017 at 4:57 PM, will sanfilippo <wi...@runtime.io> wrote:
> 
>> Yes; 76 or 80. Note that I have not actually tested with 80 byte mbuf
>> blocks. That is the theory though :-)
>> 
>>> On Jan 11, 2017, at 4:31 PM, Simon Ratner <si...@proxy.co> wrote:
>>> 
>>> Got it; by minimum size you mean the 76/80 bytes?
>>> 
>>> On Wed, Jan 11, 2017 at 4:17 PM, will sanfilippo <wi...@runtime.io>
>> wrote:
>>> 
>>>> Well, yes, there are “definitions” for these things. They are in various
>>>> places but they are there. Using them might get a bit tricky as you have
>>>> mentioned; not sure. You would have to make sure the right header files
>> get
>>>> included in the proper places...
>>>> 
>>>> Anyway, here are the definitions:
>>>> os mbuf header: sizeof(struct os_mbuf). Size = 16
>>>> os mbuf packet header: sizeof(struct os_mbuf_pkthdr) Size = 8
>>>> user header: sizeof(struct ble_mbuf_hdr) Size = 8 or 12
>>>> The HCI ACL data header: BLE_HCI_DATA_HSDR_SZ. 4 bytes
>>>> The LL PDU header: BLE_LL_PDU_HDR_LEN. 2 bytes
>>>> 
>>>> I would always make the size a multiple of 4 but the code should do that
>>>> for you; I just like to do it so the size you see in the syscfg
>> variable is
>>>> the actual memory block size.
>>>> 
>>>> Another thing I should mention: you should never add a buffer pool to
>> msys
>>>> smaller than the minimum size I mentioned if you are using the
>> controller.
>>>> This is something we will address in the future but for now it would be
>>>> bad. :-)
>>>> 
>>>> 
>>>> 
>>>>> On Jan 11, 2017, at 3:49 PM, Simon Ratner <si...@proxy.co> wrote:
>>>>> 
>>>>> 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