wiki:TBR/UserManual/Controlling_MBUF_Allocation

Version 2 (modified by taneka zenon hans, on Nov 13, 2018 at 1:17:28 PM) (diff)

For performance (sake) OR For (better) performance is grammatical

Controlling MBUF Allocation

Note: The feature discussed here is only available in RTEMS CVS, and versions after 4.6.99.3.

Sometimes it is important to be able to control where MBUF's for the network stack are located in memory, and how they are allocated.

Traditionally the BSD Stack would just malloc the buffers. This is appropriate for many systems. However, for better performance it may be more appropriate to have MBUF's located in memory that is easier and/or faster for the network driver to use. (Such as memory on a network card or simply just statically allocated).

RTEMS provides an MBUF allocation routine called:

void* rtems_bsdnet_malloc_mbuf(size_t size, int type);

this routine will allocate mbuf's by using malloc in the standard way. To change this behaviour an application simply needs to provide its own version of this routine which.

This routine has the same semantics as malloc, with the addition of the "type" parameter. "type" declares what particular network buffer is being allocated, and may be any one of the following constants (as defined in rtems_bsdnet.h):

MBUF_MALLOC_NMBCLUSTERS MBUF_MALLOC_MCLREFCNT MBUF_MALLOC_MBUF

Following is an example of this usage, to statically allocate mbuf storage:

#include <rtems/rtems_bsdnet.h>
#include <sys/mbuf.h>

/*
 * mbuf Memory allocation
 *
 * Note, nmbuf clusters are used to hold memory for packets larger than can be c ontained in
 * an a standard nmbuf, which isnt very big.
 *
 * This mbuf allocator creates static buffers. This is the only place storage can be defined,
 * sizes can not be larger than those declared here.
 */

/* 128K of storage for NMBUF Clusters */
#define DESIRED_NMBUF_CLUSTER_STORAGE_SIZE (128 * 1024)
#define TOTAL_NMBUF_CLUSTERS               (DESIRED_NMBUF_CLUSTER_STORAGE_SIZE /  MCLBYTES)
#define MAX_NMBUF_CLUSTER_STORAGE          ((TOTAL_NMBUF_CLUSTERS+1) * MCLBYTES)

/* 64K of storage for NMBUFs */
#define DESIRED_NMBUF_STORAGE_SIZE         (64 * 1024)
#define TOTAL_NMBUFS                       (DESIRED_NMBUF_STORAGE_SIZE / MSIZE)
#define MAX_NMBUF_STORAGE                  ((TOTAL_NMBUFS+1) * MSIZE)

/* Storage is allocated in multiples of the basic unit being stored, rounded up by 1 whole unit of storage */
/* This is because of how bsdnet allocates memory, and then aligns it. */

static uint8_t nmbuf_cluster_storage[MAX_NMBUF_CLUSTER_STORAGE];
static uint8_t mclrefcnt_storage[TOTAL_NMBUF_CLUSTERS];
static uint8_t nmbuf_storage[MAX_NMBUF_STORAGE];

unsigned long get_mbuf_cluster_bytecount(void)
{
  return DESIRED_NMBUF_CLUSTER_STORAGE_SIZE;
}

unsigned long get_mbuf_bytecount(void)
{
  return DESIRED_NMBUF_STORAGE_SIZE;
}

void* malloc_mbuf(size_t size, int type)
{
  void *Buffer = NULL;

  switch (type)
  {
    case MBUF_MALLOC_NMBCLUSTERS:
      if (size <= MAX_NMBUF_CLUSTER_STORAGE)
      {
        Buffer = (void*)&(nmbuf_cluster_storage[0]);
      }
    break;

    case MBUF_MALLOC_MCLREFCNT:
      if (size <= TOTAL_NMBUF_CLUSTERS)
      {
        Buffer = (void*)&(mclrefcnt_storage[0]);
      }
    break;

    case MBUF_MALLOC_MBUF:
      if (size <= MAX_NMBUF_STORAGE)
      {
        Buffer = (void*)&(nmbuf_storage[0]);
      }
    break;
  }

  return Buffer;
}

unsigned long get_mbuf_cluster_bytecount(void);
unsigned long get_mbuf_bytecount(void);

as declared in this example, can be used in network intialisation, as follows:

    rtems_bsdnet_config.mbuf_bytecount         = get_mbuf_bytecount();
    rtems_bsdnet_config.mbuf_cluster_bytecount = get_mbuf_cluster_bytecount();

    rtems_bsdnet_initialize_network();