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