mbuf: enforce alignment of private area
authorOlivier Matz <olivier.matz@6wind.com>
Thu, 30 Jul 2015 16:22:17 +0000 (18:22 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Sun, 2 Aug 2015 22:38:26 +0000 (00:38 +0200)
It looks better to have a data buffer address that is aligned to
8 bytes. This is the case when there is no mbuf private area, but
if there is one, the alignment depends on the size of this area
that is located between the mbuf structure and the data buffer.

Indeed, some drivers expects to have the buffer address aligned
to an even address, and moreover an unaligned buffer may impact
the performance when accessing to network headers.

Add a check in rte_pktmbuf_pool_create() to verify the alignment
constraint before creating the mempool. For applications that use
the alternative way (direct call to rte_mempool_create), also
add an assertion in rte_pktmbuf_init().

By the way, also add the MBUF log type.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
lib/librte_eal/common/include/rte_log.h
lib/librte_mbuf/rte_mbuf.c
lib/librte_mbuf/rte_mbuf.h

index 24a55cc..ede0dca 100644 (file)
@@ -77,6 +77,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_PORT    0x00002000 /**< Log related to port. */
 #define RTE_LOGTYPE_TABLE   0x00004000 /**< Log related to table. */
 #define RTE_LOGTYPE_PIPELINE 0x00008000 /**< Log related to pipeline. */
+#define RTE_LOGTYPE_MBUF    0x00010000 /**< Log related to mbuf. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1   0x01000000 /**< User-defined log type 1. */
index 4320dd4..e416312 100644 (file)
@@ -58,6 +58,7 @@
 #include <rte_mbuf.h>
 #include <rte_string_fns.h>
 #include <rte_hexdump.h>
+#include <rte_errno.h>
 
 /*
  * ctrlmbuf constructor, given as a callback function to
@@ -125,6 +126,7 @@ rte_pktmbuf_init(struct rte_mempool *mp,
        mbuf_size = sizeof(struct rte_mbuf) + priv_size;
        buf_len = rte_pktmbuf_data_room_size(mp);
 
+       RTE_MBUF_ASSERT(RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) == priv_size);
        RTE_MBUF_ASSERT(mp->elt_size >= mbuf_size);
        RTE_MBUF_ASSERT(buf_len <= UINT16_MAX);
 
@@ -154,7 +156,12 @@ rte_pktmbuf_pool_create(const char *name, unsigned n,
        struct rte_pktmbuf_pool_private mbp_priv;
        unsigned elt_size;
 
-
+       if (RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) != priv_size) {
+               RTE_LOG(ERR, MBUF, "mbuf priv_size=%u is not aligned\n",
+                       priv_size);
+               rte_errno = EINVAL;
+               return NULL;
+       }
        elt_size = sizeof(struct rte_mbuf) + (unsigned)priv_size +
                (unsigned)data_room_size;
        mbp_priv.mbuf_data_room_size = data_room_size;
index 010b32d..c3b8c98 100644 (file)
@@ -698,6 +698,9 @@ extern "C" {
                                                  RTE_PTYPE_INNER_L4_MASK))
 #endif /* RTE_NEXT_ABI */
 
+/** Alignment constraint of mbuf private area. */
+#define RTE_MBUF_PRIV_ALIGN 8
+
 /**
  * Get the name of a RX offload flag
  *
@@ -1238,7 +1241,7 @@ void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
  *   details.
  * @param priv_size
  *   Size of application private are between the rte_mbuf structure
- *   and the data buffer.
+ *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
  * @param data_room_size
  *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
  * @param socket_id
@@ -1250,7 +1253,7 @@ void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
  *   with rte_errno set appropriately. Possible rte_errno values include:
  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
  *    - E_RTE_SECONDARY - function was called from a secondary process instance
- *    - EINVAL - cache size provided is too large
+ *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
  *    - ENOSPC - the maximum number of memzones has already been allocated
  *    - EEXIST - a memzone with the same name already exists
  *    - ENOMEM - no appropriate memory area found in which to create memzone