From a386a3e124d09cf672cc43178018b96a52bc069b Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 30 Jul 2015 18:22:17 +0200 Subject: [PATCH] mbuf: enforce alignment of private area 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 Acked-by: Helin Zhang Acked-by: Konstantin Ananyev --- lib/librte_eal/common/include/rte_log.h | 1 + lib/librte_mbuf/rte_mbuf.c | 9 ++++++++- lib/librte_mbuf/rte_mbuf.h | 7 +++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h index 24a55cccff..ede0dca8e6 100644 --- a/lib/librte_eal/common/include/rte_log.h +++ b/lib/librte_eal/common/include/rte_log.h @@ -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. */ diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c index 4320dd46a3..e4163121d0 100644 --- a/lib/librte_mbuf/rte_mbuf.c +++ b/lib/librte_mbuf/rte_mbuf.c @@ -58,6 +58,7 @@ #include #include #include +#include /* * 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; diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 010b32de28..c3b8c98913 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -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 -- 2.20.1