aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-dpdk/odp_buffer_pool.c
diff options
context:
space:
mode:
authorCiprian Barbu <ciprian.barbu@linaro.org>2014-10-06 13:27:10 +0300
committerVenkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org>2014-10-09 17:23:58 +0530
commit98f556f5045a5d3cf073e75af9f31a2dbeefbcaa (patch)
treef5d374471fa3b0817072b20309c335107940deaa /platform/linux-dpdk/odp_buffer_pool.c
parent9e73493250d59cb3c650acf4d458d3b9d6eb40b7 (diff)
linux-dpdk: Rework buffer management
Signed-off-by: Ciprian Barbu <ciprian.barbu@linaro.org> Reviewed-by: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> Signed-off-by: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org>
Diffstat (limited to 'platform/linux-dpdk/odp_buffer_pool.c')
-rw-r--r--platform/linux-dpdk/odp_buffer_pool.c151
1 files changed, 139 insertions, 12 deletions
diff --git a/platform/linux-dpdk/odp_buffer_pool.c b/platform/linux-dpdk/odp_buffer_pool.c
index 7f28f9d47..8325b9e7d 100644
--- a/platform/linux-dpdk/odp_buffer_pool.c
+++ b/platform/linux-dpdk/odp_buffer_pool.c
@@ -9,6 +9,7 @@
#include <odp_buffer_pool_internal.h>
#include <odp_buffer_internal.h>
#include <odp_packet_internal.h>
+#include <odp_timer_internal.h>
#include <odp_shared_memory.h>
#include <odp_align.h>
#include <odp_internal.h>
@@ -44,6 +45,13 @@
#define NULL_INDEX ((uint32_t)-1)
+union buffer_type_any_u {
+ odp_buffer_hdr_t buf;
+ odp_packet_hdr_t pkt;
+ odp_timeout_hdr_t tmo;
+};
+
+typedef union buffer_type_any_u odp_any_buffer_hdr_t;
typedef union pool_entry_u {
struct pool_entry_s s;
@@ -59,7 +67,7 @@ typedef struct pool_table_t {
} pool_table_t;
-/* The pool table */
+/* The pool table ptr - resides in shared memory */
static pool_table_t *pool_tbl;
/* Pool entry pointers (for inlining) */
@@ -101,31 +109,150 @@ int odp_buffer_pool_init_global(void)
return 0;
}
+struct mbuf_ctor_arg {
+ uint16_t seg_buf_offset; /* To skip the ODP buf/pkt/tmo header */
+ uint16_t seg_buf_size; /* total sz: offset + user sz + HDROOM */
+ int buf_type;
+};
+
+struct mbuf_pool_ctor_arg {
+ uint16_t seg_buf_size; /* size of mbuf: user specified sz + HDROOM */
+};
+
+static void
+odp_dpdk_mbuf_pool_ctor(struct rte_mempool *mp,
+ void *opaque_arg)
+{
+ struct mbuf_pool_ctor_arg *mbp_ctor_arg;
+ struct rte_pktmbuf_pool_private *mbp_priv;
+
+ if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
+ ODP_ERR("%s(%s) private_data_size %d < %d",
+ __func__, mp->name, (int) mp->private_data_size,
+ (int) sizeof(struct rte_pktmbuf_pool_private));
+ return;
+ }
+ mbp_ctor_arg = (struct mbuf_pool_ctor_arg *)opaque_arg;
+ mbp_priv = rte_mempool_get_priv(mp);
+ mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
+}
+
+/* ODP DPDK mbuf constructor.
+ * This is a combination of rte_pktmbuf_init in rte_mbuf.c
+ * and testpmd_mbuf_ctor in testpmd.c
+ */
+static void
+odp_dpdk_mbuf_ctor(struct rte_mempool *mp,
+ void *opaque_arg,
+ void *raw_mbuf,
+ unsigned i)
+{
+ struct mbuf_ctor_arg *mb_ctor_arg;
+ struct rte_mbuf *mb = raw_mbuf;
+ struct odp_buffer_hdr_t *buf_hdr;
+
+ /* The rte_mbuf is at the begninning in all cases */
+ mb_ctor_arg = (struct mbuf_ctor_arg *)opaque_arg;
+ mb = (struct rte_mbuf *)raw_mbuf;
+
+ RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
+
+ memset(mb, 0, mp->elt_size);
+
+ /* Start of buffer is just after the ODP type specific header
+ * which contains in the very beginning the rte_mbuf struct */
+ mb->buf_addr = (char *)mb + mb_ctor_arg->seg_buf_offset;
+ mb->buf_physaddr = rte_mempool_virt2phy(mp, mb) +
+ mb_ctor_arg->seg_buf_offset;
+ mb->buf_len = mb_ctor_arg->seg_buf_size;
+
+ /* keep some headroom between start of buffer and data */
+ if (mb_ctor_arg->buf_type == ODP_BUFFER_TYPE_PACKET ||
+ mb_ctor_arg->buf_type == ODP_BUFFER_TYPE_ANY)
+ mb->pkt.data = (char *)mb->buf_addr + RTE_PKTMBUF_HEADROOM;
+ else
+ mb->pkt.data = mb->buf_addr;
+
+ /* init some constant fields */
+ mb->type = RTE_MBUF_PKT;
+ mb->pool = mp;
+ mb->pkt.nb_segs = 1;
+ mb->pkt.in_port = 0xff;
+ mb->ol_flags = 0;
+ mb->pkt.vlan_macip.data = 0;
+ mb->pkt.hash.rss = 0;
+
+ /* Save index, might be useful for debugging purposes */
+ buf_hdr = (struct odp_buffer_hdr_t *)raw_mbuf;
+ buf_hdr->index = i;
+}
odp_buffer_pool_t odp_buffer_pool_create(const char *name,
void *base_addr, uint64_t size,
size_t buf_size, size_t buf_align,
int buf_type)
{
- struct rte_mempool *pktmbuf_pool = NULL;
+ struct rte_mempool *pool = NULL;
+ struct mbuf_pool_ctor_arg mbp_ctor_arg;
+ struct mbuf_ctor_arg mb_ctor_arg;
+ unsigned mb_size;
+ size_t hdr_size;
+
+ /* Not used for rte_mempool; the new ODP buffer management introduces
+ * rte_mempool_create_from_region where base_addr makes sense */
+ (void)base_addr;
+
+ /* buf_align will be removed soon, no need to wory about it */
+ (void)buf_align;
+
ODP_DBG("odp_buffer_pool_create: %s, %lx, %u, %u, %u, %d\n", name,
(uint64_t) base_addr, (unsigned) size,
(unsigned) buf_size, (unsigned) buf_align,
buf_type);
- pktmbuf_pool =
- rte_mempool_create(name, NB_MBUF,
- MBUF_SIZE, MAX_PKT_BURST,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- rte_socket_id(), 0);
- if (pktmbuf_pool == NULL) {
+ switch (buf_type) {
+ case ODP_BUFFER_TYPE_RAW:
+ hdr_size = sizeof(odp_buffer_hdr_t);
+ mbp_ctor_arg.seg_buf_size = (uint16_t) buf_size;
+ break;
+ case ODP_BUFFER_TYPE_PACKET:
+ hdr_size = sizeof(odp_packet_hdr_t);
+ mbp_ctor_arg.seg_buf_size =
+ (uint16_t) (RTE_PKTMBUF_HEADROOM + buf_size);
+ break;
+ case ODP_BUFFER_TYPE_TIMEOUT:
+ hdr_size = sizeof(odp_timeout_hdr_t);
+ mbp_ctor_arg.seg_buf_size = (uint16_t) buf_size;
+ break;
+ case ODP_BUFFER_TYPE_ANY:
+ hdr_size = sizeof(odp_any_buffer_hdr_t);
+ mbp_ctor_arg.seg_buf_size =
+ (uint16_t) (RTE_PKTMBUF_HEADROOM + buf_size);
+ break;
+ default:
+ ODP_ERR("odp_buffer_pool_create: Bad type %i\n", buf_type);
+ return ODP_BUFFER_POOL_INVALID;
+ break;
+ }
+
+ mb_ctor_arg.seg_buf_offset =
+ (uint16_t) ODP_CACHE_LINE_SIZE_ROUNDUP(hdr_size);
+ mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
+ mb_ctor_arg.buf_type = buf_type;
+ mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
+
+ pool = rte_mempool_create(name, NB_MBUF,
+ mb_size, MAX_PKT_BURST,
+ sizeof(struct rte_pktmbuf_pool_private),
+ odp_dpdk_mbuf_pool_ctor, &mbp_ctor_arg,
+ odp_dpdk_mbuf_ctor, &mb_ctor_arg,
+ rte_socket_id(), 0);
+ if (pool == NULL) {
ODP_ERR("Cannot init DPDK mbuf pool\n");
- return -1;
+ return ODP_BUFFER_POOL_INVALID;
}
- return (odp_buffer_pool_t) pktmbuf_pool;
+ return (odp_buffer_pool_t) pool;
}