Message ID | 1405103725-15147-1-git-send-email-venkatesh.vivekanandan@linaro.org |
---|---|
State | New |
Headers | show |
On 2014-07-12 00:05, venkatesh.vivekanandan@linaro.org wrote: > From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> > > - Made ODP_BUFFER_<TYPES> consistent with linux-generic. > - Removed odp_buffer_is_scatter API to be inline with linux-generic. > - Added platform/linux-dpdk/odp_linux.c to supply the function > and argument to the pthread created by dpdk. > > To compile: > ---------- > - Edit configure.ac and modify with_platform=linux-dpdk why edit? ./bootstrap ./configure --with-platform=linux-dpdk make that should work... Cheers, Anders > * ./bootstrap > * ./configure > * make clean > * make > > Commands to test: > ---------------- > l2fwding app - ./test/l2fwd/odp_l2fwd -i 0,1 -t 5 -m 0 -c 2 > loopback app - ./test/packet/odp_pktio -i 0,1 -t 5 -m 0 -c 2 > > -i 0,1 - is the interface number > -t 5 - is the dpdk type > -m 0 - is the burst mode > -c 2 - is the number of cpus > > Signed-off-by: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> > --- > configure.ac | 2 + > platform/linux-dpdk/Makefile | 158 -------- > platform/linux-dpdk/Makefile.am | 100 +++++ > platform/linux-dpdk/Makefile.inc | 7 - > platform/linux-dpdk/include/api/odp_buffer.h | 17 +- > platform/linux-dpdk/odp_buffer.c | 91 +++++ > platform/linux-dpdk/odp_buffer_pool.c | 156 ++++++++ > platform/linux-dpdk/odp_init.c | 113 ++++++ > platform/linux-dpdk/odp_linux.c | 96 +++++ > platform/linux-dpdk/odp_packet.c | 374 ++++++++++++++++++ > platform/linux-dpdk/odp_packet_dpdk.c | 189 +++++++++ > platform/linux-dpdk/odp_packet_io.c | 561 +++++++++++++++++++++++++++ > platform/linux-dpdk/odp_queue.c | 435 +++++++++++++++++++++ > platform/linux-dpdk/source/odp_buffer.c | 102 ----- > platform/linux-dpdk/source/odp_buffer_pool.c | 156 -------- > platform/linux-dpdk/source/odp_init.c | 113 ------ > platform/linux-dpdk/source/odp_packet.c | 374 ------------------ > platform/linux-dpdk/source/odp_packet_dpdk.c | 177 --------- > platform/linux-dpdk/source/odp_packet_io.c | 561 --------------------------- > platform/linux-dpdk/source/odp_queue.c | 435 --------------------- > 20 files changed, 2122 insertions(+), 2095 deletions(-) > delete mode 100644 platform/linux-dpdk/Makefile > create mode 100644 platform/linux-dpdk/Makefile.am > delete mode 100644 platform/linux-dpdk/Makefile.inc > create mode 100644 platform/linux-dpdk/odp_buffer.c > create mode 100644 platform/linux-dpdk/odp_buffer_pool.c > create mode 100644 platform/linux-dpdk/odp_init.c > create mode 100644 platform/linux-dpdk/odp_linux.c > create mode 100644 platform/linux-dpdk/odp_packet.c > create mode 100644 platform/linux-dpdk/odp_packet_dpdk.c > create mode 100644 platform/linux-dpdk/odp_packet_io.c > create mode 100644 platform/linux-dpdk/odp_queue.c > delete mode 100644 platform/linux-dpdk/source/odp_buffer.c > delete mode 100644 platform/linux-dpdk/source/odp_buffer_pool.c > delete mode 100644 platform/linux-dpdk/source/odp_init.c > delete mode 100644 platform/linux-dpdk/source/odp_packet.c > delete mode 100644 platform/linux-dpdk/source/odp_packet_dpdk.c > delete mode 100644 platform/linux-dpdk/source/odp_packet_io.c > delete mode 100644 platform/linux-dpdk/source/odp_queue.c > > diff --git a/configure.ac b/configure.ac > index 873ea9e..3d8481f 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -51,6 +51,7 @@ AC_ARG_WITH([platform], > > AM_CONDITIONAL([ODP_PLATFORM_GENERIC], [test "x$with_platform" = xlinux-generic]) > AM_CONDITIONAL([ODP_PLATFORM_KEYSTONE2], [test "x$with_platform" = xlinux-keystone2]) > +AM_CONDITIONAL([ODP_PLATFORM_DPDK], [test "x$with_platform" = xlinux-dpdk]) > > AC_SUBST([with_platform]) > > @@ -111,6 +112,7 @@ AC_CONFIG_FILES([Makefile > platform/Makefile > platform/linux-generic/Makefile > platform/linux-keystone2/Makefile > + platform/linux-dpdk/Makefile > test/Makefile > test/api_test/Makefile > test/example/Makefile > diff --git a/platform/linux-dpdk/Makefile b/platform/linux-dpdk/Makefile > deleted file mode 100644 > index bf8d0b3..0000000 > --- a/platform/linux-dpdk/Makefile > +++ /dev/null > @@ -1,158 +0,0 @@ > -## Copyright (c) 2013, Linaro Limited > -## All rights reserved. > -## > -## Redistribution and use in source and binary forms, with or without > -## modification, are permitted provided that the following conditions are met: > -## > -## * Redistributions of source code must retain the above copyright notice, this > -## list of conditions and the following disclaimer. > -## > -## * Redistributions in binary form must reproduce the above copyright notice, this > -## list of conditions and the following disclaimer in the documentation and/or > -## other materials provided with the distribution. > -## > -## * Neither the name of Linaro Limited nor the names of its contributors may be > -## used to endorse or promote products derived from this software without specific > -## prior written permission. > -## > -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND > -## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > -## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > -## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE > -## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > -## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR > -## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER > -## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > -## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE > -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > - > -.DEFAULT_GOAL := libs > - > -ODP_ROOT = ../.. > -LIB_DIR = ./lib > -DOC_DIR = ./doc > - > -LINUX_GENERIC_DIR = ../linux-generic > - > -RTE_SDK ?= $(abspath $(ODP_ROOT)/../dpdk) > -RTE_OUTPUT ?= $(abspath $(RTE_SDK)/build) > -RTE_LIB ?= $(abspath $(RTE_OUTPUT)/lib/libintel_dpdk.a) > - > -PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h > -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include > -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch > -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env > -PLAT_CFLAGS += -msse4.2 > - > -EXTRA_CFLAGS += $(PLAT_CFLAGS) > -EXTRA_CFLAGS += -I./include > -EXTRA_CFLAGS += -I./include/api > -EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include > -EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include/api > -EXTRA_CFLAGS += -I$(ODP_ROOT)/include > - > -include $(ODP_ROOT)/Makefile.inc > -STATIC_LIB = ./lib/libodp.a > - > -# > -# Object files > -# > -OBJS = > -OBJS += $(OBJ_DIR)/odp_barrier.o > -OBJS += $(OBJ_DIR)/odp_buffer.o > -OBJS += $(OBJ_DIR)/odp_buffer_pool.o > -OBJS += $(OBJ_DIR)/odp_coremask.o > -OBJS += $(OBJ_DIR)/odp_init.o > -OBJS += $(OBJ_DIR)/odp_linux.o > -OBJS += $(OBJ_DIR)/odp_packet.o > -OBJS += $(OBJ_DIR)/odp_packet_flags.o > -OBJS += $(OBJ_DIR)/odp_packet_io.o > -OBJS += $(OBJ_DIR)/odp_packet_socket.o > -OBJS += $(OBJ_DIR)/odp_queue.o > -OBJS += $(OBJ_DIR)/odp_schedule.o > -OBJS += $(OBJ_DIR)/odp_shared_memory.o > -OBJS += $(OBJ_DIR)/odp_spinlock.o > -OBJS += $(OBJ_DIR)/odp_system_info.o > -OBJS += $(OBJ_DIR)/odp_thread.o > -OBJS += $(OBJ_DIR)/odp_ticketlock.o > -OBJS += $(OBJ_DIR)/odp_time.o > -OBJS += $(OBJ_DIR)/odp_timer.o > -OBJS += $(OBJ_DIR)/odp_ring.o > -OBJS += $(OBJ_DIR)/odp_rwlock.o > -OBJS += $(OBJ_DIR)/odp_packet_dpdk.o > - > -DEPS = $(OBJS:.o=.d) > - > -.PHONY: all > -all: libs docs > - > --include $(DEPS) > - > -#$(OBJ_DIR): > -# $(MKDIR) $(OBJ_DIR) > - > -$(LIB_DIR): > - $(MKDIR) $(LIB_DIR) > - > -$(DOC_DIR): > - $(MKDIR) $(DOC_DIR)/html > - $(MKDIR) $(DOC_DIR)/latex > - > -# > -# Compile rules > -# > -vpath %.c source:$(LINUX_GENERIC_DIR)/source > - > -$(OBJ_DIR)/%.o: %.c > - $(ECHO) " CC $<" > - $(CC) -c -MD $(EXTRA_CFLAGS) $(CFLAGS) -o $@ $< > - > -# > -# Lib rule > -# > -$(OBJ_DIR)/libodp.o: $(OBJS) > - $(ECHO) " LD $@" > - $(LD) -r -o $@ $(OBJS) $(RTE_LIB) > - > -$(STATIC_LIB): $(OBJ_DIR)/libodp.o > - $(ECHO) " AR $@" > - $(AR) -cr $@ $(OBJ_DIR)/libodp.o > - > - > -clean: > - $(RMDIR) $(OBJ_DIR) > - $(RMDIR) $(LIB_DIR) > - $(RMDIR) $(DOC_DIR) > - $(RM) Doxyfile > - > -Doxyfile: Doxyfile.in > - doxygen -u - < $< > $@ > - > -.PHONY: docs > -docs: $(DOC_DIR) Doxyfile ./include/odp*.h > - doxygen > - > -.PHONY: docs_install > -docs_install: docs > - $(COPY) doc $(DESTDIR) > - > -.PHONY: pdf > -pdf: docs > - make --directory doc/latex refman.pdf 1> /dev/null > - > -.PHONY: libs > -libs: $(OBJ_DIR) $(LIB_DIR) $(STATIC_LIB) > - > -.PHONY: lib_install > -lib_install: libs > - install -d $(DESTDIR)/lib > - install -m 0644 ${STATIC_LIB} $(DESTDIR)/lib/ > - > -.PHONY: headers_install > -headers_install: libs > - $(ECHO) Installing headers to $(DESTDIR)/include > - $(COPY) $(ODP_ROOT)/include $(DESTDIR) > - $(COPY) $(LINUX_GENERIC_DIR)/include/api/* $(DESTDIR)/include/ > - $(COPY) include/api/* $(DESTDIR)/include/ > - > -install: lib_install headers_install > diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am > new file mode 100644 > index 0000000..067c0bb > --- /dev/null > +++ b/platform/linux-dpdk/Makefile.am > @@ -0,0 +1,100 @@ > +include $(top_srcdir)/Makefile.inc > +LIB = $(top_builddir)/lib > + > +dist_pkgdata_DATA = $(LIB)/libodp.la > + > +pkgconfigdir = pkgconfig > +nodist_pkgconfig_DATA = $(top_builddir)/pkgconfig/libodp.pc > + > +.PHONY: pkgconfig/libodp.pc > + > +RTE_SDK ?= $(top_srcdir)/../dpdk > +RTE_OUTPUT ?= $(RTE_SDK)/build > +RTE_LIB ?= $(RTE_OUTPUT)/lib > + > +PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h > +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include > +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch > +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env > +PLAT_CFLAGS += -msse4.2 > + > +AM_CFLAGS += $(PLAT_CFLAGS) > +AM_CFLAGS += -I$(srcdir)/include > +AM_CFLAGS += -I$(srcdir)/include/api > +AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include > +AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include/api > +AM_CFLAGS += -I$(top_srcdir)/include > + > +AM_LDFLAGS += -L$(RTE_LIB) > +VPATH = $(srcdir) $(builddir) > +if ODP_PLATFORM_DPDK > +lib_LTLIBRARIES = $(LIB)/libodp.la > +DPDK_LIBS="-lintel_dpdk -ldl" > +LIBS += $(DPDK_LIBS) > + > +include_HEADERS = \ > + $(top_srcdir)/platform/linux-dpdk/include/api/odp_buffer.h \ > + $(top_srcdir)/include/odp.h \ > + $(top_srcdir)/include/odp_align.h \ > + $(top_srcdir)/include/odp_atomic.h \ > + $(top_srcdir)/include/odp_barrier.h \ > + $(top_srcdir)/include/odp_buffer_pool.h \ > + $(top_srcdir)/include/odp_byteorder.h \ > + $(top_srcdir)/include/odp_compiler.h \ > + $(top_srcdir)/include/odp_config.h \ > + $(top_srcdir)/include/odp_coremask.h \ > + $(top_srcdir)/include/odp_debug.h \ > + $(top_srcdir)/include/odp_hints.h \ > + $(top_srcdir)/include/odp_init.h \ > + $(top_srcdir)/include/odp_packet_flags.h \ > + $(top_srcdir)/include/odp_packet.h \ > + $(top_srcdir)/include/odp_packet_io.h \ > + $(top_srcdir)/include/odp_queue.h \ > + $(top_srcdir)/include/odp_rwlock.h \ > + $(top_srcdir)/include/odp_schedule.h \ > + $(top_srcdir)/include/odp_shared_memory.h \ > + $(top_srcdir)/include/odp_spinlock.h \ > + $(top_srcdir)/include/odp_std_types.h \ > + $(top_srcdir)/include/odp_sync.h \ > + $(top_srcdir)/include/odp_system_info.h \ > + $(top_srcdir)/include/odp_thread.h \ > + $(top_srcdir)/include/odp_ticketlock.h \ > + $(top_srcdir)/include/odp_time.h \ > + $(top_srcdir)/include/odp_timer.h \ > + $(top_srcdir)/include/odp_version.h > + > +subdirheadersdir = $(includedir)/helper > +subdirheaders_HEADERS = \ > + $(top_srcdir)/include/helper/odp_chksum.h \ > + $(top_srcdir)/include/helper/odp_eth.h \ > + $(top_srcdir)/include/helper/odp_ip.h \ > + $(top_srcdir)/include/helper/odp_linux.h \ > + $(top_srcdir)/include/helper/odp_packet_helper.h \ > + $(top_srcdir)/include/helper/odp_ring.h \ > + $(top_srcdir)/include/helper/odp_udp.h > + > +__LIB__libodp_la_SOURCES = \ > + ../linux-generic/odp_barrier.c \ > + odp_buffer.c \ > + odp_buffer_pool.c \ > + ../linux-generic/odp_coremask.c \ > + odp_init.c \ > + odp_linux.c \ > + odp_packet.c \ > + odp_packet_dpdk.c \ > + ../linux-generic/odp_packet_flags.c \ > + odp_packet_io.c \ > + ../linux-generic/odp_packet_socket.c \ > + odp_queue.c \ > + ../linux-generic/odp_ring.c \ > + ../linux-generic/odp_rwlock.c \ > + ../linux-generic/odp_schedule.c \ > + ../linux-generic/odp_shared_memory.c \ > + ../linux-generic/odp_spinlock.c \ > + ../linux-generic/odp_system_info.c \ > + ../linux-generic/odp_thread.c \ > + ../linux-generic/odp_ticketlock.c \ > + ../linux-generic/odp_time.c \ > + ../linux-generic/odp_timer.c > + > +endif > diff --git a/platform/linux-dpdk/Makefile.inc b/platform/linux-dpdk/Makefile.inc > deleted file mode 100644 > index fe7679b..0000000 > --- a/platform/linux-dpdk/Makefile.inc > +++ /dev/null > @@ -1,7 +0,0 @@ > -# Copyright (c) 2013, Linaro Limited > -# All rights reserved. > -# > -# SPDX-License-Identifier: BSD-3-Clause > - > -STD_LIBS += -ldl > - > diff --git a/platform/linux-dpdk/include/api/odp_buffer.h b/platform/linux-dpdk/include/api/odp_buffer.h > index 286d9e6..9ea1ed8 100644 > --- a/platform/linux-dpdk/include/api/odp_buffer.h > +++ b/platform/linux-dpdk/include/api/odp_buffer.h > @@ -63,18 +63,11 @@ size_t odp_buffer_size(odp_buffer_t buf); > int odp_buffer_type(odp_buffer_t buf); > > #define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */ > -#define ODP_BUFFER_TYPE_RAW 0 /**< Raw buffer */ > -#define ODP_BUFFER_TYPE_PACKET 1 /**< Packet buffer */ > -#define ODP_BUFFER_TYPE_TIMER 2 /**< Timer buffer */ > - > -/** > - * Tests if buffer is part of a scatter/gather list > - * > - * @param buf Buffer handle > - * > - * @return 1 if belongs to a scatter list, otherwise 0 > - */ > -int odp_buffer_is_scatter(odp_buffer_t buf); > +#define ODP_BUFFER_TYPE_ANY 0 /**< Buffer that can hold any other > + buffer type */ > +#define ODP_BUFFER_TYPE_RAW 1 /**< Raw buffer, no additional metadata */ > +#define ODP_BUFFER_TYPE_PACKET 2 /**< Packet buffer */ > +#define ODP_BUFFER_TYPE_TIMEOUT 3 /**< Timeout buffer */ > > /** > * Tests if buffer is valid > diff --git a/platform/linux-dpdk/odp_buffer.c b/platform/linux-dpdk/odp_buffer.c > new file mode 100644 > index 0000000..133658f > --- /dev/null > +++ b/platform/linux-dpdk/odp_buffer.c > @@ -0,0 +1,91 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_buffer.h> > +#include <odp_buffer_internal.h> > +#include <odp_buffer_pool_internal.h> > + > +#include <string.h> > +#include <stdio.h> > + > + > +void *odp_buffer_addr(odp_buffer_t buf) > +{ > + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > + > + return hdr->buf_addr; > +} > + > + > +size_t odp_buffer_size(odp_buffer_t buf) > +{ > + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > + > + return hdr->buf_len; > +} > + > + > +int odp_buffer_type(odp_buffer_t buf) > +{ > + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > + > + return hdr->type; > +} > + > + > +int odp_buffer_is_valid(odp_buffer_t buf) > +{ > + odp_buffer_bits_t handle; > + > + handle.u32 = buf; > + > + return (handle.index != ODP_BUFFER_INVALID_INDEX); > +} > + > + > +int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) > +{ > + odp_buffer_hdr_t *hdr; > + int len = 0; > + > + if (!odp_buffer_is_valid(buf)) { > + printf("Buffer is not valid.\n"); > + return len; > + } > + > + hdr = odp_buf_to_hdr(buf); > + > + len += snprintf(&str[len], n-len, > + "Buffer\n"); > + len += snprintf(&str[len], n-len, > + " pool %"PRIu64"\n", (int64_t) hdr->pool); > + len += snprintf(&str[len], n-len, > + " phy_addr %"PRIu64"\n", hdr->buf_physaddr); > + len += snprintf(&str[len], n-len, > + " addr %p\n", hdr->buf_addr); > + len += snprintf(&str[len], n-len, > + " size %u\n", hdr->buf_len); > + len += snprintf(&str[len], n-len, > + " ref_count %i\n", hdr->refcnt); > + len += snprintf(&str[len], n-len, > + " type %i\n", hdr->type); > + > + return len; > +} > + > + > +void odp_buffer_print(odp_buffer_t buf) > +{ > + int max_len = 512; > + char str[max_len]; > + int len; > + > + len = odp_buffer_snprint(str, max_len-1, buf); > + str[len] = 0; > + > + printf("\n%s\n", str); > +} > + > diff --git a/platform/linux-dpdk/odp_buffer_pool.c b/platform/linux-dpdk/odp_buffer_pool.c > new file mode 100644 > index 0000000..de90275 > --- /dev/null > +++ b/platform/linux-dpdk/odp_buffer_pool.c > @@ -0,0 +1,156 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_std_types.h> > +#include <odp_buffer_pool.h> > +#include <odp_buffer_pool_internal.h> > +#include <odp_buffer_internal.h> > +#include <odp_packet_internal.h> > +#include <odp_shared_memory.h> > +#include <odp_align.h> > +#include <odp_internal.h> > +#include <odp_config.h> > +#include <odp_hints.h> > +#include <odp_debug.h> > + > +#include <string.h> > +#include <stdlib.h> > + > +/* for DPDK */ > +#include <odp_packet_dpdk.h> > + > +#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) > +#define NB_MBUF 8192 > + > +#ifdef POOL_USE_TICKETLOCK > +#include <odp_ticketlock.h> > +#define LOCK(a) odp_ticketlock_lock(a) > +#define UNLOCK(a) odp_ticketlock_unlock(a) > +#define LOCK_INIT(a) odp_ticketlock_init(a) > +#else > +#include <odp_spinlock.h> > +#define LOCK(a) odp_spinlock_lock(a) > +#define UNLOCK(a) odp_spinlock_unlock(a) > +#define LOCK_INIT(a) odp_spinlock_init(a) > +#endif > + > + > +#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > +#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > +#endif > + > +#define NULL_INDEX ((uint32_t)-1) > + > + > +typedef union pool_entry_u { > + struct pool_entry_s s; > + > + uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))]; > + > +} pool_entry_t; > + > + > +typedef struct pool_table_t { > + pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS]; > + > +} pool_table_t; > + > + > +/* The pool table */ > +static pool_table_t *pool_tbl; > + > +/* Pool entry pointers (for inlining) */ > +void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS]; > + > + > +int odp_buffer_pool_init_global(void) > +{ > + odp_buffer_pool_t i; > + > + pool_tbl = odp_shm_reserve("odp_buffer_pools", > + sizeof(pool_table_t), > + sizeof(pool_entry_t)); > + > + if (pool_tbl == NULL) > + return -1; > + > + memset(pool_tbl, 0, sizeof(pool_table_t)); > + > + > + for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) { > + /* init locks */ > + pool_entry_t *pool = &pool_tbl->pool[i]; > + LOCK_INIT(&pool->s.lock); > + pool->s.pool = i; > + > + pool_entry_ptr[i] = pool; > + } > + > + ODP_DBG("\nBuffer pool init global\n"); > + ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct pool_entry_s)); > + ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t)); > + ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t)); > + ODP_DBG("\n"); > + > + return 0; > +} > + > + > +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; > + 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, 32, > + sizeof(struct rte_pktmbuf_pool_private), > + rte_pktmbuf_pool_init, NULL, > + rte_pktmbuf_init, NULL, > + rte_socket_id(), 0); > + if (pktmbuf_pool == NULL) { > + ODP_ERR("Cannot init DPDK mbuf pool\n"); > + return -1; > + } > + > + return (odp_buffer_pool_t) pktmbuf_pool; > +} > + > + > +odp_buffer_pool_t odp_buffer_pool_lookup(const char *name) > +{ > + struct rte_mempool *mp = NULL; > + > + mp = rte_mempool_lookup(name); > + if (mp == NULL) > + return ODP_BUFFER_POOL_INVALID; > + > + return (odp_buffer_pool_t)mp; > +} > + > + > +odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id) > +{ > + return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool *)pool_id); > +} > + > + > +void odp_buffer_free(odp_buffer_t buf) > +{ > + rte_pktmbuf_free((struct rte_mbuf *)buf); > +} > + > + > +void odp_buffer_pool_print(odp_buffer_pool_t pool_id) > +{ > + rte_mempool_dump((const struct rte_mempool *)pool_id); > +} > diff --git a/platform/linux-dpdk/odp_init.c b/platform/linux-dpdk/odp_init.c > new file mode 100644 > index 0000000..ecc2066 > --- /dev/null > +++ b/platform/linux-dpdk/odp_init.c > @@ -0,0 +1,113 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_init.h> > +#include <odp_internal.h> > +#include <odp_debug.h> > +#include <odp_packet_dpdk.h> > + > +int odp_init_dpdk(void) > +{ > + int test_argc = 5; > + char *test_argv[6]; > + int core_count, i, num_cores = 0; > + char core_mask[8]; > + > + core_count = odp_sys_core_count(); > + for (i = 0; i < core_count; i++) > + num_cores += (0x1 << i); > + sprintf(core_mask, "%x", num_cores); > + > + test_argv[0] = malloc(sizeof("odp_dpdk")); > + strcpy(test_argv[0], "odp_dpdk"); > + test_argv[1] = malloc(sizeof("-c")); > + strcpy(test_argv[1], "-c"); > + test_argv[2] = malloc(sizeof(core_mask)); > + strcpy(test_argv[2], core_mask); > + test_argv[3] = malloc(sizeof("-n")); > + strcpy(test_argv[3], "-n"); > + test_argv[4] = malloc(sizeof("3")); > + strcpy(test_argv[4], "3"); > + > + if (rte_eal_init(test_argc, (char **)test_argv) < 0) { > + ODP_ERR("Cannot init the Intel DPDK EAL!"); > + return -1; > + } > + > + if (rte_pmd_init_all() < 0) { > + ODP_ERR("Cannot init pmd\n"); > + return -1; > + } > + > + if (rte_eal_pci_probe() < 0) { > + ODP_ERR("Cannot probe PCI\n"); > + return -1; > + } > + > + return 0; > +} > + > +int odp_init_global(void) > +{ > + odp_thread_init_global(); > + > + odp_system_info_init(); > + > + if (odp_init_dpdk()) { > + ODP_ERR("ODP dpdk init failed.\n"); > + return -1; > + } > + > + if (odp_shm_init_global()) { > + ODP_ERR("ODP shm init failed.\n"); > + return -1; > + } > + > + if (odp_buffer_pool_init_global()) { > + ODP_ERR("ODP buffer pool init failed.\n"); > + return -1; > + } > + > + if (odp_queue_init_global()) { > + ODP_ERR("ODP queue init failed.\n"); > + return -1; > + } > + > + if (odp_schedule_init_global()) { > + ODP_ERR("ODP schedule init failed.\n"); > + return -1; > + } > + > + if (odp_pktio_init_global()) { > + ODP_ERR("ODP packet io init failed.\n"); > + return -1; > + } > + > + if (odp_timer_init_global()) { > + ODP_ERR("ODP timer init failed.\n"); > + return -1; > + } > + > + return 0; > +} > + > + > +int odp_init_local(int thr_id) > +{ > + odp_thread_init_local(thr_id); > + > + if (odp_pktio_init_local()) { > + ODP_ERR("ODP packet io local init failed.\n"); > + return -1; > + } > + > + if (odp_schedule_init_local()) { > + ODP_ERR("ODP schedule local init failed.\n"); > + return -1; > + } > + > + return 0; > +} > diff --git a/platform/linux-dpdk/odp_linux.c b/platform/linux-dpdk/odp_linux.c > new file mode 100644 > index 0000000..067bd99 > --- /dev/null > +++ b/platform/linux-dpdk/odp_linux.c > @@ -0,0 +1,96 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#ifndef _GNU_SOURCE > +#define _GNU_SOURCE > +#endif > +#include <sched.h> > + > +#include <stdlib.h> > +#include <string.h> > +#include <stdio.h> > +#include <assert.h> > + > +#include <helper/odp_linux.h> > +#include <odp_internal.h> > +#include <odp_thread.h> > +#include <odp_init.h> > +#include <odp_system_info.h> > + > +#include <rte_lcore.h> > + > +typedef struct { > + int thr_id; > + void *(*start_routine) (void *); > + void *arg; > + > +} odp_start_args_t; > + > + > +static void *odp_run_start_routine(void *arg) > +{ > + odp_start_args_t *start_args = arg; > + > + /* ODP thread local init */ > + odp_init_local(start_args->thr_id); > + > + return start_args->start_routine(start_args->arg); > +} > + > + > +void odp_linux_pthread_create(odp_linux_pthread_t *thread_tbl, int num, > + int first_core, void *(*start_routine) (void *), void *arg) > +{ > + int i; > + cpu_set_t cpu_set; > + odp_start_args_t *start_args; > + int core_count; > + int cpu; > + > + (void) cpu_set; > + (void) thread_tbl; > + > + core_count = odp_sys_core_count(); > + > + assert((first_core >= 0) && (first_core < core_count)); > + assert((num >= 0) && (num <= core_count)); > + > + for (i = 0; i < num; i++) { > + cpu = (first_core + i) % core_count; > + > + start_args = malloc(sizeof(odp_start_args_t)); > + memset(start_args, 0, sizeof(odp_start_args_t)); > + start_args->start_routine = start_routine; > + start_args->arg = arg; > + > + odp_thread_create(cpu); > + start_args->thr_id = cpu; > + /* If not master core */ > + if (cpu != 0) { > + rte_eal_remote_launch( > + (int(*)(void *))odp_run_start_routine, > + start_args, cpu); > + } else { > + lcore_config[cpu].ret = (int)(uint64_t) > + odp_run_start_routine(start_args); > + lcore_config[cpu].state = FINISHED; > + } > + } > +} > + > + > +void odp_linux_pthread_join(odp_linux_pthread_t *thread_tbl, int num) > +{ > + uint32_t lcore_id; > + > + (void) thread_tbl; > + (void) num; > + > + RTE_LCORE_FOREACH_SLAVE(lcore_id) { > + if (rte_eal_wait_lcore(lcore_id) < 0) > + return; > + } > +} > diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c > new file mode 100644 > index 0000000..c34e626 > --- /dev/null > +++ b/platform/linux-dpdk/odp_packet.c > @@ -0,0 +1,374 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_packet.h> > +#include <odp_packet_internal.h> > +#include <odp_hints.h> > +#include <odp_byteorder.h> > + > +#include <helper/odp_eth.h> > +#include <helper/odp_ip.h> > + > +#include <string.h> > +#include <stdio.h> > + > +static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, > + size_t *offset_out); > +static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, > + size_t *offset_out); > + > +void odp_packet_init(odp_packet_t pkt) > +{ > + odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > + const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); > + uint8_t *start; > + size_t len; > + > + start = (uint8_t *)pkt_hdr + start_offset; > + len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > + memset(start, 0, len); > + > + pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > + pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > + pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > +} > + > +odp_packet_t odp_packet_from_buffer(odp_buffer_t buf) > +{ > + return (odp_packet_t)buf; > +} > + > +odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt) > +{ > + return (odp_buffer_t)pkt; > +} > + > +void odp_packet_set_len(odp_packet_t pkt, size_t len) > +{ > + /* for rte_pktmbuf */ > + odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(odp_buffer_from_packet(pkt)); > + buf_hdr->pkt.data_len = len; > + > + odp_packet_hdr(pkt)->frame_len = len; > +} > + > +size_t odp_packet_get_len(odp_packet_t pkt) > +{ > + return odp_packet_hdr(pkt)->frame_len; > +} > + > +uint8_t *odp_packet_buf_addr(odp_packet_t pkt) > +{ > + return odp_buffer_addr(odp_buffer_from_packet(pkt)); > +} > + > +uint8_t *odp_packet_start(odp_packet_t pkt) > +{ > + return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset; > +} > + > + > +uint8_t *odp_packet_l2(odp_packet_t pkt) > +{ > + const size_t offset = odp_packet_l2_offset(pkt); > + > + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > + return NULL; > + > + return odp_packet_buf_addr(pkt) + offset; > +} > + > +size_t odp_packet_l2_offset(odp_packet_t pkt) > +{ > + return odp_packet_hdr(pkt)->l2_offset; > +} > + > +void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset) > +{ > + odp_packet_hdr(pkt)->l2_offset = offset; > +} > + > +uint8_t *odp_packet_l3(odp_packet_t pkt) > +{ > + const size_t offset = odp_packet_l3_offset(pkt); > + > + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > + return NULL; > + > + return odp_packet_buf_addr(pkt) + offset; > +} > + > +size_t odp_packet_l3_offset(odp_packet_t pkt) > +{ > + return odp_packet_hdr(pkt)->l3_offset; > +} > + > +void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset) > +{ > + odp_packet_hdr(pkt)->l3_offset = offset; > +} > + > +uint8_t *odp_packet_l4(odp_packet_t pkt) > +{ > + const size_t offset = odp_packet_l4_offset(pkt); > + > + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > + return NULL; > + > + return odp_packet_buf_addr(pkt) + offset; > +} > + > +size_t odp_packet_l4_offset(odp_packet_t pkt) > +{ > + return odp_packet_hdr(pkt)->l4_offset; > +} > + > +void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset) > +{ > + odp_packet_hdr(pkt)->l4_offset = offset; > +} > + > +/** > + * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP > + * > + * Internal function: caller is resposible for passing only valid packet handles > + * , lengths and offsets (usually done&called in packet input). > + * > + * @param pkt Packet handle > + * @param len Packet length in bytes > + * @param frame_offset Byte offset to L2 header > + */ > +void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset) > +{ > + odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > + odp_ethhdr_t *eth; > + odp_vlanhdr_t *vlan; > + odp_ipv4hdr_t *ipv4; > + odp_ipv6hdr_t *ipv6; > + uint16_t ethtype; > + size_t offset = 0; > + uint8_t ip_proto = 0; > + > + pkt_hdr->input_flags.eth = 1; > + pkt_hdr->frame_offset = frame_offset; > + pkt_hdr->frame_len = len; > + > + if (odp_unlikely(len < ODP_ETH_LEN_MIN)) { > + pkt_hdr->error_flags.frame_len = 1; > + return; > + } else if (len > ODP_ETH_LEN_MAX) { > + pkt_hdr->input_flags.jumbo = 1; > + } > + > + /* Assume valid L2 header, no CRC/FCS check in SW */ > + pkt_hdr->input_flags.l2 = 1; > + pkt_hdr->l2_offset = frame_offset; > + > + eth = (odp_ethhdr_t *)odp_packet_start(pkt); > + ethtype = odp_be_to_cpu_16(eth->type); > + vlan = (odp_vlanhdr_t *)ð->type; > + > + if (ethtype == ODP_ETHTYPE_VLAN_OUTER) { > + pkt_hdr->input_flags.vlan_qinq = 1; > + ethtype = odp_be_to_cpu_16(vlan->tpid); > + offset += sizeof(odp_vlanhdr_t); > + vlan = &vlan[1]; > + } > + > + if (ethtype == ODP_ETHTYPE_VLAN) { > + pkt_hdr->input_flags.vlan = 1; > + ethtype = odp_be_to_cpu_16(vlan->tpid); > + offset += sizeof(odp_vlanhdr_t); > + } > + > + /* Set l3_offset+flag only for known ethtypes */ > + switch (ethtype) { > + case ODP_ETHTYPE_IPV4: > + pkt_hdr->input_flags.ipv4 = 1; > + pkt_hdr->input_flags.l3 = 1; > + pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; > + ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt); > + ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset); > + break; > + case ODP_ETHTYPE_IPV6: > + pkt_hdr->input_flags.ipv6 = 1; > + pkt_hdr->input_flags.l3 = 1; > + pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; > + ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt); > + ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset); > + break; > + case ODP_ETHTYPE_ARP: > + pkt_hdr->input_flags.arp = 1; > + /* fall through */ > + default: > + ip_proto = 0; > + break; > + } > + > + switch (ip_proto) { > + case ODP_IPPROTO_UDP: > + pkt_hdr->input_flags.udp = 1; > + pkt_hdr->input_flags.l4 = 1; > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > + break; > + case ODP_IPPROTO_TCP: > + pkt_hdr->input_flags.tcp = 1; > + pkt_hdr->input_flags.l4 = 1; > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > + break; > + case ODP_IPPROTO_SCTP: > + pkt_hdr->input_flags.sctp = 1; > + pkt_hdr->input_flags.l4 = 1; > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > + break; > + case ODP_IPPROTO_ICMP: > + pkt_hdr->input_flags.icmp = 1; > + pkt_hdr->input_flags.l4 = 1; > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > + break; > + default: > + /* 0 or unhandled IP protocols, don't set L4 flag+offset */ > + if (pkt_hdr->input_flags.ipv6) { > + /* IPv6 next_hdr is not L4, mark as IP-option instead */ > + pkt_hdr->input_flags.ipopt = 1; > + } > + break; > + } > +} > + > +static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, > + size_t *offset_out) > +{ > + uint8_t ihl; > + uint16_t frag_offset; > + > + ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl); > + if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) { > + pkt_hdr->error_flags.ip_err = 1; > + return 0; > + } > + > + if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) { > + pkt_hdr->input_flags.ipopt = 1; > + return 0; > + } > + > + /* A packet is a fragment if: > + * "more fragments" flag is set (all fragments except the last) > + * OR > + * "fragment offset" field is nonzero (all fragments except the first) > + */ > + frag_offset = odp_be_to_cpu_16(ipv4->frag_offset); > + if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) { > + pkt_hdr->input_flags.ipfrag = 1; > + return 0; > + } > + > + if (ipv4->proto == ODP_IPPROTO_ESP || > + ipv4->proto == ODP_IPPROTO_AH) { > + pkt_hdr->input_flags.ipsec = 1; > + return 0; > + } > + > + /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after return */ > + > + *offset_out = sizeof(uint32_t) * ihl; > + return ipv4->proto; > +} > + > +static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, > + size_t *offset_out) > +{ > + if (ipv6->next_hdr == ODP_IPPROTO_ESP || > + ipv6->next_hdr == ODP_IPPROTO_AH) { > + pkt_hdr->input_flags.ipopt = 1; > + pkt_hdr->input_flags.ipsec = 1; > + return 0; > + } > + > + if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) { > + pkt_hdr->input_flags.ipopt = 1; > + pkt_hdr->input_flags.ipfrag = 1; > + return 0; > + } > + > + /* Don't step through more extensions */ > + *offset_out = ODP_IPV6HDR_LEN; > + return ipv6->next_hdr; > +} > + > +void odp_packet_print(odp_packet_t pkt) > +{ > + int max_len = 512; > + char str[max_len]; > + int len = 0; > + int n = max_len-1; > + odp_packet_hdr_t *hdr = odp_packet_hdr(pkt); > + > + len += snprintf(&str[len], n-len, "Packet "); > + len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt); > + len += snprintf(&str[len], n-len, > + " input_flags 0x%x\n", hdr->input_flags.all); > + len += snprintf(&str[len], n-len, > + " error_flags 0x%x\n", hdr->error_flags.all); > + len += snprintf(&str[len], n-len, > + " output_flags 0x%x\n", hdr->output_flags.all); > + len += snprintf(&str[len], n-len, > + " frame_offset %u\n", hdr->frame_offset); > + len += snprintf(&str[len], n-len, > + " l2_offset %u\n", hdr->l2_offset); > + len += snprintf(&str[len], n-len, > + " l3_offset %u\n", hdr->l3_offset); > + len += snprintf(&str[len], n-len, > + " l4_offset %u\n", hdr->l4_offset); > + len += snprintf(&str[len], n-len, > + " frame_len %u\n", hdr->frame_len); > + len += snprintf(&str[len], n-len, > + " input %u\n", hdr->input); > + str[len] = '\0'; > + > + printf("\n%s\n", str); > +} > + > +int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src) > +{ > + odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst); > + odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src); > + const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); > + uint8_t *start_src; > + uint8_t *start_dst; > + size_t len; > + > + if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID) > + return -1; > + > + /* if (pkt_hdr_dst->buf_hdr.size < */ > + /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */ > + if (pkt_hdr_dst->buf_hdr.buf_len < > + pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) > + return -1; > + > + /* Copy packet header */ > + start_dst = (uint8_t *)pkt_hdr_dst + start_offset; > + start_src = (uint8_t *)pkt_hdr_src + start_offset; > + len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > + memcpy(start_dst, start_src, len); > + > + /* Copy frame payload */ > + start_dst = (uint8_t *)odp_packet_start(pkt_dst); > + start_src = (uint8_t *)odp_packet_start(pkt_src); > + len = pkt_hdr_src->frame_len; > + memcpy(start_dst, start_src, len); > + > + /* Copy useful things from the buffer header */ > + /* pkt_hdr_dst->buf_hdr.cur_offset = pkt_hdr_src->buf_hdr.cur_offset; */ > + > + /* Create a copy of the scatter list */ > + /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */ > + /* odp_buffer_from_packet(pkt_src)); */ > + > + return 0; > +} > diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c > new file mode 100644 > index 0000000..31bfa30 > --- /dev/null > +++ b/platform/linux-dpdk/odp_packet_dpdk.c > @@ -0,0 +1,189 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#define _GNU_SOURCE > +#include <stdio.h> > +#include <errno.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <sys/ioctl.h> > +#include <sys/mman.h> > +#include <poll.h> > +#include <unistd.h> > +#include <fcntl.h> > +#include <string.h> > +#include <stdlib.h> > + > +#include <linux/ethtool.h> > +#include <linux/sockios.h> > + > +#include <odp_hints.h> > +#include <odp_thread.h> > + > +#include <odp_packet_dpdk.h> > +#include <net/if.h> > + > +/* > + * RX and TX Prefetch, Host, and Write-back threshold values should be > + * carefully set for optimal performance. Consult the network > + * controller's datasheet and supporting DPDK documentation for guidance > + * on how these parameters should be set. > + */ > +#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ > +#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ > +#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */ > + > +/* > + * These default values are optimized for use with the Intel(R) 82599 10 GbE > + * Controller and the DPDK ixgbe PMD. Consider using other values for other > + * network controllers and/or network drivers. > + */ > +#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */ > +#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ > +#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ > + > +#define MAX_PKT_BURST 16 > +#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ > +#define RTE_TEST_RX_DESC_DEFAULT 128 > +#define RTE_TEST_TX_DESC_DEFAULT 512 > +static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; > +static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; > + > +static const struct rte_eth_conf port_conf = { > + .rxmode = { > + .split_hdr_size = 0, > + .header_split = 0, /**< Header Split disabled */ > + .hw_ip_checksum = 0, /**< IP checksum offload disabled */ > + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ > + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ > + .hw_strip_crc = 0, /**< CRC stripped by hardware */ > + }, > + .txmode = { > + .mq_mode = ETH_MQ_TX_NONE, > + }, > +}; > + > +static const struct rte_eth_rxconf rx_conf = { > + .rx_thresh = { > + .pthresh = RX_PTHRESH, > + .hthresh = RX_HTHRESH, > + .wthresh = RX_WTHRESH, > + }, > +}; > + > +static const struct rte_eth_txconf tx_conf = { > + .tx_thresh = { > + .pthresh = TX_PTHRESH, > + .hthresh = TX_HTHRESH, > + .wthresh = TX_WTHRESH, > + }, > + .tx_free_thresh = 0, /* Use PMD default values */ > + .tx_rs_thresh = 0, /* Use PMD default values */ > + /* > + * As the example won't handle mult-segments and offload cases, > + * set the flag by default. > + */ > + .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS, > +}; > + > +int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, > + odp_buffer_pool_t pool) > +{ > + ODP_DBG("setup_pkt_dpdk\n"); > + > + static struct ether_addr eth_addr[RTE_MAX_ETHPORTS]; > + uint8_t portid = 0; > + uint16_t queueid = 0; > + int ret; > + printf("dpdk netdev: %s\n", netdev); > + printf("dpdk pool: %lx\n", pool); > + > + portid = atoi(netdev); > + pkt_dpdk->portid = portid; > + pkt_dpdk->queueid = queueid; > + pkt_dpdk->pool = pool; > + printf("dpdk portid: %u\n", portid); > + > + fflush(stdout); > + ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); > + if (ret < 0) > + ODP_ERR("Cannot configure device: err=%d, port=%u\n", > + ret, (unsigned) portid); > + > + rte_eth_macaddr_get(portid, ð_addr[portid]); > + ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", > + (unsigned) portid, > + eth_addr[portid].addr_bytes[0], > + eth_addr[portid].addr_bytes[1], > + eth_addr[portid].addr_bytes[2], > + eth_addr[portid].addr_bytes[3], > + eth_addr[portid].addr_bytes[4], > + eth_addr[portid].addr_bytes[5]); > + > + /* init one RX queue on each port */ > + fflush(stdout); > + ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd, > + rte_eth_dev_socket_id(portid), &rx_conf, > + (struct rte_mempool *)pool); > + if (ret < 0) > + ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n", > + ret, (unsigned) portid); > + ODP_DBG("dpdk rx queue setup done\n"); > + > + /* init one TX queue on each port */ > + fflush(stdout); > + ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, > + rte_eth_dev_socket_id(portid), &tx_conf); > + if (ret < 0) > + ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n", > + ret, (unsigned) portid); > + ODP_DBG("dpdk tx queue setup done\n"); > + > + /* Start device */ > + ret = rte_eth_dev_start(portid); > + if (ret < 0) > + ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n", > + ret, (unsigned) portid); > + ODP_DBG("dpdk setup done\n\n"); > + > + > + return 0; > +} > + > +int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk) > +{ > + ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid); > + > + return 0; > +} > + > +int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > + unsigned len) > +{ > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > + uint16_t nb_rx, i = 0; > + > + memset(pkts_burst, 0 , sizeof(pkts_burst)); > + nb_rx = rte_eth_rx_burst((uint8_t)pkt_dpdk->portid, > + (uint16_t)pkt_dpdk->queueid, > + (struct rte_mbuf **)pkts_burst, (uint16_t)len); > + for (i = 0; i < nb_rx; i++) > + pkt_table[i] = (odp_packet_t)pkts_burst[i]; > + return nb_rx; > +} > + > +int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > + unsigned len) > +{ > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > + uint16_t i; > + > + for (i = 0; i < len; i++) > + pkts_burst[i] = (struct rte_mbuf *)pkt_table[i]; > + return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid, > + (uint16_t)pkt_dpdk->queueid, > + (struct rte_mbuf **)pkts_burst, (uint16_t)len); > +} > diff --git a/platform/linux-dpdk/odp_packet_io.c b/platform/linux-dpdk/odp_packet_io.c > new file mode 100644 > index 0000000..abea0ec > --- /dev/null > +++ b/platform/linux-dpdk/odp_packet_io.c > @@ -0,0 +1,561 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_packet_io.h> > +#include <odp_packet_io_internal.h> > +#include <odp_packet_io_queue.h> > +#include <odp_packet.h> > +#include <odp_packet_internal.h> > +#include <odp_internal.h> > +#include <odp_spinlock.h> > +#include <odp_shared_memory.h> > +#include <odp_packet_socket.h> > +#ifdef ODP_HAVE_NETMAP > +#include <odp_packet_netmap.h> > +#endif > +#include <odp_hints.h> > +#include <odp_config.h> > +#include <odp_queue_internal.h> > +#include <odp_schedule_internal.h> > +#include <odp_debug.h> > + > +#include <odp_pktio_socket.h> > +#ifdef ODP_HAVE_NETMAP > +#include <odp_pktio_netmap.h> > +#endif > + > +#include <string.h> > + > +typedef struct { > + pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; > +} pktio_table_t; > + > +static pktio_table_t *pktio_tbl; > + > + > +static pktio_entry_t *get_entry(odp_pktio_t id) > +{ > + if (odp_unlikely(id == ODP_PKTIO_INVALID || > + id > ODP_CONFIG_PKTIO_ENTRIES)) > + return NULL; > + > + return &pktio_tbl->entries[id - 1]; > +} > + > +int odp_pktio_init_global(void) > +{ > + char name[ODP_QUEUE_NAME_LEN]; > + pktio_entry_t *pktio_entry; > + queue_entry_t *queue_entry; > + odp_queue_t qid; > + int id; > + > + pktio_tbl = odp_shm_reserve("odp_pktio_entries", > + sizeof(pktio_table_t), > + sizeof(pktio_entry_t)); > + if (pktio_tbl == NULL) > + return -1; > + > + memset(pktio_tbl, 0, sizeof(pktio_table_t)); > + > + for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) { > + pktio_entry = get_entry(id); > + > + odp_spinlock_init(&pktio_entry->s.lock); > + > + /* Create a default output queue for each pktio resource */ > + snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id); > + name[ODP_QUEUE_NAME_LEN-1] = '\0'; > + > + qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL); > + if (qid == ODP_QUEUE_INVALID) > + return -1; > + pktio_entry->s.outq_default = qid; > + > + queue_entry = queue_to_qentry(qid); > + queue_entry->s.pktout = id; > + } > + > + return 0; > +} > + > +int odp_pktio_init_local(void) > +{ > + return 0; > +} > + > +static int is_free(pktio_entry_t *entry) > +{ > + return (entry->s.taken == 0); > +} > + > +static void set_free(pktio_entry_t *entry) > +{ > + entry->s.taken = 0; > +} > + > +static void set_taken(pktio_entry_t *entry) > +{ > + entry->s.taken = 1; > +} > + > +static void lock_entry(pktio_entry_t *entry) > +{ > + odp_spinlock_lock(&entry->s.lock); > +} > + > +static void unlock_entry(pktio_entry_t *entry) > +{ > + odp_spinlock_unlock(&entry->s.lock); > +} > + > +static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params) > +{ > + set_taken(entry); > + entry->s.inq_default = ODP_QUEUE_INVALID; > + switch (params->type) { > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); > + memset(&entry->s.pkt_sock_mmap, 0, > + sizeof(entry->s.pkt_sock_mmap)); > + break; > +#ifdef ODP_HAVE_NETMAP > + case ODP_PKTIO_TYPE_NETMAP: > + memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); > + break; > +#endif > + case ODP_PKTIO_TYPE_DPDK: > + memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk)); > + break; > + default: > + ODP_ERR("Packet I/O type not supported. Please recompile\n"); > + break; > + } > + /* Save pktio parameters, type is the most useful */ > + memcpy(&entry->s.params, params, sizeof(*params)); > +} > + > +static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params) > +{ > + odp_pktio_t id; > + pktio_entry_t *entry; > + int i; > + > + for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { > + entry = &pktio_tbl->entries[i]; > + if (is_free(entry)) { > + lock_entry(entry); > + if (is_free(entry)) { > + init_pktio_entry(entry, params); > + id = i + 1; > + return id; /* return with entry locked! */ > + } > + unlock_entry(entry); > + } > + } > + > + return ODP_PKTIO_INVALID; > +} > + > +static int free_pktio_entry(odp_pktio_t id) > +{ > + pktio_entry_t *entry = get_entry(id); > + > + if (entry == NULL) > + return -1; > + > + set_free(entry); > + > + return 0; > +} > + > +odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool, > + odp_pktio_params_t *params) > +{ > + odp_pktio_t id; > + pktio_entry_t *pktio_entry; > + int res; > + > + if (params == NULL) { > + ODP_ERR("Invalid pktio params\n"); > + return ODP_PKTIO_INVALID; > + } > + > + switch (params->type) { > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + ODP_DBG("Allocating socket pktio\n"); > + break; > +#ifdef ODP_HAVE_NETMAP > + case ODP_PKTIO_TYPE_NETMAP: > + ODP_DBG("Allocating netmap pktio\n"); > + break; > +#endif > + case ODP_PKTIO_TYPE_DPDK: > + ODP_DBG("Allocating dpdk pktio\n"); > + break; > + default: > + ODP_ERR("Invalid pktio type: %02x\n", params->type); > + return ODP_PKTIO_INVALID; > + } > + > + id = alloc_lock_pktio_entry(params); > + if (id == ODP_PKTIO_INVALID) { > + ODP_ERR("No resources available.\n"); > + return ODP_PKTIO_INVALID; > + } > + /* if successful, alloc_pktio_entry() returns with the entry locked */ > + > + pktio_entry = get_entry(id); > + > + switch (params->type) { > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); > + if (res == -1) { > + close_pkt_sock(&pktio_entry->s.pkt_sock); > + free_pktio_entry(id); > + id = ODP_PKTIO_INVALID; > + } > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev, > + pool, params->sock_params.fanout); > + if (res == -1) { > + close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); > + free_pktio_entry(id); > + id = ODP_PKTIO_INVALID; > + } > + break; > +#ifdef ODP_HAVE_NETMAP > + case ODP_PKTIO_TYPE_NETMAP: > + > + res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, > + pool, ¶ms->nm_params); > + if (res == -1) { > + close_pkt_netmap(&pktio_entry->s.pkt_nm); > + free_pktio_entry(id); > + id = ODP_PKTIO_INVALID; > + } > + break; > +#endif > + case ODP_PKTIO_TYPE_DPDK: > + res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool); > + if (res == -1) { > + close_pkt_dpdk(&pktio_entry->s.pkt_dpdk); > + free_pktio_entry(id); > + id = ODP_PKTIO_INVALID; > + } > + break; > + default: > + free_pktio_entry(id); > + id = ODP_PKTIO_INVALID; > + ODP_ERR("Invalid pktio type. Please recompile.\n"); > + break; > + } > + > + unlock_entry(pktio_entry); > + return id; > +} > + > +int odp_pktio_close(odp_pktio_t id) > +{ > + pktio_entry_t *entry; > + int res = -1; > + > + entry = get_entry(id); > + if (entry == NULL) > + return -1; > + > + lock_entry(entry); > + if (!is_free(entry)) { > + switch (entry->s.params.type) { > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + res = close_pkt_sock(&entry->s.pkt_sock); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); > + break; > +#ifdef ODP_HAVE_NETMAP > + case ODP_PKTIO_TYPE_NETMAP: > + res = close_pkt_netmap(&entry->s.pkt_nm); > + break; > +#endif > + case ODP_PKTIO_TYPE_DPDK: > + res = close_pkt_dpdk(&entry->s.pkt_dpdk); > + break; > + default: > + break; > + res |= free_pktio_entry(id); > + } > + } > + unlock_entry(entry); > + > + if (res != 0) > + return -1; > + > + return 0; > +} > + > +void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio) > +{ > + odp_packet_hdr(pkt)->input = pktio; > +} > + > +odp_pktio_t odp_pktio_get_input(odp_packet_t pkt) > +{ > + return odp_packet_hdr(pkt)->input; > +} > + > +int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) > +{ > + pktio_entry_t *pktio_entry = get_entry(id); > + int pkts; > + int i; > + > + if (pktio_entry == NULL) > + return -1; > + > + lock_entry(pktio_entry); > + switch (pktio_entry->s.params.type) { > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > + pkt_table, len); > + break; > +#ifdef ODP_HAVE_NETMAP > + case ODP_PKTIO_TYPE_NETMAP: > + pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len); > + break; > +#endif > + case ODP_PKTIO_TYPE_DPDK: > + pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, len); > + break; > + default: > + pkts = -1; > + break; > + } > + > + unlock_entry(pktio_entry); > + if (pkts < 0) > + return pkts; > + > + for (i = 0; i < pkts; ++i) > + odp_pktio_set_input(pkt_table[i], id); > + > + return pkts; > +} > + > +int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) > +{ > + pktio_entry_t *pktio_entry = get_entry(id); > + int pkts; > + > + if (pktio_entry == NULL) > + return -1; > + > + lock_entry(pktio_entry); > + switch (pktio_entry->s.params.type) { > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > + pkt_table, len); > + break; > +#ifdef ODP_HAVE_NETMAP > + case ODP_PKTIO_TYPE_NETMAP: > + pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, > + pkt_table, len); > + break; > +#endif > + case ODP_PKTIO_TYPE_DPDK: > + pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk, > + pkt_table, len); > + break; > + default: > + pkts = -1; > + } > + unlock_entry(pktio_entry); > + > + return pkts; > +} > + > +int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue) > +{ > + pktio_entry_t *pktio_entry = get_entry(id); > + queue_entry_t *qentry = queue_to_qentry(queue); > + > + if (pktio_entry == NULL || qentry == NULL) > + return -1; > + > + if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN) > + return -1; > + > + lock_entry(pktio_entry); > + pktio_entry->s.inq_default = queue; > + unlock_entry(pktio_entry); > + > + queue_lock(qentry); > + qentry->s.pktin = id; > + qentry->s.status = QUEUE_STATUS_SCHED; > + queue_unlock(qentry); > + > + odp_schedule_queue(queue, qentry->s.param.sched.prio); > + > + return 0; > +} > + > +int odp_pktio_inq_remdef(odp_pktio_t id) > +{ > + return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID); > +} > + > +odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id) > +{ > + pktio_entry_t *pktio_entry = get_entry(id); > + > + if (pktio_entry == NULL) > + return ODP_QUEUE_INVALID; > + > + return pktio_entry->s.inq_default; > +} > + > +odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id) > +{ > + pktio_entry_t *pktio_entry = get_entry(id); > + > + if (pktio_entry == NULL) > + return ODP_QUEUE_INVALID; > + > + return pktio_entry->s.outq_default; > +} > + > +int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > +{ > + odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr); > + int len = 1; > + int nbr; > + > + nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); > + return (nbr == len ? 0 : -1); > +} > + > +odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry) > +{ > + (void)qentry; > + return NULL; > +} > + > +int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > + int num) > +{ > + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > + int nbr; > + int i; > + > + for (i = 0; i < num; ++i) > + pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) buf_hdr[i]); > + > + nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > + return (nbr == num ? 0 : -1); > +} > + > +int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > + int num) > +{ > + (void)qentry; > + (void)buf_hdr; > + (void)num; > + > + return 0; > +} > + > +int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > +{ > + /* Use default action */ > + return queue_enq(qentry, buf_hdr); > +} > + > +odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry) > +{ > + odp_buffer_hdr_t *buf_hdr; > + > + buf_hdr = queue_deq(qentry); > + > + if (buf_hdr == NULL) { > + odp_packet_t pkt; > + odp_buffer_t buf; > + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > + odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > + int pkts, i, j; > + > + pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > + QUEUE_MULTI_MAX); > + > + if (pkts > 0) { > + pkt = pkt_tbl[0]; > + buf = odp_buffer_from_packet(pkt); > + buf_hdr = odp_buf_to_hdr(buf); > + > + for (i = 1, j = 0; i < pkts; ++i) { > + buf = odp_buffer_from_packet(pkt_tbl[i]); > + tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf); > + } > + queue_enq_multi(qentry, tmp_hdr_tbl, j); > + } > + } > + > + return buf_hdr; > +} > + > +int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) > +{ > + /* Use default action */ > + return queue_enq_multi(qentry, buf_hdr, num); > +} > + > +int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) > +{ > + int nbr; > + > + nbr = queue_deq_multi(qentry, buf_hdr, num); > + > + if (nbr < num) { > + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > + odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > + odp_buffer_t buf; > + int pkts, i; > + > + pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > + QUEUE_MULTI_MAX); > + if (pkts > 0) { > + for (i = 0; i < pkts; ++i) { > + buf = odp_buffer_from_packet(pkt_tbl[i]); > + tmp_hdr_tbl[i] = odp_buf_to_hdr(buf); > + } > + queue_enq_multi(qentry, tmp_hdr_tbl, pkts); > + } > + } > + > + return nbr; > +} > diff --git a/platform/linux-dpdk/odp_queue.c b/platform/linux-dpdk/odp_queue.c > new file mode 100644 > index 0000000..554b8ea > --- /dev/null > +++ b/platform/linux-dpdk/odp_queue.c > @@ -0,0 +1,435 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_queue.h> > +#include <odp_queue_internal.h> > +#include <odp_std_types.h> > +#include <odp_align.h> > +#include <odp_buffer.h> > +#include <odp_buffer_internal.h> > +#include <odp_buffer_pool_internal.h> > +#include <odp_internal.h> > +#include <odp_shared_memory.h> > +#include <odp_schedule_internal.h> > +#include <odp_config.h> > +#include <odp_packet_io_internal.h> > +#include <odp_packet_io_queue.h> > +#include <odp_debug.h> > +#include <odp_hints.h> > + > +#ifdef USE_TICKETLOCK > +#include <odp_ticketlock.h> > +#define LOCK(a) odp_ticketlock_lock(a) > +#define UNLOCK(a) odp_ticketlock_unlock(a) > +#define LOCK_INIT(a) odp_ticketlock_init(a) > +#else > +#include <odp_spinlock.h> > +#define LOCK(a) odp_spinlock_lock(a) > +#define UNLOCK(a) odp_spinlock_unlock(a) > +#define LOCK_INIT(a) odp_spinlock_init(a) > +#endif > + > +#include <string.h> > + > + > +typedef struct queue_table_t { > + queue_entry_t queue[ODP_CONFIG_QUEUES]; > +} queue_table_t; > + > +static queue_table_t *queue_tbl; > + > + > +queue_entry_t *get_qentry(uint32_t queue_id) > +{ > + return &queue_tbl->queue[queue_id]; > +} > + > +static void queue_init(queue_entry_t *queue, const char *name, > + odp_queue_type_t type, odp_queue_param_t *param) > +{ > + strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1); > + queue->s.type = type; > + > + if (param) { > + memcpy(&queue->s.param, param, sizeof(odp_queue_param_t)); > + } else { > + /* Defaults */ > + memset(&queue->s.param, 0, sizeof(odp_queue_param_t)); > + queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT; > + queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT; > + queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT; > + } > + > + switch (type) { > + case ODP_QUEUE_TYPE_PKTIN: > + queue->s.enqueue = pktin_enqueue; > + queue->s.dequeue = pktin_dequeue; > + queue->s.enqueue_multi = pktin_enq_multi; > + queue->s.dequeue_multi = pktin_deq_multi; > + break; > + case ODP_QUEUE_TYPE_PKTOUT: > + queue->s.enqueue = pktout_enqueue; > + queue->s.dequeue = pktout_dequeue; > + queue->s.enqueue_multi = pktout_enq_multi; > + queue->s.dequeue_multi = pktout_deq_multi; > + break; > + default: > + queue->s.enqueue = queue_enq; > + queue->s.dequeue = queue_deq; > + queue->s.enqueue_multi = queue_enq_multi; > + queue->s.dequeue_multi = queue_deq_multi; > + break; > + } > + > + queue->s.head = NULL; > + queue->s.tail = NULL; > + queue->s.sched_buf = ODP_BUFFER_INVALID; > +} > + > + > +int odp_queue_init_global(void) > +{ > + uint32_t i; > + > + ODP_DBG("Queue init ... "); > + > + queue_tbl = odp_shm_reserve("odp_queues", > + sizeof(queue_table_t), > + sizeof(queue_entry_t)); > + > + if (queue_tbl == NULL) > + return -1; > + > + memset(queue_tbl, 0, sizeof(queue_table_t)); > + > + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > + /* init locks */ > + queue_entry_t *queue = get_qentry(i); > + LOCK_INIT(&queue->s.lock); > + queue->s.handle = queue_from_id(i); > + } > + > + ODP_DBG("done\n"); > + ODP_DBG("Queue init global\n"); > + ODP_DBG(" struct queue_entry_s size %zu\n", > + sizeof(struct queue_entry_s)); > + ODP_DBG(" queue_entry_t size %zu\n", > + sizeof(queue_entry_t)); > + ODP_DBG("\n"); > + > + return 0; > +} > + > +odp_queue_type_t odp_queue_type(odp_queue_t handle) > +{ > + queue_entry_t *queue; > + > + queue = queue_to_qentry(handle); > + > + return queue->s.type; > +} > + > +odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle) > +{ > + queue_entry_t *queue; > + > + queue = queue_to_qentry(handle); > + > + return queue->s.param.sched.sync; > +} > + > +odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type, > + odp_queue_param_t *param) > +{ > + uint32_t i; > + queue_entry_t *queue; > + odp_queue_t handle = ODP_QUEUE_INVALID; > + > + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > + queue = &queue_tbl->queue[i]; > + > + if (queue->s.status != QUEUE_STATUS_FREE) > + continue; > + > + LOCK(&queue->s.lock); > + if (queue->s.status == QUEUE_STATUS_FREE) { > + queue_init(queue, name, type, param); > + > + if (type == ODP_QUEUE_TYPE_SCHED || > + type == ODP_QUEUE_TYPE_PKTIN) > + queue->s.status = QUEUE_STATUS_NOTSCHED; > + else > + queue->s.status = QUEUE_STATUS_READY; > + > + handle = queue->s.handle; > + UNLOCK(&queue->s.lock); > + break; > + } > + UNLOCK(&queue->s.lock); > + } > + > + if (handle != ODP_QUEUE_INVALID && > + (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) { > + odp_buffer_t buf; > + > + buf = odp_schedule_buffer_alloc(handle); > + if (buf == ODP_BUFFER_INVALID) { > + ODP_ERR("queue_init: sched buf alloc failed\n"); > + return ODP_QUEUE_INVALID; > + } > + > + queue->s.sched_buf = buf; > + odp_schedule_mask_set(handle, queue->s.param.sched.prio); > + } > + > + return handle; > +} > + > + > +odp_buffer_t queue_sched_buf(odp_queue_t handle) > +{ > + queue_entry_t *queue; > + queue = queue_to_qentry(handle); > + > + return queue->s.sched_buf; > +} > + > + > +int queue_sched_atomic(odp_queue_t handle) > +{ > + queue_entry_t *queue; > + queue = queue_to_qentry(handle); > + > + return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC; > +} > + > + > +odp_queue_t odp_queue_lookup(const char *name) > +{ > + uint32_t i; > + > + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > + queue_entry_t *queue = &queue_tbl->queue[i]; > + > + if (queue->s.status == QUEUE_STATUS_FREE) > + continue; > + > + LOCK(&queue->s.lock); > + if (strcmp(name, queue->s.name) == 0) { > + /* found it */ > + UNLOCK(&queue->s.lock); > + return queue->s.handle; > + } > + UNLOCK(&queue->s.lock); > + } > + > + return ODP_QUEUE_INVALID; > +} > + > + > +int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr) > +{ > + int sched = 0; > + > + LOCK(&queue->s.lock); > + if (queue->s.head == NULL) { > + /* Empty queue */ > + queue->s.head = buf_hdr; > + queue->s.tail = buf_hdr; > + buf_hdr->pkt.next = NULL; > + } else { > + queue->s.tail->pkt.next = buf_hdr; > + queue->s.tail = buf_hdr; > + buf_hdr->pkt.next = NULL; > + } > + > + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > + queue->s.status = QUEUE_STATUS_SCHED; > + sched = 1; /* retval: schedule queue */ > + } > + UNLOCK(&queue->s.lock); > + > + /* Add queue to scheduling */ > + if (sched == 1) > + odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); > + > + return 0; > +} > + > + > +int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) > +{ > + int sched = 0; > + int i; > + odp_buffer_hdr_t *tail; > + > + for (i = 0; i < num - 1; i++) > + buf_hdr[i]->pkt.next = buf_hdr[i+1]; > + > + tail = buf_hdr[num-1]; > + buf_hdr[num-1]->pkt.next = NULL; > + > + LOCK(&queue->s.lock); > + /* Empty queue */ > + if (queue->s.head == NULL) > + queue->s.head = buf_hdr[0]; > + else > + queue->s.tail->pkt.next = buf_hdr[0]; > + > + queue->s.tail = tail; > + > + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > + queue->s.status = QUEUE_STATUS_SCHED; > + sched = 1; /* retval: schedule queue */ > + } > + UNLOCK(&queue->s.lock); > + > + /* Add queue to scheduling */ > + if (sched == 1) > + odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); > + > + return 0; > +} > + > + > +int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > +{ > + odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > + queue_entry_t *queue; > + int i; > + > + if (num > QUEUE_MULTI_MAX) > + num = QUEUE_MULTI_MAX; > + > + queue = queue_to_qentry(handle); > + > + for (i = 0; i < num; i++) > + buf_hdr[i] = odp_buf_to_hdr(buf[i]); > + > + return queue->s.enqueue_multi(queue, buf_hdr, num); > +} > + > + > +int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf) > +{ > + odp_buffer_hdr_t *buf_hdr; > + queue_entry_t *queue; > + > + queue = queue_to_qentry(handle); > + buf_hdr = odp_buf_to_hdr(buf); > + > + return queue->s.enqueue(queue, buf_hdr); > +} > + > + > +odp_buffer_hdr_t *queue_deq(queue_entry_t *queue) > +{ > + odp_buffer_hdr_t *buf_hdr = NULL; > + > + LOCK(&queue->s.lock); > + > + if (queue->s.head == NULL) { > + /* Already empty queue */ > + if (queue->s.status == QUEUE_STATUS_SCHED && > + queue->s.type != ODP_QUEUE_TYPE_PKTIN) > + queue->s.status = QUEUE_STATUS_NOTSCHED; > + } else { > + buf_hdr = queue->s.head; > + queue->s.head = buf_hdr->pkt.next; > + buf_hdr->pkt.next = NULL; > + > + if (queue->s.head == NULL) { > + /* Queue is now empty */ > + queue->s.tail = NULL; > + } > + } > + > + UNLOCK(&queue->s.lock); > + > + return buf_hdr; > +} > + > + > +int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) > +{ > + int i = 0; > + > + LOCK(&queue->s.lock); > + > + if (queue->s.head == NULL) { > + /* Already empty queue */ > + if (queue->s.status == QUEUE_STATUS_SCHED && > + queue->s.type != ODP_QUEUE_TYPE_PKTIN) > + queue->s.status = QUEUE_STATUS_NOTSCHED; > + } else { > + odp_buffer_hdr_t *hdr = queue->s.head; > + > + for (; i < num && hdr; i++) { > + buf_hdr[i] = hdr; > + /* odp_prefetch(hdr->addr); */ > + hdr = hdr->pkt.next; > + buf_hdr[i]->pkt.next = NULL; > + } > + > + queue->s.head = hdr; > + > + if (hdr == NULL) { > + /* Queue is now empty */ > + queue->s.tail = NULL; > + } > + } > + > + UNLOCK(&queue->s.lock); > + > + return i; > +} > + > + > +int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > +{ > + queue_entry_t *queue; > + odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > + int i, ret; > + > + if (num > QUEUE_MULTI_MAX) > + num = QUEUE_MULTI_MAX; > + > + queue = queue_to_qentry(handle); > + > + ret = queue->s.dequeue_multi(queue, buf_hdr, num); > + > + for (i = 0; i < ret; i++) > + buf[i] = (odp_buffer_t) buf_hdr[i]; > + > + return ret; > +} > + > + > +odp_buffer_t odp_queue_deq(odp_queue_t handle) > +{ > + queue_entry_t *queue; > + odp_buffer_hdr_t *buf_hdr; > + > + queue = queue_to_qentry(handle); > + buf_hdr = queue->s.dequeue(queue); > + > + if (buf_hdr) > + return (odp_buffer_t) buf_hdr; > + > + return ODP_BUFFER_INVALID; > +} > + > + > +void queue_lock(queue_entry_t *queue) > +{ > + LOCK(&queue->s.lock); > +} > + > + > +void queue_unlock(queue_entry_t *queue) > +{ > + UNLOCK(&queue->s.lock); > +} > diff --git a/platform/linux-dpdk/source/odp_buffer.c b/platform/linux-dpdk/source/odp_buffer.c > deleted file mode 100644 > index bfb5ff6..0000000 > --- a/platform/linux-dpdk/source/odp_buffer.c > +++ /dev/null > @@ -1,102 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -#include <odp_buffer.h> > -#include <odp_buffer_internal.h> > -#include <odp_buffer_pool_internal.h> > - > -#include <string.h> > -#include <stdio.h> > - > - > -void *odp_buffer_addr(odp_buffer_t buf) > -{ > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > - > - return hdr->buf_addr; > -} > - > - > -size_t odp_buffer_size(odp_buffer_t buf) > -{ > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > - > - return hdr->buf_len; > -} > - > - > -int odp_buffer_type(odp_buffer_t buf) > -{ > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > - > - return hdr->type; > -} > - > - > -int odp_buffer_is_scatter(odp_buffer_t buf) > -{ > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > - > - if (hdr->refcnt == 0) > - return 0; > - else > - return 1; > -} > - > - > -int odp_buffer_is_valid(odp_buffer_t buf) > -{ > - odp_buffer_bits_t handle; > - > - handle.u32 = buf; > - > - return (handle.index != ODP_BUFFER_INVALID_INDEX); > -} > - > - > -int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) > -{ > - odp_buffer_hdr_t *hdr; > - int len = 0; > - > - if (!odp_buffer_is_valid(buf)) { > - printf("Buffer is not valid.\n"); > - return len; > - } > - > - hdr = odp_buf_to_hdr(buf); > - > - len += snprintf(&str[len], n-len, > - "Buffer\n"); > - len += snprintf(&str[len], n-len, > - " pool %"PRIu64"\n", (int64_t) hdr->pool); > - len += snprintf(&str[len], n-len, > - " phy_addr %"PRIu64"\n", hdr->buf_physaddr); > - len += snprintf(&str[len], n-len, > - " addr %p\n", hdr->buf_addr); > - len += snprintf(&str[len], n-len, > - " size %u\n", hdr->buf_len); > - len += snprintf(&str[len], n-len, > - " ref_count %i\n", hdr->refcnt); > - len += snprintf(&str[len], n-len, > - " type %i\n", hdr->type); > - > - return len; > -} > - > - > -void odp_buffer_print(odp_buffer_t buf) > -{ > - int max_len = 512; > - char str[max_len]; > - int len; > - > - len = odp_buffer_snprint(str, max_len-1, buf); > - str[len] = 0; > - > - printf("\n%s\n", str); > -} > - > diff --git a/platform/linux-dpdk/source/odp_buffer_pool.c b/platform/linux-dpdk/source/odp_buffer_pool.c > deleted file mode 100644 > index de90275..0000000 > --- a/platform/linux-dpdk/source/odp_buffer_pool.c > +++ /dev/null > @@ -1,156 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -#include <odp_std_types.h> > -#include <odp_buffer_pool.h> > -#include <odp_buffer_pool_internal.h> > -#include <odp_buffer_internal.h> > -#include <odp_packet_internal.h> > -#include <odp_shared_memory.h> > -#include <odp_align.h> > -#include <odp_internal.h> > -#include <odp_config.h> > -#include <odp_hints.h> > -#include <odp_debug.h> > - > -#include <string.h> > -#include <stdlib.h> > - > -/* for DPDK */ > -#include <odp_packet_dpdk.h> > - > -#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) > -#define NB_MBUF 8192 > - > -#ifdef POOL_USE_TICKETLOCK > -#include <odp_ticketlock.h> > -#define LOCK(a) odp_ticketlock_lock(a) > -#define UNLOCK(a) odp_ticketlock_unlock(a) > -#define LOCK_INIT(a) odp_ticketlock_init(a) > -#else > -#include <odp_spinlock.h> > -#define LOCK(a) odp_spinlock_lock(a) > -#define UNLOCK(a) odp_spinlock_unlock(a) > -#define LOCK_INIT(a) odp_spinlock_init(a) > -#endif > - > - > -#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > -#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > -#endif > - > -#define NULL_INDEX ((uint32_t)-1) > - > - > -typedef union pool_entry_u { > - struct pool_entry_s s; > - > - uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))]; > - > -} pool_entry_t; > - > - > -typedef struct pool_table_t { > - pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS]; > - > -} pool_table_t; > - > - > -/* The pool table */ > -static pool_table_t *pool_tbl; > - > -/* Pool entry pointers (for inlining) */ > -void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS]; > - > - > -int odp_buffer_pool_init_global(void) > -{ > - odp_buffer_pool_t i; > - > - pool_tbl = odp_shm_reserve("odp_buffer_pools", > - sizeof(pool_table_t), > - sizeof(pool_entry_t)); > - > - if (pool_tbl == NULL) > - return -1; > - > - memset(pool_tbl, 0, sizeof(pool_table_t)); > - > - > - for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) { > - /* init locks */ > - pool_entry_t *pool = &pool_tbl->pool[i]; > - LOCK_INIT(&pool->s.lock); > - pool->s.pool = i; > - > - pool_entry_ptr[i] = pool; > - } > - > - ODP_DBG("\nBuffer pool init global\n"); > - ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct pool_entry_s)); > - ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t)); > - ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t)); > - ODP_DBG("\n"); > - > - return 0; > -} > - > - > -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; > - 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, 32, > - sizeof(struct rte_pktmbuf_pool_private), > - rte_pktmbuf_pool_init, NULL, > - rte_pktmbuf_init, NULL, > - rte_socket_id(), 0); > - if (pktmbuf_pool == NULL) { > - ODP_ERR("Cannot init DPDK mbuf pool\n"); > - return -1; > - } > - > - return (odp_buffer_pool_t) pktmbuf_pool; > -} > - > - > -odp_buffer_pool_t odp_buffer_pool_lookup(const char *name) > -{ > - struct rte_mempool *mp = NULL; > - > - mp = rte_mempool_lookup(name); > - if (mp == NULL) > - return ODP_BUFFER_POOL_INVALID; > - > - return (odp_buffer_pool_t)mp; > -} > - > - > -odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id) > -{ > - return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool *)pool_id); > -} > - > - > -void odp_buffer_free(odp_buffer_t buf) > -{ > - rte_pktmbuf_free((struct rte_mbuf *)buf); > -} > - > - > -void odp_buffer_pool_print(odp_buffer_pool_t pool_id) > -{ > - rte_mempool_dump((const struct rte_mempool *)pool_id); > -} > diff --git a/platform/linux-dpdk/source/odp_init.c b/platform/linux-dpdk/source/odp_init.c > deleted file mode 100644 > index ecc2066..0000000 > --- a/platform/linux-dpdk/source/odp_init.c > +++ /dev/null > @@ -1,113 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -#include <odp_init.h> > -#include <odp_internal.h> > -#include <odp_debug.h> > -#include <odp_packet_dpdk.h> > - > -int odp_init_dpdk(void) > -{ > - int test_argc = 5; > - char *test_argv[6]; > - int core_count, i, num_cores = 0; > - char core_mask[8]; > - > - core_count = odp_sys_core_count(); > - for (i = 0; i < core_count; i++) > - num_cores += (0x1 << i); > - sprintf(core_mask, "%x", num_cores); > - > - test_argv[0] = malloc(sizeof("odp_dpdk")); > - strcpy(test_argv[0], "odp_dpdk"); > - test_argv[1] = malloc(sizeof("-c")); > - strcpy(test_argv[1], "-c"); > - test_argv[2] = malloc(sizeof(core_mask)); > - strcpy(test_argv[2], core_mask); > - test_argv[3] = malloc(sizeof("-n")); > - strcpy(test_argv[3], "-n"); > - test_argv[4] = malloc(sizeof("3")); > - strcpy(test_argv[4], "3"); > - > - if (rte_eal_init(test_argc, (char **)test_argv) < 0) { > - ODP_ERR("Cannot init the Intel DPDK EAL!"); > - return -1; > - } > - > - if (rte_pmd_init_all() < 0) { > - ODP_ERR("Cannot init pmd\n"); > - return -1; > - } > - > - if (rte_eal_pci_probe() < 0) { > - ODP_ERR("Cannot probe PCI\n"); > - return -1; > - } > - > - return 0; > -} > - > -int odp_init_global(void) > -{ > - odp_thread_init_global(); > - > - odp_system_info_init(); > - > - if (odp_init_dpdk()) { > - ODP_ERR("ODP dpdk init failed.\n"); > - return -1; > - } > - > - if (odp_shm_init_global()) { > - ODP_ERR("ODP shm init failed.\n"); > - return -1; > - } > - > - if (odp_buffer_pool_init_global()) { > - ODP_ERR("ODP buffer pool init failed.\n"); > - return -1; > - } > - > - if (odp_queue_init_global()) { > - ODP_ERR("ODP queue init failed.\n"); > - return -1; > - } > - > - if (odp_schedule_init_global()) { > - ODP_ERR("ODP schedule init failed.\n"); > - return -1; > - } > - > - if (odp_pktio_init_global()) { > - ODP_ERR("ODP packet io init failed.\n"); > - return -1; > - } > - > - if (odp_timer_init_global()) { > - ODP_ERR("ODP timer init failed.\n"); > - return -1; > - } > - > - return 0; > -} > - > - > -int odp_init_local(int thr_id) > -{ > - odp_thread_init_local(thr_id); > - > - if (odp_pktio_init_local()) { > - ODP_ERR("ODP packet io local init failed.\n"); > - return -1; > - } > - > - if (odp_schedule_init_local()) { > - ODP_ERR("ODP schedule local init failed.\n"); > - return -1; > - } > - > - return 0; > -} > diff --git a/platform/linux-dpdk/source/odp_packet.c b/platform/linux-dpdk/source/odp_packet.c > deleted file mode 100644 > index c34e626..0000000 > --- a/platform/linux-dpdk/source/odp_packet.c > +++ /dev/null > @@ -1,374 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -#include <odp_packet.h> > -#include <odp_packet_internal.h> > -#include <odp_hints.h> > -#include <odp_byteorder.h> > - > -#include <helper/odp_eth.h> > -#include <helper/odp_ip.h> > - > -#include <string.h> > -#include <stdio.h> > - > -static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, > - size_t *offset_out); > -static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, > - size_t *offset_out); > - > -void odp_packet_init(odp_packet_t pkt) > -{ > - odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > - const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); > - uint8_t *start; > - size_t len; > - > - start = (uint8_t *)pkt_hdr + start_offset; > - len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > - memset(start, 0, len); > - > - pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > - pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > - pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > -} > - > -odp_packet_t odp_packet_from_buffer(odp_buffer_t buf) > -{ > - return (odp_packet_t)buf; > -} > - > -odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt) > -{ > - return (odp_buffer_t)pkt; > -} > - > -void odp_packet_set_len(odp_packet_t pkt, size_t len) > -{ > - /* for rte_pktmbuf */ > - odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(odp_buffer_from_packet(pkt)); > - buf_hdr->pkt.data_len = len; > - > - odp_packet_hdr(pkt)->frame_len = len; > -} > - > -size_t odp_packet_get_len(odp_packet_t pkt) > -{ > - return odp_packet_hdr(pkt)->frame_len; > -} > - > -uint8_t *odp_packet_buf_addr(odp_packet_t pkt) > -{ > - return odp_buffer_addr(odp_buffer_from_packet(pkt)); > -} > - > -uint8_t *odp_packet_start(odp_packet_t pkt) > -{ > - return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset; > -} > - > - > -uint8_t *odp_packet_l2(odp_packet_t pkt) > -{ > - const size_t offset = odp_packet_l2_offset(pkt); > - > - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > - return NULL; > - > - return odp_packet_buf_addr(pkt) + offset; > -} > - > -size_t odp_packet_l2_offset(odp_packet_t pkt) > -{ > - return odp_packet_hdr(pkt)->l2_offset; > -} > - > -void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset) > -{ > - odp_packet_hdr(pkt)->l2_offset = offset; > -} > - > -uint8_t *odp_packet_l3(odp_packet_t pkt) > -{ > - const size_t offset = odp_packet_l3_offset(pkt); > - > - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > - return NULL; > - > - return odp_packet_buf_addr(pkt) + offset; > -} > - > -size_t odp_packet_l3_offset(odp_packet_t pkt) > -{ > - return odp_packet_hdr(pkt)->l3_offset; > -} > - > -void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset) > -{ > - odp_packet_hdr(pkt)->l3_offset = offset; > -} > - > -uint8_t *odp_packet_l4(odp_packet_t pkt) > -{ > - const size_t offset = odp_packet_l4_offset(pkt); > - > - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > - return NULL; > - > - return odp_packet_buf_addr(pkt) + offset; > -} > - > -size_t odp_packet_l4_offset(odp_packet_t pkt) > -{ > - return odp_packet_hdr(pkt)->l4_offset; > -} > - > -void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset) > -{ > - odp_packet_hdr(pkt)->l4_offset = offset; > -} > - > -/** > - * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP > - * > - * Internal function: caller is resposible for passing only valid packet handles > - * , lengths and offsets (usually done&called in packet input). > - * > - * @param pkt Packet handle > - * @param len Packet length in bytes > - * @param frame_offset Byte offset to L2 header > - */ > -void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset) > -{ > - odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > - odp_ethhdr_t *eth; > - odp_vlanhdr_t *vlan; > - odp_ipv4hdr_t *ipv4; > - odp_ipv6hdr_t *ipv6; > - uint16_t ethtype; > - size_t offset = 0; > - uint8_t ip_proto = 0; > - > - pkt_hdr->input_flags.eth = 1; > - pkt_hdr->frame_offset = frame_offset; > - pkt_hdr->frame_len = len; > - > - if (odp_unlikely(len < ODP_ETH_LEN_MIN)) { > - pkt_hdr->error_flags.frame_len = 1; > - return; > - } else if (len > ODP_ETH_LEN_MAX) { > - pkt_hdr->input_flags.jumbo = 1; > - } > - > - /* Assume valid L2 header, no CRC/FCS check in SW */ > - pkt_hdr->input_flags.l2 = 1; > - pkt_hdr->l2_offset = frame_offset; > - > - eth = (odp_ethhdr_t *)odp_packet_start(pkt); > - ethtype = odp_be_to_cpu_16(eth->type); > - vlan = (odp_vlanhdr_t *)ð->type; > - > - if (ethtype == ODP_ETHTYPE_VLAN_OUTER) { > - pkt_hdr->input_flags.vlan_qinq = 1; > - ethtype = odp_be_to_cpu_16(vlan->tpid); > - offset += sizeof(odp_vlanhdr_t); > - vlan = &vlan[1]; > - } > - > - if (ethtype == ODP_ETHTYPE_VLAN) { > - pkt_hdr->input_flags.vlan = 1; > - ethtype = odp_be_to_cpu_16(vlan->tpid); > - offset += sizeof(odp_vlanhdr_t); > - } > - > - /* Set l3_offset+flag only for known ethtypes */ > - switch (ethtype) { > - case ODP_ETHTYPE_IPV4: > - pkt_hdr->input_flags.ipv4 = 1; > - pkt_hdr->input_flags.l3 = 1; > - pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; > - ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt); > - ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset); > - break; > - case ODP_ETHTYPE_IPV6: > - pkt_hdr->input_flags.ipv6 = 1; > - pkt_hdr->input_flags.l3 = 1; > - pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; > - ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt); > - ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset); > - break; > - case ODP_ETHTYPE_ARP: > - pkt_hdr->input_flags.arp = 1; > - /* fall through */ > - default: > - ip_proto = 0; > - break; > - } > - > - switch (ip_proto) { > - case ODP_IPPROTO_UDP: > - pkt_hdr->input_flags.udp = 1; > - pkt_hdr->input_flags.l4 = 1; > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > - break; > - case ODP_IPPROTO_TCP: > - pkt_hdr->input_flags.tcp = 1; > - pkt_hdr->input_flags.l4 = 1; > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > - break; > - case ODP_IPPROTO_SCTP: > - pkt_hdr->input_flags.sctp = 1; > - pkt_hdr->input_flags.l4 = 1; > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > - break; > - case ODP_IPPROTO_ICMP: > - pkt_hdr->input_flags.icmp = 1; > - pkt_hdr->input_flags.l4 = 1; > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > - break; > - default: > - /* 0 or unhandled IP protocols, don't set L4 flag+offset */ > - if (pkt_hdr->input_flags.ipv6) { > - /* IPv6 next_hdr is not L4, mark as IP-option instead */ > - pkt_hdr->input_flags.ipopt = 1; > - } > - break; > - } > -} > - > -static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, > - size_t *offset_out) > -{ > - uint8_t ihl; > - uint16_t frag_offset; > - > - ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl); > - if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) { > - pkt_hdr->error_flags.ip_err = 1; > - return 0; > - } > - > - if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) { > - pkt_hdr->input_flags.ipopt = 1; > - return 0; > - } > - > - /* A packet is a fragment if: > - * "more fragments" flag is set (all fragments except the last) > - * OR > - * "fragment offset" field is nonzero (all fragments except the first) > - */ > - frag_offset = odp_be_to_cpu_16(ipv4->frag_offset); > - if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) { > - pkt_hdr->input_flags.ipfrag = 1; > - return 0; > - } > - > - if (ipv4->proto == ODP_IPPROTO_ESP || > - ipv4->proto == ODP_IPPROTO_AH) { > - pkt_hdr->input_flags.ipsec = 1; > - return 0; > - } > - > - /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after return */ > - > - *offset_out = sizeof(uint32_t) * ihl; > - return ipv4->proto; > -} > - > -static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, > - size_t *offset_out) > -{ > - if (ipv6->next_hdr == ODP_IPPROTO_ESP || > - ipv6->next_hdr == ODP_IPPROTO_AH) { > - pkt_hdr->input_flags.ipopt = 1; > - pkt_hdr->input_flags.ipsec = 1; > - return 0; > - } > - > - if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) { > - pkt_hdr->input_flags.ipopt = 1; > - pkt_hdr->input_flags.ipfrag = 1; > - return 0; > - } > - > - /* Don't step through more extensions */ > - *offset_out = ODP_IPV6HDR_LEN; > - return ipv6->next_hdr; > -} > - > -void odp_packet_print(odp_packet_t pkt) > -{ > - int max_len = 512; > - char str[max_len]; > - int len = 0; > - int n = max_len-1; > - odp_packet_hdr_t *hdr = odp_packet_hdr(pkt); > - > - len += snprintf(&str[len], n-len, "Packet "); > - len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt); > - len += snprintf(&str[len], n-len, > - " input_flags 0x%x\n", hdr->input_flags.all); > - len += snprintf(&str[len], n-len, > - " error_flags 0x%x\n", hdr->error_flags.all); > - len += snprintf(&str[len], n-len, > - " output_flags 0x%x\n", hdr->output_flags.all); > - len += snprintf(&str[len], n-len, > - " frame_offset %u\n", hdr->frame_offset); > - len += snprintf(&str[len], n-len, > - " l2_offset %u\n", hdr->l2_offset); > - len += snprintf(&str[len], n-len, > - " l3_offset %u\n", hdr->l3_offset); > - len += snprintf(&str[len], n-len, > - " l4_offset %u\n", hdr->l4_offset); > - len += snprintf(&str[len], n-len, > - " frame_len %u\n", hdr->frame_len); > - len += snprintf(&str[len], n-len, > - " input %u\n", hdr->input); > - str[len] = '\0'; > - > - printf("\n%s\n", str); > -} > - > -int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src) > -{ > - odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst); > - odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src); > - const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); > - uint8_t *start_src; > - uint8_t *start_dst; > - size_t len; > - > - if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID) > - return -1; > - > - /* if (pkt_hdr_dst->buf_hdr.size < */ > - /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */ > - if (pkt_hdr_dst->buf_hdr.buf_len < > - pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) > - return -1; > - > - /* Copy packet header */ > - start_dst = (uint8_t *)pkt_hdr_dst + start_offset; > - start_src = (uint8_t *)pkt_hdr_src + start_offset; > - len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > - memcpy(start_dst, start_src, len); > - > - /* Copy frame payload */ > - start_dst = (uint8_t *)odp_packet_start(pkt_dst); > - start_src = (uint8_t *)odp_packet_start(pkt_src); > - len = pkt_hdr_src->frame_len; > - memcpy(start_dst, start_src, len); > - > - /* Copy useful things from the buffer header */ > - /* pkt_hdr_dst->buf_hdr.cur_offset = pkt_hdr_src->buf_hdr.cur_offset; */ > - > - /* Create a copy of the scatter list */ > - /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */ > - /* odp_buffer_from_packet(pkt_src)); */ > - > - return 0; > -} > diff --git a/platform/linux-dpdk/source/odp_packet_dpdk.c b/platform/linux-dpdk/source/odp_packet_dpdk.c > deleted file mode 100644 > index 6d16bbe..0000000 > --- a/platform/linux-dpdk/source/odp_packet_dpdk.c > +++ /dev/null > @@ -1,177 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -#define _GNU_SOURCE > -#include <stdio.h> > -#include <errno.h> > -#include <sys/types.h> > -#include <sys/stat.h> > -#include <sys/ioctl.h> > -#include <sys/mman.h> > -#include <poll.h> > -#include <unistd.h> > -#include <fcntl.h> > -#include <string.h> > -#include <stdlib.h> > - > -#include <linux/ethtool.h> > -#include <linux/sockios.h> > - > -#include <odp_hints.h> > -#include <odp_thread.h> > - > -#include <odp_packet_dpdk.h> > -#include <net/if.h> > - > -/* > - * RX and TX Prefetch, Host, and Write-back threshold values should be > - * carefully set for optimal performance. Consult the network > - * controller's datasheet and supporting DPDK documentation for guidance > - * on how these parameters should be set. > - */ > -#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ > -#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ > -#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */ > - > -/* > - * These default values are optimized for use with the Intel(R) 82599 10 GbE > - * Controller and the DPDK ixgbe PMD. Consider using other values for other > - * network controllers and/or network drivers. > - */ > -#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */ > -#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ > -#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ > - > -#define MAX_PKT_BURST 32 > -#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ > -#define RTE_TEST_RX_DESC_DEFAULT 128 > -#define RTE_TEST_TX_DESC_DEFAULT 512 > -static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; > -static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; > - > -static const struct rte_eth_conf port_conf = { > - .rxmode = { > - .split_hdr_size = 0, > - .header_split = 0, /**< Header Split disabled */ > - .hw_ip_checksum = 0, /**< IP checksum offload disabled */ > - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ > - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ > - .hw_strip_crc = 0, /**< CRC stripped by hardware */ > - }, > - .txmode = { > - .mq_mode = ETH_MQ_TX_NONE, > - }, > -}; > - > -static const struct rte_eth_rxconf rx_conf = { > - .rx_thresh = { > - .pthresh = RX_PTHRESH, > - .hthresh = RX_HTHRESH, > - .wthresh = RX_WTHRESH, > - }, > -}; > - > -static const struct rte_eth_txconf tx_conf = { > - .tx_thresh = { > - .pthresh = TX_PTHRESH, > - .hthresh = TX_HTHRESH, > - .wthresh = TX_WTHRESH, > - }, > - .tx_free_thresh = 0, /* Use PMD default values */ > - .tx_rs_thresh = 0, /* Use PMD default values */ > - /* > - * As the example won't handle mult-segments and offload cases, > - * set the flag by default. > - */ > - .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS, > -}; > - > -int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, > - odp_buffer_pool_t pool) > -{ > - ODP_DBG("setup_pkt_dpdk\n"); > - > - static struct ether_addr eth_addr[RTE_MAX_ETHPORTS]; > - uint8_t portid = 0; > - uint16_t queueid = 0; > - int ret; > - printf("vincent netdev: %s\n", netdev); > - printf("vincent pool: %lx\n", pool); > - > - portid = atoi(netdev); > - pkt_dpdk->portid = portid; > - pkt_dpdk->queueid = queueid; > - pkt_dpdk->pool = pool; > - printf("vincent portid: %u\n", portid); > - > - fflush(stdout); > - ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); > - if (ret < 0) > - ODP_ERR("Cannot configure device: err=%d, port=%u\n", > - ret, (unsigned) portid); > - > - rte_eth_macaddr_get(portid, ð_addr[portid]); > - ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", > - (unsigned) portid, > - eth_addr[portid].addr_bytes[0], > - eth_addr[portid].addr_bytes[1], > - eth_addr[portid].addr_bytes[2], > - eth_addr[portid].addr_bytes[3], > - eth_addr[portid].addr_bytes[4], > - eth_addr[portid].addr_bytes[5]); > - > - /* init one RX queue on each port */ > - fflush(stdout); > - ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd, > - rte_eth_dev_socket_id(portid), &rx_conf, > - (struct rte_mempool *)pool); > - if (ret < 0) > - ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n", > - ret, (unsigned) portid); > - ODP_DBG("dpdk rx queue setup done\n"); > - > - /* init one TX queue on each port */ > - fflush(stdout); > - ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, > - rte_eth_dev_socket_id(portid), &tx_conf); > - if (ret < 0) > - ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n", > - ret, (unsigned) portid); > - ODP_DBG("dpdk tx queue setup done\n"); > - > - /* Start device */ > - ret = rte_eth_dev_start(portid); > - if (ret < 0) > - ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n", > - ret, (unsigned) portid); > - ODP_DBG("dpdk setup done\n\n"); > - > - > - return 0; > -} > - > -int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk) > -{ > - ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid); > - > - return 0; > -} > - > -int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > - unsigned len) > -{ > - return rte_eth_rx_burst((uint8_t)pkt_dpdk->portid, > - (uint16_t)pkt_dpdk->queueid, > - (struct rte_mbuf **)pkt_table, (uint16_t)len); > -} > - > -int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > - unsigned len) > -{ > - return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid, > - (uint16_t)pkt_dpdk->queueid, > - (struct rte_mbuf **)pkt_table, (uint16_t)len); > -} > diff --git a/platform/linux-dpdk/source/odp_packet_io.c b/platform/linux-dpdk/source/odp_packet_io.c > deleted file mode 100644 > index abea0ec..0000000 > --- a/platform/linux-dpdk/source/odp_packet_io.c > +++ /dev/null > @@ -1,561 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -#include <odp_packet_io.h> > -#include <odp_packet_io_internal.h> > -#include <odp_packet_io_queue.h> > -#include <odp_packet.h> > -#include <odp_packet_internal.h> > -#include <odp_internal.h> > -#include <odp_spinlock.h> > -#include <odp_shared_memory.h> > -#include <odp_packet_socket.h> > -#ifdef ODP_HAVE_NETMAP > -#include <odp_packet_netmap.h> > -#endif > -#include <odp_hints.h> > -#include <odp_config.h> > -#include <odp_queue_internal.h> > -#include <odp_schedule_internal.h> > -#include <odp_debug.h> > - > -#include <odp_pktio_socket.h> > -#ifdef ODP_HAVE_NETMAP > -#include <odp_pktio_netmap.h> > -#endif > - > -#include <string.h> > - > -typedef struct { > - pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; > -} pktio_table_t; > - > -static pktio_table_t *pktio_tbl; > - > - > -static pktio_entry_t *get_entry(odp_pktio_t id) > -{ > - if (odp_unlikely(id == ODP_PKTIO_INVALID || > - id > ODP_CONFIG_PKTIO_ENTRIES)) > - return NULL; > - > - return &pktio_tbl->entries[id - 1]; > -} > - > -int odp_pktio_init_global(void) > -{ > - char name[ODP_QUEUE_NAME_LEN]; > - pktio_entry_t *pktio_entry; > - queue_entry_t *queue_entry; > - odp_queue_t qid; > - int id; > - > - pktio_tbl = odp_shm_reserve("odp_pktio_entries", > - sizeof(pktio_table_t), > - sizeof(pktio_entry_t)); > - if (pktio_tbl == NULL) > - return -1; > - > - memset(pktio_tbl, 0, sizeof(pktio_table_t)); > - > - for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) { > - pktio_entry = get_entry(id); > - > - odp_spinlock_init(&pktio_entry->s.lock); > - > - /* Create a default output queue for each pktio resource */ > - snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id); > - name[ODP_QUEUE_NAME_LEN-1] = '\0'; > - > - qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL); > - if (qid == ODP_QUEUE_INVALID) > - return -1; > - pktio_entry->s.outq_default = qid; > - > - queue_entry = queue_to_qentry(qid); > - queue_entry->s.pktout = id; > - } > - > - return 0; > -} > - > -int odp_pktio_init_local(void) > -{ > - return 0; > -} > - > -static int is_free(pktio_entry_t *entry) > -{ > - return (entry->s.taken == 0); > -} > - > -static void set_free(pktio_entry_t *entry) > -{ > - entry->s.taken = 0; > -} > - > -static void set_taken(pktio_entry_t *entry) > -{ > - entry->s.taken = 1; > -} > - > -static void lock_entry(pktio_entry_t *entry) > -{ > - odp_spinlock_lock(&entry->s.lock); > -} > - > -static void unlock_entry(pktio_entry_t *entry) > -{ > - odp_spinlock_unlock(&entry->s.lock); > -} > - > -static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params) > -{ > - set_taken(entry); > - entry->s.inq_default = ODP_QUEUE_INVALID; > - switch (params->type) { > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > - memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); > - memset(&entry->s.pkt_sock_mmap, 0, > - sizeof(entry->s.pkt_sock_mmap)); > - break; > -#ifdef ODP_HAVE_NETMAP > - case ODP_PKTIO_TYPE_NETMAP: > - memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); > - break; > -#endif > - case ODP_PKTIO_TYPE_DPDK: > - memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk)); > - break; > - default: > - ODP_ERR("Packet I/O type not supported. Please recompile\n"); > - break; > - } > - /* Save pktio parameters, type is the most useful */ > - memcpy(&entry->s.params, params, sizeof(*params)); > -} > - > -static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params) > -{ > - odp_pktio_t id; > - pktio_entry_t *entry; > - int i; > - > - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { > - entry = &pktio_tbl->entries[i]; > - if (is_free(entry)) { > - lock_entry(entry); > - if (is_free(entry)) { > - init_pktio_entry(entry, params); > - id = i + 1; > - return id; /* return with entry locked! */ > - } > - unlock_entry(entry); > - } > - } > - > - return ODP_PKTIO_INVALID; > -} > - > -static int free_pktio_entry(odp_pktio_t id) > -{ > - pktio_entry_t *entry = get_entry(id); > - > - if (entry == NULL) > - return -1; > - > - set_free(entry); > - > - return 0; > -} > - > -odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool, > - odp_pktio_params_t *params) > -{ > - odp_pktio_t id; > - pktio_entry_t *pktio_entry; > - int res; > - > - if (params == NULL) { > - ODP_ERR("Invalid pktio params\n"); > - return ODP_PKTIO_INVALID; > - } > - > - switch (params->type) { > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > - ODP_DBG("Allocating socket pktio\n"); > - break; > -#ifdef ODP_HAVE_NETMAP > - case ODP_PKTIO_TYPE_NETMAP: > - ODP_DBG("Allocating netmap pktio\n"); > - break; > -#endif > - case ODP_PKTIO_TYPE_DPDK: > - ODP_DBG("Allocating dpdk pktio\n"); > - break; > - default: > - ODP_ERR("Invalid pktio type: %02x\n", params->type); > - return ODP_PKTIO_INVALID; > - } > - > - id = alloc_lock_pktio_entry(params); > - if (id == ODP_PKTIO_INVALID) { > - ODP_ERR("No resources available.\n"); > - return ODP_PKTIO_INVALID; > - } > - /* if successful, alloc_pktio_entry() returns with the entry locked */ > - > - pktio_entry = get_entry(id); > - > - switch (params->type) { > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > - res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); > - if (res == -1) { > - close_pkt_sock(&pktio_entry->s.pkt_sock); > - free_pktio_entry(id); > - id = ODP_PKTIO_INVALID; > - } > - break; > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > - res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev, > - pool, params->sock_params.fanout); > - if (res == -1) { > - close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); > - free_pktio_entry(id); > - id = ODP_PKTIO_INVALID; > - } > - break; > -#ifdef ODP_HAVE_NETMAP > - case ODP_PKTIO_TYPE_NETMAP: > - > - res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, > - pool, ¶ms->nm_params); > - if (res == -1) { > - close_pkt_netmap(&pktio_entry->s.pkt_nm); > - free_pktio_entry(id); > - id = ODP_PKTIO_INVALID; > - } > - break; > -#endif > - case ODP_PKTIO_TYPE_DPDK: > - res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool); > - if (res == -1) { > - close_pkt_dpdk(&pktio_entry->s.pkt_dpdk); > - free_pktio_entry(id); > - id = ODP_PKTIO_INVALID; > - } > - break; > - default: > - free_pktio_entry(id); > - id = ODP_PKTIO_INVALID; > - ODP_ERR("Invalid pktio type. Please recompile.\n"); > - break; > - } > - > - unlock_entry(pktio_entry); > - return id; > -} > - > -int odp_pktio_close(odp_pktio_t id) > -{ > - pktio_entry_t *entry; > - int res = -1; > - > - entry = get_entry(id); > - if (entry == NULL) > - return -1; > - > - lock_entry(entry); > - if (!is_free(entry)) { > - switch (entry->s.params.type) { > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > - res = close_pkt_sock(&entry->s.pkt_sock); > - break; > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > - res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); > - break; > -#ifdef ODP_HAVE_NETMAP > - case ODP_PKTIO_TYPE_NETMAP: > - res = close_pkt_netmap(&entry->s.pkt_nm); > - break; > -#endif > - case ODP_PKTIO_TYPE_DPDK: > - res = close_pkt_dpdk(&entry->s.pkt_dpdk); > - break; > - default: > - break; > - res |= free_pktio_entry(id); > - } > - } > - unlock_entry(entry); > - > - if (res != 0) > - return -1; > - > - return 0; > -} > - > -void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio) > -{ > - odp_packet_hdr(pkt)->input = pktio; > -} > - > -odp_pktio_t odp_pktio_get_input(odp_packet_t pkt) > -{ > - return odp_packet_hdr(pkt)->input; > -} > - > -int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) > -{ > - pktio_entry_t *pktio_entry = get_entry(id); > - int pkts; > - int i; > - > - if (pktio_entry == NULL) > - return -1; > - > - lock_entry(pktio_entry); > - switch (pktio_entry->s.params.type) { > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > - pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, > - pkt_table, len); > - break; > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > - pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > - pkt_table, len); > - break; > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > - pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > - pkt_table, len); > - break; > -#ifdef ODP_HAVE_NETMAP > - case ODP_PKTIO_TYPE_NETMAP: > - pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len); > - break; > -#endif > - case ODP_PKTIO_TYPE_DPDK: > - pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, len); > - break; > - default: > - pkts = -1; > - break; > - } > - > - unlock_entry(pktio_entry); > - if (pkts < 0) > - return pkts; > - > - for (i = 0; i < pkts; ++i) > - odp_pktio_set_input(pkt_table[i], id); > - > - return pkts; > -} > - > -int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) > -{ > - pktio_entry_t *pktio_entry = get_entry(id); > - int pkts; > - > - if (pktio_entry == NULL) > - return -1; > - > - lock_entry(pktio_entry); > - switch (pktio_entry->s.params.type) { > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > - pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, > - pkt_table, len); > - break; > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > - pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > - pkt_table, len); > - break; > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > - pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > - pkt_table, len); > - break; > -#ifdef ODP_HAVE_NETMAP > - case ODP_PKTIO_TYPE_NETMAP: > - pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, > - pkt_table, len); > - break; > -#endif > - case ODP_PKTIO_TYPE_DPDK: > - pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk, > - pkt_table, len); > - break; > - default: > - pkts = -1; > - } > - unlock_entry(pktio_entry); > - > - return pkts; > -} > - > -int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue) > -{ > - pktio_entry_t *pktio_entry = get_entry(id); > - queue_entry_t *qentry = queue_to_qentry(queue); > - > - if (pktio_entry == NULL || qentry == NULL) > - return -1; > - > - if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN) > - return -1; > - > - lock_entry(pktio_entry); > - pktio_entry->s.inq_default = queue; > - unlock_entry(pktio_entry); > - > - queue_lock(qentry); > - qentry->s.pktin = id; > - qentry->s.status = QUEUE_STATUS_SCHED; > - queue_unlock(qentry); > - > - odp_schedule_queue(queue, qentry->s.param.sched.prio); > - > - return 0; > -} > - > -int odp_pktio_inq_remdef(odp_pktio_t id) > -{ > - return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID); > -} > - > -odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id) > -{ > - pktio_entry_t *pktio_entry = get_entry(id); > - > - if (pktio_entry == NULL) > - return ODP_QUEUE_INVALID; > - > - return pktio_entry->s.inq_default; > -} > - > -odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id) > -{ > - pktio_entry_t *pktio_entry = get_entry(id); > - > - if (pktio_entry == NULL) > - return ODP_QUEUE_INVALID; > - > - return pktio_entry->s.outq_default; > -} > - > -int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > -{ > - odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr); > - int len = 1; > - int nbr; > - > - nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); > - return (nbr == len ? 0 : -1); > -} > - > -odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry) > -{ > - (void)qentry; > - return NULL; > -} > - > -int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > - int num) > -{ > - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > - int nbr; > - int i; > - > - for (i = 0; i < num; ++i) > - pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) buf_hdr[i]); > - > - nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > - return (nbr == num ? 0 : -1); > -} > - > -int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > - int num) > -{ > - (void)qentry; > - (void)buf_hdr; > - (void)num; > - > - return 0; > -} > - > -int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > -{ > - /* Use default action */ > - return queue_enq(qentry, buf_hdr); > -} > - > -odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry) > -{ > - odp_buffer_hdr_t *buf_hdr; > - > - buf_hdr = queue_deq(qentry); > - > - if (buf_hdr == NULL) { > - odp_packet_t pkt; > - odp_buffer_t buf; > - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > - odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > - int pkts, i, j; > - > - pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > - QUEUE_MULTI_MAX); > - > - if (pkts > 0) { > - pkt = pkt_tbl[0]; > - buf = odp_buffer_from_packet(pkt); > - buf_hdr = odp_buf_to_hdr(buf); > - > - for (i = 1, j = 0; i < pkts; ++i) { > - buf = odp_buffer_from_packet(pkt_tbl[i]); > - tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf); > - } > - queue_enq_multi(qentry, tmp_hdr_tbl, j); > - } > - } > - > - return buf_hdr; > -} > - > -int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) > -{ > - /* Use default action */ > - return queue_enq_multi(qentry, buf_hdr, num); > -} > - > -int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) > -{ > - int nbr; > - > - nbr = queue_deq_multi(qentry, buf_hdr, num); > - > - if (nbr < num) { > - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > - odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > - odp_buffer_t buf; > - int pkts, i; > - > - pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > - QUEUE_MULTI_MAX); > - if (pkts > 0) { > - for (i = 0; i < pkts; ++i) { > - buf = odp_buffer_from_packet(pkt_tbl[i]); > - tmp_hdr_tbl[i] = odp_buf_to_hdr(buf); > - } > - queue_enq_multi(qentry, tmp_hdr_tbl, pkts); > - } > - } > - > - return nbr; > -} > diff --git a/platform/linux-dpdk/source/odp_queue.c b/platform/linux-dpdk/source/odp_queue.c > deleted file mode 100644 > index 554b8ea..0000000 > --- a/platform/linux-dpdk/source/odp_queue.c > +++ /dev/null > @@ -1,435 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -#include <odp_queue.h> > -#include <odp_queue_internal.h> > -#include <odp_std_types.h> > -#include <odp_align.h> > -#include <odp_buffer.h> > -#include <odp_buffer_internal.h> > -#include <odp_buffer_pool_internal.h> > -#include <odp_internal.h> > -#include <odp_shared_memory.h> > -#include <odp_schedule_internal.h> > -#include <odp_config.h> > -#include <odp_packet_io_internal.h> > -#include <odp_packet_io_queue.h> > -#include <odp_debug.h> > -#include <odp_hints.h> > - > -#ifdef USE_TICKETLOCK > -#include <odp_ticketlock.h> > -#define LOCK(a) odp_ticketlock_lock(a) > -#define UNLOCK(a) odp_ticketlock_unlock(a) > -#define LOCK_INIT(a) odp_ticketlock_init(a) > -#else > -#include <odp_spinlock.h> > -#define LOCK(a) odp_spinlock_lock(a) > -#define UNLOCK(a) odp_spinlock_unlock(a) > -#define LOCK_INIT(a) odp_spinlock_init(a) > -#endif > - > -#include <string.h> > - > - > -typedef struct queue_table_t { > - queue_entry_t queue[ODP_CONFIG_QUEUES]; > -} queue_table_t; > - > -static queue_table_t *queue_tbl; > - > - > -queue_entry_t *get_qentry(uint32_t queue_id) > -{ > - return &queue_tbl->queue[queue_id]; > -} > - > -static void queue_init(queue_entry_t *queue, const char *name, > - odp_queue_type_t type, odp_queue_param_t *param) > -{ > - strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1); > - queue->s.type = type; > - > - if (param) { > - memcpy(&queue->s.param, param, sizeof(odp_queue_param_t)); > - } else { > - /* Defaults */ > - memset(&queue->s.param, 0, sizeof(odp_queue_param_t)); > - queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT; > - queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT; > - queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT; > - } > - > - switch (type) { > - case ODP_QUEUE_TYPE_PKTIN: > - queue->s.enqueue = pktin_enqueue; > - queue->s.dequeue = pktin_dequeue; > - queue->s.enqueue_multi = pktin_enq_multi; > - queue->s.dequeue_multi = pktin_deq_multi; > - break; > - case ODP_QUEUE_TYPE_PKTOUT: > - queue->s.enqueue = pktout_enqueue; > - queue->s.dequeue = pktout_dequeue; > - queue->s.enqueue_multi = pktout_enq_multi; > - queue->s.dequeue_multi = pktout_deq_multi; > - break; > - default: > - queue->s.enqueue = queue_enq; > - queue->s.dequeue = queue_deq; > - queue->s.enqueue_multi = queue_enq_multi; > - queue->s.dequeue_multi = queue_deq_multi; > - break; > - } > - > - queue->s.head = NULL; > - queue->s.tail = NULL; > - queue->s.sched_buf = ODP_BUFFER_INVALID; > -} > - > - > -int odp_queue_init_global(void) > -{ > - uint32_t i; > - > - ODP_DBG("Queue init ... "); > - > - queue_tbl = odp_shm_reserve("odp_queues", > - sizeof(queue_table_t), > - sizeof(queue_entry_t)); > - > - if (queue_tbl == NULL) > - return -1; > - > - memset(queue_tbl, 0, sizeof(queue_table_t)); > - > - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > - /* init locks */ > - queue_entry_t *queue = get_qentry(i); > - LOCK_INIT(&queue->s.lock); > - queue->s.handle = queue_from_id(i); > - } > - > - ODP_DBG("done\n"); > - ODP_DBG("Queue init global\n"); > - ODP_DBG(" struct queue_entry_s size %zu\n", > - sizeof(struct queue_entry_s)); > - ODP_DBG(" queue_entry_t size %zu\n", > - sizeof(queue_entry_t)); > - ODP_DBG("\n"); > - > - return 0; > -} > - > -odp_queue_type_t odp_queue_type(odp_queue_t handle) > -{ > - queue_entry_t *queue; > - > - queue = queue_to_qentry(handle); > - > - return queue->s.type; > -} > - > -odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle) > -{ > - queue_entry_t *queue; > - > - queue = queue_to_qentry(handle); > - > - return queue->s.param.sched.sync; > -} > - > -odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type, > - odp_queue_param_t *param) > -{ > - uint32_t i; > - queue_entry_t *queue; > - odp_queue_t handle = ODP_QUEUE_INVALID; > - > - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > - queue = &queue_tbl->queue[i]; > - > - if (queue->s.status != QUEUE_STATUS_FREE) > - continue; > - > - LOCK(&queue->s.lock); > - if (queue->s.status == QUEUE_STATUS_FREE) { > - queue_init(queue, name, type, param); > - > - if (type == ODP_QUEUE_TYPE_SCHED || > - type == ODP_QUEUE_TYPE_PKTIN) > - queue->s.status = QUEUE_STATUS_NOTSCHED; > - else > - queue->s.status = QUEUE_STATUS_READY; > - > - handle = queue->s.handle; > - UNLOCK(&queue->s.lock); > - break; > - } > - UNLOCK(&queue->s.lock); > - } > - > - if (handle != ODP_QUEUE_INVALID && > - (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) { > - odp_buffer_t buf; > - > - buf = odp_schedule_buffer_alloc(handle); > - if (buf == ODP_BUFFER_INVALID) { > - ODP_ERR("queue_init: sched buf alloc failed\n"); > - return ODP_QUEUE_INVALID; > - } > - > - queue->s.sched_buf = buf; > - odp_schedule_mask_set(handle, queue->s.param.sched.prio); > - } > - > - return handle; > -} > - > - > -odp_buffer_t queue_sched_buf(odp_queue_t handle) > -{ > - queue_entry_t *queue; > - queue = queue_to_qentry(handle); > - > - return queue->s.sched_buf; > -} > - > - > -int queue_sched_atomic(odp_queue_t handle) > -{ > - queue_entry_t *queue; > - queue = queue_to_qentry(handle); > - > - return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC; > -} > - > - > -odp_queue_t odp_queue_lookup(const char *name) > -{ > - uint32_t i; > - > - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > - queue_entry_t *queue = &queue_tbl->queue[i]; > - > - if (queue->s.status == QUEUE_STATUS_FREE) > - continue; > - > - LOCK(&queue->s.lock); > - if (strcmp(name, queue->s.name) == 0) { > - /* found it */ > - UNLOCK(&queue->s.lock); > - return queue->s.handle; > - } > - UNLOCK(&queue->s.lock); > - } > - > - return ODP_QUEUE_INVALID; > -} > - > - > -int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr) > -{ > - int sched = 0; > - > - LOCK(&queue->s.lock); > - if (queue->s.head == NULL) { > - /* Empty queue */ > - queue->s.head = buf_hdr; > - queue->s.tail = buf_hdr; > - buf_hdr->pkt.next = NULL; > - } else { > - queue->s.tail->pkt.next = buf_hdr; > - queue->s.tail = buf_hdr; > - buf_hdr->pkt.next = NULL; > - } > - > - if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > - queue->s.status = QUEUE_STATUS_SCHED; > - sched = 1; /* retval: schedule queue */ > - } > - UNLOCK(&queue->s.lock); > - > - /* Add queue to scheduling */ > - if (sched == 1) > - odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); > - > - return 0; > -} > - > - > -int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) > -{ > - int sched = 0; > - int i; > - odp_buffer_hdr_t *tail; > - > - for (i = 0; i < num - 1; i++) > - buf_hdr[i]->pkt.next = buf_hdr[i+1]; > - > - tail = buf_hdr[num-1]; > - buf_hdr[num-1]->pkt.next = NULL; > - > - LOCK(&queue->s.lock); > - /* Empty queue */ > - if (queue->s.head == NULL) > - queue->s.head = buf_hdr[0]; > - else > - queue->s.tail->pkt.next = buf_hdr[0]; > - > - queue->s.tail = tail; > - > - if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > - queue->s.status = QUEUE_STATUS_SCHED; > - sched = 1; /* retval: schedule queue */ > - } > - UNLOCK(&queue->s.lock); > - > - /* Add queue to scheduling */ > - if (sched == 1) > - odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); > - > - return 0; > -} > - > - > -int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > -{ > - odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > - queue_entry_t *queue; > - int i; > - > - if (num > QUEUE_MULTI_MAX) > - num = QUEUE_MULTI_MAX; > - > - queue = queue_to_qentry(handle); > - > - for (i = 0; i < num; i++) > - buf_hdr[i] = odp_buf_to_hdr(buf[i]); > - > - return queue->s.enqueue_multi(queue, buf_hdr, num); > -} > - > - > -int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf) > -{ > - odp_buffer_hdr_t *buf_hdr; > - queue_entry_t *queue; > - > - queue = queue_to_qentry(handle); > - buf_hdr = odp_buf_to_hdr(buf); > - > - return queue->s.enqueue(queue, buf_hdr); > -} > - > - > -odp_buffer_hdr_t *queue_deq(queue_entry_t *queue) > -{ > - odp_buffer_hdr_t *buf_hdr = NULL; > - > - LOCK(&queue->s.lock); > - > - if (queue->s.head == NULL) { > - /* Already empty queue */ > - if (queue->s.status == QUEUE_STATUS_SCHED && > - queue->s.type != ODP_QUEUE_TYPE_PKTIN) > - queue->s.status = QUEUE_STATUS_NOTSCHED; > - } else { > - buf_hdr = queue->s.head; > - queue->s.head = buf_hdr->pkt.next; > - buf_hdr->pkt.next = NULL; > - > - if (queue->s.head == NULL) { > - /* Queue is now empty */ > - queue->s.tail = NULL; > - } > - } > - > - UNLOCK(&queue->s.lock); > - > - return buf_hdr; > -} > - > - > -int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) > -{ > - int i = 0; > - > - LOCK(&queue->s.lock); > - > - if (queue->s.head == NULL) { > - /* Already empty queue */ > - if (queue->s.status == QUEUE_STATUS_SCHED && > - queue->s.type != ODP_QUEUE_TYPE_PKTIN) > - queue->s.status = QUEUE_STATUS_NOTSCHED; > - } else { > - odp_buffer_hdr_t *hdr = queue->s.head; > - > - for (; i < num && hdr; i++) { > - buf_hdr[i] = hdr; > - /* odp_prefetch(hdr->addr); */ > - hdr = hdr->pkt.next; > - buf_hdr[i]->pkt.next = NULL; > - } > - > - queue->s.head = hdr; > - > - if (hdr == NULL) { > - /* Queue is now empty */ > - queue->s.tail = NULL; > - } > - } > - > - UNLOCK(&queue->s.lock); > - > - return i; > -} > - > - > -int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > -{ > - queue_entry_t *queue; > - odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > - int i, ret; > - > - if (num > QUEUE_MULTI_MAX) > - num = QUEUE_MULTI_MAX; > - > - queue = queue_to_qentry(handle); > - > - ret = queue->s.dequeue_multi(queue, buf_hdr, num); > - > - for (i = 0; i < ret; i++) > - buf[i] = (odp_buffer_t) buf_hdr[i]; > - > - return ret; > -} > - > - > -odp_buffer_t odp_queue_deq(odp_queue_t handle) > -{ > - queue_entry_t *queue; > - odp_buffer_hdr_t *buf_hdr; > - > - queue = queue_to_qentry(handle); > - buf_hdr = queue->s.dequeue(queue); > - > - if (buf_hdr) > - return (odp_buffer_t) buf_hdr; > - > - return ODP_BUFFER_INVALID; > -} > - > - > -void queue_lock(queue_entry_t *queue) > -{ > - LOCK(&queue->s.lock); > -} > - > - > -void queue_unlock(queue_entry_t *queue) > -{ > - UNLOCK(&queue->s.lock); > -} > -- > 1.9.1 > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp
On 14 July 2014 15:11, Anders Roxell <anders.roxell@linaro.org> wrote: > On 2014-07-12 00:05, venkatesh.vivekanandan@linaro.org wrote: > > From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> > > > > - Made ODP_BUFFER_<TYPES> consistent with linux-generic. > > - Removed odp_buffer_is_scatter API to be inline with linux-generic. > > - Added platform/linux-dpdk/odp_linux.c to supply the function > > and argument to the pthread created by dpdk. > > > > To compile: > > ---------- > > - Edit configure.ac and modify with_platform=linux-dpdk > > why edit? > > ./bootstrap > ./configure --with-platform=linux-dpdk > Yeah, I will fix them and send out patch v2 . make > > that should work... > > Cheers, > Anders > > > * ./bootstrap > > * ./configure > > * make clean > > * make > > > > Commands to test: > > ---------------- > > l2fwding app - ./test/l2fwd/odp_l2fwd -i 0,1 -t 5 -m 0 -c 2 > > loopback app - ./test/packet/odp_pktio -i 0,1 -t 5 -m 0 -c 2 > > > > -i 0,1 - is the interface number > > -t 5 - is the dpdk type > > -m 0 - is the burst mode > > -c 2 - is the number of cpus > > > > Signed-off-by: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org > > > > --- > > configure.ac | 2 + > > platform/linux-dpdk/Makefile | 158 -------- > > platform/linux-dpdk/Makefile.am | 100 +++++ > > platform/linux-dpdk/Makefile.inc | 7 - > > platform/linux-dpdk/include/api/odp_buffer.h | 17 +- > > platform/linux-dpdk/odp_buffer.c | 91 +++++ > > platform/linux-dpdk/odp_buffer_pool.c | 156 ++++++++ > > platform/linux-dpdk/odp_init.c | 113 ++++++ > > platform/linux-dpdk/odp_linux.c | 96 +++++ > > platform/linux-dpdk/odp_packet.c | 374 ++++++++++++++++++ > > platform/linux-dpdk/odp_packet_dpdk.c | 189 +++++++++ > > platform/linux-dpdk/odp_packet_io.c | 561 > +++++++++++++++++++++++++++ > > platform/linux-dpdk/odp_queue.c | 435 +++++++++++++++++++++ > > platform/linux-dpdk/source/odp_buffer.c | 102 ----- > > platform/linux-dpdk/source/odp_buffer_pool.c | 156 -------- > > platform/linux-dpdk/source/odp_init.c | 113 ------ > > platform/linux-dpdk/source/odp_packet.c | 374 ------------------ > > platform/linux-dpdk/source/odp_packet_dpdk.c | 177 --------- > > platform/linux-dpdk/source/odp_packet_io.c | 561 > --------------------------- > > platform/linux-dpdk/source/odp_queue.c | 435 --------------------- > > 20 files changed, 2122 insertions(+), 2095 deletions(-) > > delete mode 100644 platform/linux-dpdk/Makefile > > create mode 100644 platform/linux-dpdk/Makefile.am > > delete mode 100644 platform/linux-dpdk/Makefile.inc > > create mode 100644 platform/linux-dpdk/odp_buffer.c > > create mode 100644 platform/linux-dpdk/odp_buffer_pool.c > > create mode 100644 platform/linux-dpdk/odp_init.c > > create mode 100644 platform/linux-dpdk/odp_linux.c > > create mode 100644 platform/linux-dpdk/odp_packet.c > > create mode 100644 platform/linux-dpdk/odp_packet_dpdk.c > > create mode 100644 platform/linux-dpdk/odp_packet_io.c > > create mode 100644 platform/linux-dpdk/odp_queue.c > > delete mode 100644 platform/linux-dpdk/source/odp_buffer.c > > delete mode 100644 platform/linux-dpdk/source/odp_buffer_pool.c > > delete mode 100644 platform/linux-dpdk/source/odp_init.c > > delete mode 100644 platform/linux-dpdk/source/odp_packet.c > > delete mode 100644 platform/linux-dpdk/source/odp_packet_dpdk.c > > delete mode 100644 platform/linux-dpdk/source/odp_packet_io.c > > delete mode 100644 platform/linux-dpdk/source/odp_queue.c > > > > diff --git a/configure.ac b/configure.ac > > index 873ea9e..3d8481f 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -51,6 +51,7 @@ AC_ARG_WITH([platform], > > > > AM_CONDITIONAL([ODP_PLATFORM_GENERIC], [test "x$with_platform" = > xlinux-generic]) > > AM_CONDITIONAL([ODP_PLATFORM_KEYSTONE2], [test "x$with_platform" = > xlinux-keystone2]) > > +AM_CONDITIONAL([ODP_PLATFORM_DPDK], [test "x$with_platform" = > xlinux-dpdk]) > > > > AC_SUBST([with_platform]) > > > > @@ -111,6 +112,7 @@ AC_CONFIG_FILES([Makefile > > platform/Makefile > > platform/linux-generic/Makefile > > platform/linux-keystone2/Makefile > > + platform/linux-dpdk/Makefile > > test/Makefile > > test/api_test/Makefile > > test/example/Makefile > > diff --git a/platform/linux-dpdk/Makefile b/platform/linux-dpdk/Makefile > > deleted file mode 100644 > > index bf8d0b3..0000000 > > --- a/platform/linux-dpdk/Makefile > > +++ /dev/null > > @@ -1,158 +0,0 @@ > > -## Copyright (c) 2013, Linaro Limited > > -## All rights reserved. > > -## > > -## Redistribution and use in source and binary forms, with or without > > -## modification, are permitted provided that the following conditions > are met: > > -## > > -## * Redistributions of source code must retain the above copyright > notice, this > > -## list of conditions and the following disclaimer. > > -## > > -## * Redistributions in binary form must reproduce the above > copyright notice, this > > -## list of conditions and the following disclaimer in the > documentation and/or > > -## other materials provided with the distribution. > > -## > > -## * Neither the name of Linaro Limited nor the names of its > contributors may be > > -## used to endorse or promote products derived from this software > without specific > > -## prior written permission. > > -## > > -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" AND > > -## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE IMPLIED > > -## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > ARE > > -## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE LIABLE > > -## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL > > -## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR > > -## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER > > -## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, > > -## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT > OF THE USE > > -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > > - > > -.DEFAULT_GOAL := libs > > - > > -ODP_ROOT = ../.. > > -LIB_DIR = ./lib > > -DOC_DIR = ./doc > > - > > -LINUX_GENERIC_DIR = ../linux-generic > > - > > -RTE_SDK ?= $(abspath $(ODP_ROOT)/../dpdk) > > -RTE_OUTPUT ?= $(abspath $(RTE_SDK)/build) > > -RTE_LIB ?= $(abspath $(RTE_OUTPUT)/lib/libintel_dpdk.a) > > - > > -PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h > > -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include > > -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch > > -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env > > -PLAT_CFLAGS += -msse4.2 > > - > > -EXTRA_CFLAGS += $(PLAT_CFLAGS) > > -EXTRA_CFLAGS += -I./include > > -EXTRA_CFLAGS += -I./include/api > > -EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include > > -EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include/api > > -EXTRA_CFLAGS += -I$(ODP_ROOT)/include > > - > > -include $(ODP_ROOT)/Makefile.inc > > -STATIC_LIB = ./lib/libodp.a > > - > > -# > > -# Object files > > -# > > -OBJS = > > -OBJS += $(OBJ_DIR)/odp_barrier.o > > -OBJS += $(OBJ_DIR)/odp_buffer.o > > -OBJS += $(OBJ_DIR)/odp_buffer_pool.o > > -OBJS += $(OBJ_DIR)/odp_coremask.o > > -OBJS += $(OBJ_DIR)/odp_init.o > > -OBJS += $(OBJ_DIR)/odp_linux.o > > -OBJS += $(OBJ_DIR)/odp_packet.o > > -OBJS += $(OBJ_DIR)/odp_packet_flags.o > > -OBJS += $(OBJ_DIR)/odp_packet_io.o > > -OBJS += $(OBJ_DIR)/odp_packet_socket.o > > -OBJS += $(OBJ_DIR)/odp_queue.o > > -OBJS += $(OBJ_DIR)/odp_schedule.o > > -OBJS += $(OBJ_DIR)/odp_shared_memory.o > > -OBJS += $(OBJ_DIR)/odp_spinlock.o > > -OBJS += $(OBJ_DIR)/odp_system_info.o > > -OBJS += $(OBJ_DIR)/odp_thread.o > > -OBJS += $(OBJ_DIR)/odp_ticketlock.o > > -OBJS += $(OBJ_DIR)/odp_time.o > > -OBJS += $(OBJ_DIR)/odp_timer.o > > -OBJS += $(OBJ_DIR)/odp_ring.o > > -OBJS += $(OBJ_DIR)/odp_rwlock.o > > -OBJS += $(OBJ_DIR)/odp_packet_dpdk.o > > - > > -DEPS = $(OBJS:.o=.d) > > - > > -.PHONY: all > > -all: libs docs > > - > > --include $(DEPS) > > - > > -#$(OBJ_DIR): > > -# $(MKDIR) $(OBJ_DIR) > > - > > -$(LIB_DIR): > > - $(MKDIR) $(LIB_DIR) > > - > > -$(DOC_DIR): > > - $(MKDIR) $(DOC_DIR)/html > > - $(MKDIR) $(DOC_DIR)/latex > > - > > -# > > -# Compile rules > > -# > > -vpath %.c source:$(LINUX_GENERIC_DIR)/source > > - > > -$(OBJ_DIR)/%.o: %.c > > - $(ECHO) " CC $<" > > - $(CC) -c -MD $(EXTRA_CFLAGS) $(CFLAGS) -o $@ $< > > - > > -# > > -# Lib rule > > -# > > -$(OBJ_DIR)/libodp.o: $(OBJS) > > - $(ECHO) " LD $@" > > - $(LD) -r -o $@ $(OBJS) $(RTE_LIB) > > - > > -$(STATIC_LIB): $(OBJ_DIR)/libodp.o > > - $(ECHO) " AR $@" > > - $(AR) -cr $@ $(OBJ_DIR)/libodp.o > > - > > - > > -clean: > > - $(RMDIR) $(OBJ_DIR) > > - $(RMDIR) $(LIB_DIR) > > - $(RMDIR) $(DOC_DIR) > > - $(RM) Doxyfile > > - > > -Doxyfile: Doxyfile.in > > - doxygen -u - < $< > $@ > > - > > -.PHONY: docs > > -docs: $(DOC_DIR) Doxyfile ./include/odp*.h > > - doxygen > > - > > -.PHONY: docs_install > > -docs_install: docs > > - $(COPY) doc $(DESTDIR) > > - > > -.PHONY: pdf > > -pdf: docs > > - make --directory doc/latex refman.pdf 1> /dev/null > > - > > -.PHONY: libs > > -libs: $(OBJ_DIR) $(LIB_DIR) $(STATIC_LIB) > > - > > -.PHONY: lib_install > > -lib_install: libs > > - install -d $(DESTDIR)/lib > > - install -m 0644 ${STATIC_LIB} $(DESTDIR)/lib/ > > - > > -.PHONY: headers_install > > -headers_install: libs > > - $(ECHO) Installing headers to $(DESTDIR)/include > > - $(COPY) $(ODP_ROOT)/include $(DESTDIR) > > - $(COPY) $(LINUX_GENERIC_DIR)/include/api/* $(DESTDIR)/include/ > > - $(COPY) include/api/* $(DESTDIR)/include/ > > - > > -install: lib_install headers_install > > diff --git a/platform/linux-dpdk/Makefile.am > b/platform/linux-dpdk/Makefile.am > > new file mode 100644 > > index 0000000..067c0bb > > --- /dev/null > > +++ b/platform/linux-dpdk/Makefile.am > > @@ -0,0 +1,100 @@ > > +include $(top_srcdir)/Makefile.inc > > +LIB = $(top_builddir)/lib > > + > > +dist_pkgdata_DATA = $(LIB)/libodp.la > > + > > +pkgconfigdir = pkgconfig > > +nodist_pkgconfig_DATA = $(top_builddir)/pkgconfig/libodp.pc > > + > > +.PHONY: pkgconfig/libodp.pc > > + > > +RTE_SDK ?= $(top_srcdir)/../dpdk > > +RTE_OUTPUT ?= $(RTE_SDK)/build > > +RTE_LIB ?= $(RTE_OUTPUT)/lib > > + > > +PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h > > +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include > > +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch > > +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env > > +PLAT_CFLAGS += -msse4.2 > > + > > +AM_CFLAGS += $(PLAT_CFLAGS) > > +AM_CFLAGS += -I$(srcdir)/include > > +AM_CFLAGS += -I$(srcdir)/include/api > > +AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include > > +AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include/api > > +AM_CFLAGS += -I$(top_srcdir)/include > > + > > +AM_LDFLAGS += -L$(RTE_LIB) > > +VPATH = $(srcdir) $(builddir) > > +if ODP_PLATFORM_DPDK > > +lib_LTLIBRARIES = $(LIB)/libodp.la > > +DPDK_LIBS="-lintel_dpdk -ldl" > > +LIBS += $(DPDK_LIBS) > > + > > +include_HEADERS = \ > > + > $(top_srcdir)/platform/linux-dpdk/include/api/odp_buffer.h \ > > + $(top_srcdir)/include/odp.h \ > > + $(top_srcdir)/include/odp_align.h \ > > + $(top_srcdir)/include/odp_atomic.h \ > > + $(top_srcdir)/include/odp_barrier.h \ > > + $(top_srcdir)/include/odp_buffer_pool.h \ > > + $(top_srcdir)/include/odp_byteorder.h \ > > + $(top_srcdir)/include/odp_compiler.h \ > > + $(top_srcdir)/include/odp_config.h \ > > + $(top_srcdir)/include/odp_coremask.h \ > > + $(top_srcdir)/include/odp_debug.h \ > > + $(top_srcdir)/include/odp_hints.h \ > > + $(top_srcdir)/include/odp_init.h \ > > + $(top_srcdir)/include/odp_packet_flags.h \ > > + $(top_srcdir)/include/odp_packet.h \ > > + $(top_srcdir)/include/odp_packet_io.h \ > > + $(top_srcdir)/include/odp_queue.h \ > > + $(top_srcdir)/include/odp_rwlock.h \ > > + $(top_srcdir)/include/odp_schedule.h \ > > + $(top_srcdir)/include/odp_shared_memory.h \ > > + $(top_srcdir)/include/odp_spinlock.h \ > > + $(top_srcdir)/include/odp_std_types.h \ > > + $(top_srcdir)/include/odp_sync.h \ > > + $(top_srcdir)/include/odp_system_info.h \ > > + $(top_srcdir)/include/odp_thread.h \ > > + $(top_srcdir)/include/odp_ticketlock.h \ > > + $(top_srcdir)/include/odp_time.h \ > > + $(top_srcdir)/include/odp_timer.h \ > > + $(top_srcdir)/include/odp_version.h > > + > > +subdirheadersdir = $(includedir)/helper > > +subdirheaders_HEADERS = \ > > + $(top_srcdir)/include/helper/odp_chksum.h \ > > + $(top_srcdir)/include/helper/odp_eth.h \ > > + $(top_srcdir)/include/helper/odp_ip.h \ > > + $(top_srcdir)/include/helper/odp_linux.h \ > > + $(top_srcdir)/include/helper/odp_packet_helper.h \ > > + $(top_srcdir)/include/helper/odp_ring.h \ > > + $(top_srcdir)/include/helper/odp_udp.h > > + > > +__LIB__libodp_la_SOURCES = \ > > + ../linux-generic/odp_barrier.c \ > > + odp_buffer.c \ > > + odp_buffer_pool.c \ > > + ../linux-generic/odp_coremask.c \ > > + odp_init.c \ > > + odp_linux.c \ > > + odp_packet.c \ > > + odp_packet_dpdk.c \ > > + ../linux-generic/odp_packet_flags.c \ > > + odp_packet_io.c \ > > + ../linux-generic/odp_packet_socket.c \ > > + odp_queue.c \ > > + ../linux-generic/odp_ring.c \ > > + ../linux-generic/odp_rwlock.c \ > > + ../linux-generic/odp_schedule.c \ > > + ../linux-generic/odp_shared_memory.c \ > > + ../linux-generic/odp_spinlock.c \ > > + ../linux-generic/odp_system_info.c \ > > + ../linux-generic/odp_thread.c \ > > + ../linux-generic/odp_ticketlock.c \ > > + ../linux-generic/odp_time.c \ > > + ../linux-generic/odp_timer.c > > + > > +endif > > diff --git a/platform/linux-dpdk/Makefile.inc > b/platform/linux-dpdk/Makefile.inc > > deleted file mode 100644 > > index fe7679b..0000000 > > --- a/platform/linux-dpdk/Makefile.inc > > +++ /dev/null > > @@ -1,7 +0,0 @@ > > -# Copyright (c) 2013, Linaro Limited > > -# All rights reserved. > > -# > > -# SPDX-License-Identifier: BSD-3-Clause > > - > > -STD_LIBS += -ldl > > - > > diff --git a/platform/linux-dpdk/include/api/odp_buffer.h > b/platform/linux-dpdk/include/api/odp_buffer.h > > index 286d9e6..9ea1ed8 100644 > > --- a/platform/linux-dpdk/include/api/odp_buffer.h > > +++ b/platform/linux-dpdk/include/api/odp_buffer.h > > @@ -63,18 +63,11 @@ size_t odp_buffer_size(odp_buffer_t buf); > > int odp_buffer_type(odp_buffer_t buf); > > > > #define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */ > > -#define ODP_BUFFER_TYPE_RAW 0 /**< Raw buffer */ > > -#define ODP_BUFFER_TYPE_PACKET 1 /**< Packet buffer */ > > -#define ODP_BUFFER_TYPE_TIMER 2 /**< Timer buffer */ > > - > > -/** > > - * Tests if buffer is part of a scatter/gather list > > - * > > - * @param buf Buffer handle > > - * > > - * @return 1 if belongs to a scatter list, otherwise 0 > > - */ > > -int odp_buffer_is_scatter(odp_buffer_t buf); > > +#define ODP_BUFFER_TYPE_ANY 0 /**< Buffer that can hold any other > > + buffer type */ > > +#define ODP_BUFFER_TYPE_RAW 1 /**< Raw buffer, no additional > metadata */ > > +#define ODP_BUFFER_TYPE_PACKET 2 /**< Packet buffer */ > > +#define ODP_BUFFER_TYPE_TIMEOUT 3 /**< Timeout buffer */ > > > > /** > > * Tests if buffer is valid > > diff --git a/platform/linux-dpdk/odp_buffer.c > b/platform/linux-dpdk/odp_buffer.c > > new file mode 100644 > > index 0000000..133658f > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_buffer.c > > @@ -0,0 +1,91 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#include <odp_buffer.h> > > +#include <odp_buffer_internal.h> > > +#include <odp_buffer_pool_internal.h> > > + > > +#include <string.h> > > +#include <stdio.h> > > + > > + > > +void *odp_buffer_addr(odp_buffer_t buf) > > +{ > > + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > > + > > + return hdr->buf_addr; > > +} > > + > > + > > +size_t odp_buffer_size(odp_buffer_t buf) > > +{ > > + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > > + > > + return hdr->buf_len; > > +} > > + > > + > > +int odp_buffer_type(odp_buffer_t buf) > > +{ > > + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > > + > > + return hdr->type; > > +} > > + > > + > > +int odp_buffer_is_valid(odp_buffer_t buf) > > +{ > > + odp_buffer_bits_t handle; > > + > > + handle.u32 = buf; > > + > > + return (handle.index != ODP_BUFFER_INVALID_INDEX); > > +} > > + > > + > > +int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) > > +{ > > + odp_buffer_hdr_t *hdr; > > + int len = 0; > > + > > + if (!odp_buffer_is_valid(buf)) { > > + printf("Buffer is not valid.\n"); > > + return len; > > + } > > + > > + hdr = odp_buf_to_hdr(buf); > > + > > + len += snprintf(&str[len], n-len, > > + "Buffer\n"); > > + len += snprintf(&str[len], n-len, > > + " pool %"PRIu64"\n", (int64_t) hdr->pool); > > + len += snprintf(&str[len], n-len, > > + " phy_addr %"PRIu64"\n", hdr->buf_physaddr); > > + len += snprintf(&str[len], n-len, > > + " addr %p\n", hdr->buf_addr); > > + len += snprintf(&str[len], n-len, > > + " size %u\n", hdr->buf_len); > > + len += snprintf(&str[len], n-len, > > + " ref_count %i\n", hdr->refcnt); > > + len += snprintf(&str[len], n-len, > > + " type %i\n", hdr->type); > > + > > + return len; > > +} > > + > > + > > +void odp_buffer_print(odp_buffer_t buf) > > +{ > > + int max_len = 512; > > + char str[max_len]; > > + int len; > > + > > + len = odp_buffer_snprint(str, max_len-1, buf); > > + str[len] = 0; > > + > > + printf("\n%s\n", str); > > +} > > + > > diff --git a/platform/linux-dpdk/odp_buffer_pool.c > b/platform/linux-dpdk/odp_buffer_pool.c > > new file mode 100644 > > index 0000000..de90275 > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_buffer_pool.c > > @@ -0,0 +1,156 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#include <odp_std_types.h> > > +#include <odp_buffer_pool.h> > > +#include <odp_buffer_pool_internal.h> > > +#include <odp_buffer_internal.h> > > +#include <odp_packet_internal.h> > > +#include <odp_shared_memory.h> > > +#include <odp_align.h> > > +#include <odp_internal.h> > > +#include <odp_config.h> > > +#include <odp_hints.h> > > +#include <odp_debug.h> > > + > > +#include <string.h> > > +#include <stdlib.h> > > + > > +/* for DPDK */ > > +#include <odp_packet_dpdk.h> > > + > > +#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + > RTE_PKTMBUF_HEADROOM) > > +#define NB_MBUF 8192 > > + > > +#ifdef POOL_USE_TICKETLOCK > > +#include <odp_ticketlock.h> > > +#define LOCK(a) odp_ticketlock_lock(a) > > +#define UNLOCK(a) odp_ticketlock_unlock(a) > > +#define LOCK_INIT(a) odp_ticketlock_init(a) > > +#else > > +#include <odp_spinlock.h> > > +#define LOCK(a) odp_spinlock_lock(a) > > +#define UNLOCK(a) odp_spinlock_unlock(a) > > +#define LOCK_INIT(a) odp_spinlock_init(a) > > +#endif > > + > > + > > +#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > > +#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > > +#endif > > + > > +#define NULL_INDEX ((uint32_t)-1) > > + > > + > > +typedef union pool_entry_u { > > + struct pool_entry_s s; > > + > > + uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct > pool_entry_s))]; > > + > > +} pool_entry_t; > > + > > + > > +typedef struct pool_table_t { > > + pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS]; > > + > > +} pool_table_t; > > + > > + > > +/* The pool table */ > > +static pool_table_t *pool_tbl; > > + > > +/* Pool entry pointers (for inlining) */ > > +void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS]; > > + > > + > > +int odp_buffer_pool_init_global(void) > > +{ > > + odp_buffer_pool_t i; > > + > > + pool_tbl = odp_shm_reserve("odp_buffer_pools", > > + sizeof(pool_table_t), > > + sizeof(pool_entry_t)); > > + > > + if (pool_tbl == NULL) > > + return -1; > > + > > + memset(pool_tbl, 0, sizeof(pool_table_t)); > > + > > + > > + for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) { > > + /* init locks */ > > + pool_entry_t *pool = &pool_tbl->pool[i]; > > + LOCK_INIT(&pool->s.lock); > > + pool->s.pool = i; > > + > > + pool_entry_ptr[i] = pool; > > + } > > + > > + ODP_DBG("\nBuffer pool init global\n"); > > + ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct > pool_entry_s)); > > + ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t)); > > + ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t)); > > + ODP_DBG("\n"); > > + > > + return 0; > > +} > > + > > + > > +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; > > + 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, 32, > > + sizeof(struct rte_pktmbuf_pool_private), > > + rte_pktmbuf_pool_init, NULL, > > + rte_pktmbuf_init, NULL, > > + rte_socket_id(), 0); > > + if (pktmbuf_pool == NULL) { > > + ODP_ERR("Cannot init DPDK mbuf pool\n"); > > + return -1; > > + } > > + > > + return (odp_buffer_pool_t) pktmbuf_pool; > > +} > > + > > + > > +odp_buffer_pool_t odp_buffer_pool_lookup(const char *name) > > +{ > > + struct rte_mempool *mp = NULL; > > + > > + mp = rte_mempool_lookup(name); > > + if (mp == NULL) > > + return ODP_BUFFER_POOL_INVALID; > > + > > + return (odp_buffer_pool_t)mp; > > +} > > + > > + > > +odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id) > > +{ > > + return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool > *)pool_id); > > +} > > + > > + > > +void odp_buffer_free(odp_buffer_t buf) > > +{ > > + rte_pktmbuf_free((struct rte_mbuf *)buf); > > +} > > + > > + > > +void odp_buffer_pool_print(odp_buffer_pool_t pool_id) > > +{ > > + rte_mempool_dump((const struct rte_mempool *)pool_id); > > +} > > diff --git a/platform/linux-dpdk/odp_init.c > b/platform/linux-dpdk/odp_init.c > > new file mode 100644 > > index 0000000..ecc2066 > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_init.c > > @@ -0,0 +1,113 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#include <odp_init.h> > > +#include <odp_internal.h> > > +#include <odp_debug.h> > > +#include <odp_packet_dpdk.h> > > + > > +int odp_init_dpdk(void) > > +{ > > + int test_argc = 5; > > + char *test_argv[6]; > > + int core_count, i, num_cores = 0; > > + char core_mask[8]; > > + > > + core_count = odp_sys_core_count(); > > + for (i = 0; i < core_count; i++) > > + num_cores += (0x1 << i); > > + sprintf(core_mask, "%x", num_cores); > > + > > + test_argv[0] = malloc(sizeof("odp_dpdk")); > > + strcpy(test_argv[0], "odp_dpdk"); > > + test_argv[1] = malloc(sizeof("-c")); > > + strcpy(test_argv[1], "-c"); > > + test_argv[2] = malloc(sizeof(core_mask)); > > + strcpy(test_argv[2], core_mask); > > + test_argv[3] = malloc(sizeof("-n")); > > + strcpy(test_argv[3], "-n"); > > + test_argv[4] = malloc(sizeof("3")); > > + strcpy(test_argv[4], "3"); > > + > > + if (rte_eal_init(test_argc, (char **)test_argv) < 0) { > > + ODP_ERR("Cannot init the Intel DPDK EAL!"); > > + return -1; > > + } > > + > > + if (rte_pmd_init_all() < 0) { > > + ODP_ERR("Cannot init pmd\n"); > > + return -1; > > + } > > + > > + if (rte_eal_pci_probe() < 0) { > > + ODP_ERR("Cannot probe PCI\n"); > > + return -1; > > + } > > + > > + return 0; > > +} > > + > > +int odp_init_global(void) > > +{ > > + odp_thread_init_global(); > > + > > + odp_system_info_init(); > > + > > + if (odp_init_dpdk()) { > > + ODP_ERR("ODP dpdk init failed.\n"); > > + return -1; > > + } > > + > > + if (odp_shm_init_global()) { > > + ODP_ERR("ODP shm init failed.\n"); > > + return -1; > > + } > > + > > + if (odp_buffer_pool_init_global()) { > > + ODP_ERR("ODP buffer pool init failed.\n"); > > + return -1; > > + } > > + > > + if (odp_queue_init_global()) { > > + ODP_ERR("ODP queue init failed.\n"); > > + return -1; > > + } > > + > > + if (odp_schedule_init_global()) { > > + ODP_ERR("ODP schedule init failed.\n"); > > + return -1; > > + } > > + > > + if (odp_pktio_init_global()) { > > + ODP_ERR("ODP packet io init failed.\n"); > > + return -1; > > + } > > + > > + if (odp_timer_init_global()) { > > + ODP_ERR("ODP timer init failed.\n"); > > + return -1; > > + } > > + > > + return 0; > > +} > > + > > + > > +int odp_init_local(int thr_id) > > +{ > > + odp_thread_init_local(thr_id); > > + > > + if (odp_pktio_init_local()) { > > + ODP_ERR("ODP packet io local init failed.\n"); > > + return -1; > > + } > > + > > + if (odp_schedule_init_local()) { > > + ODP_ERR("ODP schedule local init failed.\n"); > > + return -1; > > + } > > + > > + return 0; > > +} > > diff --git a/platform/linux-dpdk/odp_linux.c > b/platform/linux-dpdk/odp_linux.c > > new file mode 100644 > > index 0000000..067bd99 > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_linux.c > > @@ -0,0 +1,96 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#ifndef _GNU_SOURCE > > +#define _GNU_SOURCE > > +#endif > > +#include <sched.h> > > + > > +#include <stdlib.h> > > +#include <string.h> > > +#include <stdio.h> > > +#include <assert.h> > > + > > +#include <helper/odp_linux.h> > > +#include <odp_internal.h> > > +#include <odp_thread.h> > > +#include <odp_init.h> > > +#include <odp_system_info.h> > > + > > +#include <rte_lcore.h> > > + > > +typedef struct { > > + int thr_id; > > + void *(*start_routine) (void *); > > + void *arg; > > + > > +} odp_start_args_t; > > + > > + > > +static void *odp_run_start_routine(void *arg) > > +{ > > + odp_start_args_t *start_args = arg; > > + > > + /* ODP thread local init */ > > + odp_init_local(start_args->thr_id); > > + > > + return start_args->start_routine(start_args->arg); > > +} > > + > > + > > +void odp_linux_pthread_create(odp_linux_pthread_t *thread_tbl, int num, > > + int first_core, void *(*start_routine) (void *), void *arg) > > +{ > > + int i; > > + cpu_set_t cpu_set; > > + odp_start_args_t *start_args; > > + int core_count; > > + int cpu; > > + > > + (void) cpu_set; > > + (void) thread_tbl; > > + > > + core_count = odp_sys_core_count(); > > + > > + assert((first_core >= 0) && (first_core < core_count)); > > + assert((num >= 0) && (num <= core_count)); > > + > > + for (i = 0; i < num; i++) { > > + cpu = (first_core + i) % core_count; > > + > > + start_args = malloc(sizeof(odp_start_args_t)); > > + memset(start_args, 0, sizeof(odp_start_args_t)); > > + start_args->start_routine = start_routine; > > + start_args->arg = arg; > > + > > + odp_thread_create(cpu); > > + start_args->thr_id = cpu; > > + /* If not master core */ > > + if (cpu != 0) { > > + rte_eal_remote_launch( > > + (int(*)(void *))odp_run_start_routine, > > + start_args, cpu); > > + } else { > > + lcore_config[cpu].ret = (int)(uint64_t) > > + odp_run_start_routine(start_args); > > + lcore_config[cpu].state = FINISHED; > > + } > > + } > > +} > > + > > + > > +void odp_linux_pthread_join(odp_linux_pthread_t *thread_tbl, int num) > > +{ > > + uint32_t lcore_id; > > + > > + (void) thread_tbl; > > + (void) num; > > + > > + RTE_LCORE_FOREACH_SLAVE(lcore_id) { > > + if (rte_eal_wait_lcore(lcore_id) < 0) > > + return; > > + } > > +} > > diff --git a/platform/linux-dpdk/odp_packet.c > b/platform/linux-dpdk/odp_packet.c > > new file mode 100644 > > index 0000000..c34e626 > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_packet.c > > @@ -0,0 +1,374 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#include <odp_packet.h> > > +#include <odp_packet_internal.h> > > +#include <odp_hints.h> > > +#include <odp_byteorder.h> > > + > > +#include <helper/odp_eth.h> > > +#include <helper/odp_ip.h> > > + > > +#include <string.h> > > +#include <stdio.h> > > + > > +static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, > odp_ipv4hdr_t *ipv4, > > + size_t *offset_out); > > +static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, > odp_ipv6hdr_t *ipv6, > > + size_t *offset_out); > > + > > +void odp_packet_init(odp_packet_t pkt) > > +{ > > + odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > > + const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, > buf_hdr); > > + uint8_t *start; > > + size_t len; > > + > > + start = (uint8_t *)pkt_hdr + start_offset; > > + len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > > + memset(start, 0, len); > > + > > + pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > > + pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > > + pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > > +} > > + > > +odp_packet_t odp_packet_from_buffer(odp_buffer_t buf) > > +{ > > + return (odp_packet_t)buf; > > +} > > + > > +odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt) > > +{ > > + return (odp_buffer_t)pkt; > > +} > > + > > +void odp_packet_set_len(odp_packet_t pkt, size_t len) > > +{ > > + /* for rte_pktmbuf */ > > + odp_buffer_hdr_t *buf_hdr = > odp_buf_to_hdr(odp_buffer_from_packet(pkt)); > > + buf_hdr->pkt.data_len = len; > > + > > + odp_packet_hdr(pkt)->frame_len = len; > > +} > > + > > +size_t odp_packet_get_len(odp_packet_t pkt) > > +{ > > + return odp_packet_hdr(pkt)->frame_len; > > +} > > + > > +uint8_t *odp_packet_buf_addr(odp_packet_t pkt) > > +{ > > + return odp_buffer_addr(odp_buffer_from_packet(pkt)); > > +} > > + > > +uint8_t *odp_packet_start(odp_packet_t pkt) > > +{ > > + return odp_packet_buf_addr(pkt) + > odp_packet_hdr(pkt)->frame_offset; > > +} > > + > > + > > +uint8_t *odp_packet_l2(odp_packet_t pkt) > > +{ > > + const size_t offset = odp_packet_l2_offset(pkt); > > + > > + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > > + return NULL; > > + > > + return odp_packet_buf_addr(pkt) + offset; > > +} > > + > > +size_t odp_packet_l2_offset(odp_packet_t pkt) > > +{ > > + return odp_packet_hdr(pkt)->l2_offset; > > +} > > + > > +void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset) > > +{ > > + odp_packet_hdr(pkt)->l2_offset = offset; > > +} > > + > > +uint8_t *odp_packet_l3(odp_packet_t pkt) > > +{ > > + const size_t offset = odp_packet_l3_offset(pkt); > > + > > + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > > + return NULL; > > + > > + return odp_packet_buf_addr(pkt) + offset; > > +} > > + > > +size_t odp_packet_l3_offset(odp_packet_t pkt) > > +{ > > + return odp_packet_hdr(pkt)->l3_offset; > > +} > > + > > +void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset) > > +{ > > + odp_packet_hdr(pkt)->l3_offset = offset; > > +} > > + > > +uint8_t *odp_packet_l4(odp_packet_t pkt) > > +{ > > + const size_t offset = odp_packet_l4_offset(pkt); > > + > > + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > > + return NULL; > > + > > + return odp_packet_buf_addr(pkt) + offset; > > +} > > + > > +size_t odp_packet_l4_offset(odp_packet_t pkt) > > +{ > > + return odp_packet_hdr(pkt)->l4_offset; > > +} > > + > > +void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset) > > +{ > > + odp_packet_hdr(pkt)->l4_offset = offset; > > +} > > + > > +/** > > + * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP > > + * > > + * Internal function: caller is resposible for passing only valid > packet handles > > + * , lengths and offsets (usually done&called in packet input). > > + * > > + * @param pkt Packet handle > > + * @param len Packet length in bytes > > + * @param frame_offset Byte offset to L2 header > > + */ > > +void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset) > > +{ > > + odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > > + odp_ethhdr_t *eth; > > + odp_vlanhdr_t *vlan; > > + odp_ipv4hdr_t *ipv4; > > + odp_ipv6hdr_t *ipv6; > > + uint16_t ethtype; > > + size_t offset = 0; > > + uint8_t ip_proto = 0; > > + > > + pkt_hdr->input_flags.eth = 1; > > + pkt_hdr->frame_offset = frame_offset; > > + pkt_hdr->frame_len = len; > > + > > + if (odp_unlikely(len < ODP_ETH_LEN_MIN)) { > > + pkt_hdr->error_flags.frame_len = 1; > > + return; > > + } else if (len > ODP_ETH_LEN_MAX) { > > + pkt_hdr->input_flags.jumbo = 1; > > + } > > + > > + /* Assume valid L2 header, no CRC/FCS check in SW */ > > + pkt_hdr->input_flags.l2 = 1; > > + pkt_hdr->l2_offset = frame_offset; > > + > > + eth = (odp_ethhdr_t *)odp_packet_start(pkt); > > + ethtype = odp_be_to_cpu_16(eth->type); > > + vlan = (odp_vlanhdr_t *)ð->type; > > + > > + if (ethtype == ODP_ETHTYPE_VLAN_OUTER) { > > + pkt_hdr->input_flags.vlan_qinq = 1; > > + ethtype = odp_be_to_cpu_16(vlan->tpid); > > + offset += sizeof(odp_vlanhdr_t); > > + vlan = &vlan[1]; > > + } > > + > > + if (ethtype == ODP_ETHTYPE_VLAN) { > > + pkt_hdr->input_flags.vlan = 1; > > + ethtype = odp_be_to_cpu_16(vlan->tpid); > > + offset += sizeof(odp_vlanhdr_t); > > + } > > + > > + /* Set l3_offset+flag only for known ethtypes */ > > + switch (ethtype) { > > + case ODP_ETHTYPE_IPV4: > > + pkt_hdr->input_flags.ipv4 = 1; > > + pkt_hdr->input_flags.l3 = 1; > > + pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + > offset; > > + ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt); > > + ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset); > > + break; > > + case ODP_ETHTYPE_IPV6: > > + pkt_hdr->input_flags.ipv6 = 1; > > + pkt_hdr->input_flags.l3 = 1; > > + pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + > offset; > > + ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt); > > + ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset); > > + break; > > + case ODP_ETHTYPE_ARP: > > + pkt_hdr->input_flags.arp = 1; > > + /* fall through */ > > + default: > > + ip_proto = 0; > > + break; > > + } > > + > > + switch (ip_proto) { > > + case ODP_IPPROTO_UDP: > > + pkt_hdr->input_flags.udp = 1; > > + pkt_hdr->input_flags.l4 = 1; > > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > + break; > > + case ODP_IPPROTO_TCP: > > + pkt_hdr->input_flags.tcp = 1; > > + pkt_hdr->input_flags.l4 = 1; > > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > + break; > > + case ODP_IPPROTO_SCTP: > > + pkt_hdr->input_flags.sctp = 1; > > + pkt_hdr->input_flags.l4 = 1; > > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > + break; > > + case ODP_IPPROTO_ICMP: > > + pkt_hdr->input_flags.icmp = 1; > > + pkt_hdr->input_flags.l4 = 1; > > + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > + break; > > + default: > > + /* 0 or unhandled IP protocols, don't set L4 flag+offset */ > > + if (pkt_hdr->input_flags.ipv6) { > > + /* IPv6 next_hdr is not L4, mark as IP-option > instead */ > > + pkt_hdr->input_flags.ipopt = 1; > > + } > > + break; > > + } > > +} > > + > > +static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, > odp_ipv4hdr_t *ipv4, > > + size_t *offset_out) > > +{ > > + uint8_t ihl; > > + uint16_t frag_offset; > > + > > + ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl); > > + if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) { > > + pkt_hdr->error_flags.ip_err = 1; > > + return 0; > > + } > > + > > + if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) { > > + pkt_hdr->input_flags.ipopt = 1; > > + return 0; > > + } > > + > > + /* A packet is a fragment if: > > + * "more fragments" flag is set (all fragments except the last) > > + * OR > > + * "fragment offset" field is nonzero (all fragments except the > first) > > + */ > > + frag_offset = odp_be_to_cpu_16(ipv4->frag_offset); > > + if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) { > > + pkt_hdr->input_flags.ipfrag = 1; > > + return 0; > > + } > > + > > + if (ipv4->proto == ODP_IPPROTO_ESP || > > + ipv4->proto == ODP_IPPROTO_AH) { > > + pkt_hdr->input_flags.ipsec = 1; > > + return 0; > > + } > > + > > + /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after > return */ > > + > > + *offset_out = sizeof(uint32_t) * ihl; > > + return ipv4->proto; > > +} > > + > > +static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, > odp_ipv6hdr_t *ipv6, > > + size_t *offset_out) > > +{ > > + if (ipv6->next_hdr == ODP_IPPROTO_ESP || > > + ipv6->next_hdr == ODP_IPPROTO_AH) { > > + pkt_hdr->input_flags.ipopt = 1; > > + pkt_hdr->input_flags.ipsec = 1; > > + return 0; > > + } > > + > > + if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) { > > + pkt_hdr->input_flags.ipopt = 1; > > + pkt_hdr->input_flags.ipfrag = 1; > > + return 0; > > + } > > + > > + /* Don't step through more extensions */ > > + *offset_out = ODP_IPV6HDR_LEN; > > + return ipv6->next_hdr; > > +} > > + > > +void odp_packet_print(odp_packet_t pkt) > > +{ > > + int max_len = 512; > > + char str[max_len]; > > + int len = 0; > > + int n = max_len-1; > > + odp_packet_hdr_t *hdr = odp_packet_hdr(pkt); > > + > > + len += snprintf(&str[len], n-len, "Packet "); > > + len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt); > > + len += snprintf(&str[len], n-len, > > + " input_flags 0x%x\n", hdr->input_flags.all); > > + len += snprintf(&str[len], n-len, > > + " error_flags 0x%x\n", hdr->error_flags.all); > > + len += snprintf(&str[len], n-len, > > + " output_flags 0x%x\n", hdr->output_flags.all); > > + len += snprintf(&str[len], n-len, > > + " frame_offset %u\n", hdr->frame_offset); > > + len += snprintf(&str[len], n-len, > > + " l2_offset %u\n", hdr->l2_offset); > > + len += snprintf(&str[len], n-len, > > + " l3_offset %u\n", hdr->l3_offset); > > + len += snprintf(&str[len], n-len, > > + " l4_offset %u\n", hdr->l4_offset); > > + len += snprintf(&str[len], n-len, > > + " frame_len %u\n", hdr->frame_len); > > + len += snprintf(&str[len], n-len, > > + " input %u\n", hdr->input); > > + str[len] = '\0'; > > + > > + printf("\n%s\n", str); > > +} > > + > > +int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src) > > +{ > > + odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst); > > + odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src); > > + const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, > buf_hdr); > > + uint8_t *start_src; > > + uint8_t *start_dst; > > + size_t len; > > + > > + if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID) > > + return -1; > > + > > + /* if (pkt_hdr_dst->buf_hdr.size < */ > > + /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */ > > + if (pkt_hdr_dst->buf_hdr.buf_len < > > + pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) > > + return -1; > > + > > + /* Copy packet header */ > > + start_dst = (uint8_t *)pkt_hdr_dst + start_offset; > > + start_src = (uint8_t *)pkt_hdr_src + start_offset; > > + len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > > + memcpy(start_dst, start_src, len); > > + > > + /* Copy frame payload */ > > + start_dst = (uint8_t *)odp_packet_start(pkt_dst); > > + start_src = (uint8_t *)odp_packet_start(pkt_src); > > + len = pkt_hdr_src->frame_len; > > + memcpy(start_dst, start_src, len); > > + > > + /* Copy useful things from the buffer header */ > > + /* pkt_hdr_dst->buf_hdr.cur_offset = > pkt_hdr_src->buf_hdr.cur_offset; */ > > + > > + /* Create a copy of the scatter list */ > > + /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */ > > + /* odp_buffer_from_packet(pkt_src)); */ > > + > > + return 0; > > +} > > diff --git a/platform/linux-dpdk/odp_packet_dpdk.c > b/platform/linux-dpdk/odp_packet_dpdk.c > > new file mode 100644 > > index 0000000..31bfa30 > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_packet_dpdk.c > > @@ -0,0 +1,189 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#define _GNU_SOURCE > > +#include <stdio.h> > > +#include <errno.h> > > +#include <sys/types.h> > > +#include <sys/stat.h> > > +#include <sys/ioctl.h> > > +#include <sys/mman.h> > > +#include <poll.h> > > +#include <unistd.h> > > +#include <fcntl.h> > > +#include <string.h> > > +#include <stdlib.h> > > + > > +#include <linux/ethtool.h> > > +#include <linux/sockios.h> > > + > > +#include <odp_hints.h> > > +#include <odp_thread.h> > > + > > +#include <odp_packet_dpdk.h> > > +#include <net/if.h> > > + > > +/* > > + * RX and TX Prefetch, Host, and Write-back threshold values should be > > + * carefully set for optimal performance. Consult the network > > + * controller's datasheet and supporting DPDK documentation for guidance > > + * on how these parameters should be set. > > + */ > > +#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. > */ > > +#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ > > +#define RX_WTHRESH 4 /**< Default values of RX write-back threshold > reg. */ > > + > > +/* > > + * These default values are optimized for use with the Intel(R) 82599 > 10 GbE > > + * Controller and the DPDK ixgbe PMD. Consider using other values for > other > > + * network controllers and/or network drivers. > > + */ > > +#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. > */ > > +#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ > > +#define TX_WTHRESH 0 /**< Default values of TX write-back threshold > reg. */ > > + > > +#define MAX_PKT_BURST 16 > > +#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ > > +#define RTE_TEST_RX_DESC_DEFAULT 128 > > +#define RTE_TEST_TX_DESC_DEFAULT 512 > > +static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; > > +static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; > > + > > +static const struct rte_eth_conf port_conf = { > > + .rxmode = { > > + .split_hdr_size = 0, > > + .header_split = 0, /**< Header Split disabled */ > > + .hw_ip_checksum = 0, /**< IP checksum offload disabled */ > > + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ > > + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ > > + .hw_strip_crc = 0, /**< CRC stripped by hardware */ > > + }, > > + .txmode = { > > + .mq_mode = ETH_MQ_TX_NONE, > > + }, > > +}; > > + > > +static const struct rte_eth_rxconf rx_conf = { > > + .rx_thresh = { > > + .pthresh = RX_PTHRESH, > > + .hthresh = RX_HTHRESH, > > + .wthresh = RX_WTHRESH, > > + }, > > +}; > > + > > +static const struct rte_eth_txconf tx_conf = { > > + .tx_thresh = { > > + .pthresh = TX_PTHRESH, > > + .hthresh = TX_HTHRESH, > > + .wthresh = TX_WTHRESH, > > + }, > > + .tx_free_thresh = 0, /* Use PMD default values */ > > + .tx_rs_thresh = 0, /* Use PMD default values */ > > + /* > > + * As the example won't handle mult-segments and offload cases, > > + * set the flag by default. > > + */ > > + .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS, > > +}; > > + > > +int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, > > + odp_buffer_pool_t pool) > > +{ > > + ODP_DBG("setup_pkt_dpdk\n"); > > + > > + static struct ether_addr eth_addr[RTE_MAX_ETHPORTS]; > > + uint8_t portid = 0; > > + uint16_t queueid = 0; > > + int ret; > > + printf("dpdk netdev: %s\n", netdev); > > + printf("dpdk pool: %lx\n", pool); > > + > > + portid = atoi(netdev); > > + pkt_dpdk->portid = portid; > > + pkt_dpdk->queueid = queueid; > > + pkt_dpdk->pool = pool; > > + printf("dpdk portid: %u\n", portid); > > + > > + fflush(stdout); > > + ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); > > + if (ret < 0) > > + ODP_ERR("Cannot configure device: err=%d, port=%u\n", > > + ret, (unsigned) portid); > > + > > + rte_eth_macaddr_get(portid, ð_addr[portid]); > > + ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", > > + (unsigned) portid, > > + eth_addr[portid].addr_bytes[0], > > + eth_addr[portid].addr_bytes[1], > > + eth_addr[portid].addr_bytes[2], > > + eth_addr[portid].addr_bytes[3], > > + eth_addr[portid].addr_bytes[4], > > + eth_addr[portid].addr_bytes[5]); > > + > > + /* init one RX queue on each port */ > > + fflush(stdout); > > + ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd, > > + rte_eth_dev_socket_id(portid), > &rx_conf, > > + (struct rte_mempool *)pool); > > + if (ret < 0) > > + ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n", > > + ret, (unsigned) portid); > > + ODP_DBG("dpdk rx queue setup done\n"); > > + > > + /* init one TX queue on each port */ > > + fflush(stdout); > > + ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, > > + rte_eth_dev_socket_id(portid), &tx_conf); > > + if (ret < 0) > > + ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n", > > + ret, (unsigned) portid); > > + ODP_DBG("dpdk tx queue setup done\n"); > > + > > + /* Start device */ > > + ret = rte_eth_dev_start(portid); > > + if (ret < 0) > > + ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n", > > + ret, (unsigned) portid); > > + ODP_DBG("dpdk setup done\n\n"); > > + > > + > > + return 0; > > +} > > + > > +int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk) > > +{ > > + ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid); > > + > > + return 0; > > +} > > + > > +int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > > + unsigned len) > > +{ > > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > + uint16_t nb_rx, i = 0; > > + > > + memset(pkts_burst, 0 , sizeof(pkts_burst)); > > + nb_rx = rte_eth_rx_burst((uint8_t)pkt_dpdk->portid, > > + (uint16_t)pkt_dpdk->queueid, > > + (struct rte_mbuf **)pkts_burst, > (uint16_t)len); > > + for (i = 0; i < nb_rx; i++) > > + pkt_table[i] = (odp_packet_t)pkts_burst[i]; > > + return nb_rx; > > +} > > + > > +int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > > + unsigned len) > > +{ > > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > + uint16_t i; > > + > > + for (i = 0; i < len; i++) > > + pkts_burst[i] = (struct rte_mbuf *)pkt_table[i]; > > + return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid, > > + (uint16_t)pkt_dpdk->queueid, > > + (struct rte_mbuf **)pkts_burst, > (uint16_t)len); > > +} > > diff --git a/platform/linux-dpdk/odp_packet_io.c > b/platform/linux-dpdk/odp_packet_io.c > > new file mode 100644 > > index 0000000..abea0ec > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_packet_io.c > > @@ -0,0 +1,561 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#include <odp_packet_io.h> > > +#include <odp_packet_io_internal.h> > > +#include <odp_packet_io_queue.h> > > +#include <odp_packet.h> > > +#include <odp_packet_internal.h> > > +#include <odp_internal.h> > > +#include <odp_spinlock.h> > > +#include <odp_shared_memory.h> > > +#include <odp_packet_socket.h> > > +#ifdef ODP_HAVE_NETMAP > > +#include <odp_packet_netmap.h> > > +#endif > > +#include <odp_hints.h> > > +#include <odp_config.h> > > +#include <odp_queue_internal.h> > > +#include <odp_schedule_internal.h> > > +#include <odp_debug.h> > > + > > +#include <odp_pktio_socket.h> > > +#ifdef ODP_HAVE_NETMAP > > +#include <odp_pktio_netmap.h> > > +#endif > > + > > +#include <string.h> > > + > > +typedef struct { > > + pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; > > +} pktio_table_t; > > + > > +static pktio_table_t *pktio_tbl; > > + > > + > > +static pktio_entry_t *get_entry(odp_pktio_t id) > > +{ > > + if (odp_unlikely(id == ODP_PKTIO_INVALID || > > + id > ODP_CONFIG_PKTIO_ENTRIES)) > > + return NULL; > > + > > + return &pktio_tbl->entries[id - 1]; > > +} > > + > > +int odp_pktio_init_global(void) > > +{ > > + char name[ODP_QUEUE_NAME_LEN]; > > + pktio_entry_t *pktio_entry; > > + queue_entry_t *queue_entry; > > + odp_queue_t qid; > > + int id; > > + > > + pktio_tbl = odp_shm_reserve("odp_pktio_entries", > > + sizeof(pktio_table_t), > > + sizeof(pktio_entry_t)); > > + if (pktio_tbl == NULL) > > + return -1; > > + > > + memset(pktio_tbl, 0, sizeof(pktio_table_t)); > > + > > + for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) { > > + pktio_entry = get_entry(id); > > + > > + odp_spinlock_init(&pktio_entry->s.lock); > > + > > + /* Create a default output queue for each pktio resource */ > > + snprintf(name, sizeof(name), "%i-pktio_outq_default", > (int)id); > > + name[ODP_QUEUE_NAME_LEN-1] = '\0'; > > + > > + qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL); > > + if (qid == ODP_QUEUE_INVALID) > > + return -1; > > + pktio_entry->s.outq_default = qid; > > + > > + queue_entry = queue_to_qentry(qid); > > + queue_entry->s.pktout = id; > > + } > > + > > + return 0; > > +} > > + > > +int odp_pktio_init_local(void) > > +{ > > + return 0; > > +} > > + > > +static int is_free(pktio_entry_t *entry) > > +{ > > + return (entry->s.taken == 0); > > +} > > + > > +static void set_free(pktio_entry_t *entry) > > +{ > > + entry->s.taken = 0; > > +} > > + > > +static void set_taken(pktio_entry_t *entry) > > +{ > > + entry->s.taken = 1; > > +} > > + > > +static void lock_entry(pktio_entry_t *entry) > > +{ > > + odp_spinlock_lock(&entry->s.lock); > > +} > > + > > +static void unlock_entry(pktio_entry_t *entry) > > +{ > > + odp_spinlock_unlock(&entry->s.lock); > > +} > > + > > +static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t > *params) > > +{ > > + set_taken(entry); > > + entry->s.inq_default = ODP_QUEUE_INVALID; > > + switch (params->type) { > > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > > + memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); > > + memset(&entry->s.pkt_sock_mmap, 0, > > + sizeof(entry->s.pkt_sock_mmap)); > > + break; > > +#ifdef ODP_HAVE_NETMAP > > + case ODP_PKTIO_TYPE_NETMAP: > > + memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); > > + break; > > +#endif > > + case ODP_PKTIO_TYPE_DPDK: > > + memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk)); > > + break; > > + default: > > + ODP_ERR("Packet I/O type not supported. Please > recompile\n"); > > + break; > > + } > > + /* Save pktio parameters, type is the most useful */ > > + memcpy(&entry->s.params, params, sizeof(*params)); > > +} > > + > > +static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params) > > +{ > > + odp_pktio_t id; > > + pktio_entry_t *entry; > > + int i; > > + > > + for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { > > + entry = &pktio_tbl->entries[i]; > > + if (is_free(entry)) { > > + lock_entry(entry); > > + if (is_free(entry)) { > > + init_pktio_entry(entry, params); > > + id = i + 1; > > + return id; /* return with entry locked! */ > > + } > > + unlock_entry(entry); > > + } > > + } > > + > > + return ODP_PKTIO_INVALID; > > +} > > + > > +static int free_pktio_entry(odp_pktio_t id) > > +{ > > + pktio_entry_t *entry = get_entry(id); > > + > > + if (entry == NULL) > > + return -1; > > + > > + set_free(entry); > > + > > + return 0; > > +} > > + > > +odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool, > > + odp_pktio_params_t *params) > > +{ > > + odp_pktio_t id; > > + pktio_entry_t *pktio_entry; > > + int res; > > + > > + if (params == NULL) { > > + ODP_ERR("Invalid pktio params\n"); > > + return ODP_PKTIO_INVALID; > > + } > > + > > + switch (params->type) { > > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > > + ODP_DBG("Allocating socket pktio\n"); > > + break; > > +#ifdef ODP_HAVE_NETMAP > > + case ODP_PKTIO_TYPE_NETMAP: > > + ODP_DBG("Allocating netmap pktio\n"); > > + break; > > +#endif > > + case ODP_PKTIO_TYPE_DPDK: > > + ODP_DBG("Allocating dpdk pktio\n"); > > + break; > > + default: > > + ODP_ERR("Invalid pktio type: %02x\n", params->type); > > + return ODP_PKTIO_INVALID; > > + } > > + > > + id = alloc_lock_pktio_entry(params); > > + if (id == ODP_PKTIO_INVALID) { > > + ODP_ERR("No resources available.\n"); > > + return ODP_PKTIO_INVALID; > > + } > > + /* if successful, alloc_pktio_entry() returns with the entry > locked */ > > + > > + pktio_entry = get_entry(id); > > + > > + switch (params->type) { > > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > > + res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); > > + if (res == -1) { > > + close_pkt_sock(&pktio_entry->s.pkt_sock); > > + free_pktio_entry(id); > > + id = ODP_PKTIO_INVALID; > > + } > > + break; > > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > > + res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > dev, > > + pool, params->sock_params.fanout); > > + if (res == -1) { > > + close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); > > + free_pktio_entry(id); > > + id = ODP_PKTIO_INVALID; > > + } > > + break; > > +#ifdef ODP_HAVE_NETMAP > > + case ODP_PKTIO_TYPE_NETMAP: > > + > > + res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, > > + pool, ¶ms->nm_params); > > + if (res == -1) { > > + close_pkt_netmap(&pktio_entry->s.pkt_nm); > > + free_pktio_entry(id); > > + id = ODP_PKTIO_INVALID; > > + } > > + break; > > +#endif > > + case ODP_PKTIO_TYPE_DPDK: > > + res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool); > > + if (res == -1) { > > + close_pkt_dpdk(&pktio_entry->s.pkt_dpdk); > > + free_pktio_entry(id); > > + id = ODP_PKTIO_INVALID; > > + } > > + break; > > + default: > > + free_pktio_entry(id); > > + id = ODP_PKTIO_INVALID; > > + ODP_ERR("Invalid pktio type. Please recompile.\n"); > > + break; > > + } > > + > > + unlock_entry(pktio_entry); > > + return id; > > +} > > + > > +int odp_pktio_close(odp_pktio_t id) > > +{ > > + pktio_entry_t *entry; > > + int res = -1; > > + > > + entry = get_entry(id); > > + if (entry == NULL) > > + return -1; > > + > > + lock_entry(entry); > > + if (!is_free(entry)) { > > + switch (entry->s.params.type) { > > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > > + res = close_pkt_sock(&entry->s.pkt_sock); > > + break; > > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > > + res = > close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); > > + break; > > +#ifdef ODP_HAVE_NETMAP > > + case ODP_PKTIO_TYPE_NETMAP: > > + res = close_pkt_netmap(&entry->s.pkt_nm); > > + break; > > +#endif > > + case ODP_PKTIO_TYPE_DPDK: > > + res = close_pkt_dpdk(&entry->s.pkt_dpdk); > > + break; > > + default: > > + break; > > + res |= free_pktio_entry(id); > > + } > > + } > > + unlock_entry(entry); > > + > > + if (res != 0) > > + return -1; > > + > > + return 0; > > +} > > + > > +void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio) > > +{ > > + odp_packet_hdr(pkt)->input = pktio; > > +} > > + > > +odp_pktio_t odp_pktio_get_input(odp_packet_t pkt) > > +{ > > + return odp_packet_hdr(pkt)->input; > > +} > > + > > +int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned > len) > > +{ > > + pktio_entry_t *pktio_entry = get_entry(id); > > + int pkts; > > + int i; > > + > > + if (pktio_entry == NULL) > > + return -1; > > + > > + lock_entry(pktio_entry); > > + switch (pktio_entry->s.params.type) { > > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > > + pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, > > + pkt_table, len); > > + break; > > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > > + pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > > + pkt_table, len); > > + break; > > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > > + pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > > + pkt_table, len); > > + break; > > +#ifdef ODP_HAVE_NETMAP > > + case ODP_PKTIO_TYPE_NETMAP: > > + pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, > len); > > + break; > > +#endif > > + case ODP_PKTIO_TYPE_DPDK: > > + pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, > len); > > + break; > > + default: > > + pkts = -1; > > + break; > > + } > > + > > + unlock_entry(pktio_entry); > > + if (pkts < 0) > > + return pkts; > > + > > + for (i = 0; i < pkts; ++i) > > + odp_pktio_set_input(pkt_table[i], id); > > + > > + return pkts; > > +} > > + > > +int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned > len) > > +{ > > + pktio_entry_t *pktio_entry = get_entry(id); > > + int pkts; > > + > > + if (pktio_entry == NULL) > > + return -1; > > + > > + lock_entry(pktio_entry); > > + switch (pktio_entry->s.params.type) { > > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > > + pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, > > + pkt_table, len); > > + break; > > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > > + pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > > + pkt_table, len); > > + break; > > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > > + pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > > + pkt_table, len); > > + break; > > +#ifdef ODP_HAVE_NETMAP > > + case ODP_PKTIO_TYPE_NETMAP: > > + pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, > > + pkt_table, len); > > + break; > > +#endif > > + case ODP_PKTIO_TYPE_DPDK: > > + pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk, > > + pkt_table, len); > > + break; > > + default: > > + pkts = -1; > > + } > > + unlock_entry(pktio_entry); > > + > > + return pkts; > > +} > > + > > +int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue) > > +{ > > + pktio_entry_t *pktio_entry = get_entry(id); > > + queue_entry_t *qentry = queue_to_qentry(queue); > > + > > + if (pktio_entry == NULL || qentry == NULL) > > + return -1; > > + > > + if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN) > > + return -1; > > + > > + lock_entry(pktio_entry); > > + pktio_entry->s.inq_default = queue; > > + unlock_entry(pktio_entry); > > + > > + queue_lock(qentry); > > + qentry->s.pktin = id; > > + qentry->s.status = QUEUE_STATUS_SCHED; > > + queue_unlock(qentry); > > + > > + odp_schedule_queue(queue, qentry->s.param.sched.prio); > > + > > + return 0; > > +} > > + > > +int odp_pktio_inq_remdef(odp_pktio_t id) > > +{ > > + return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID); > > +} > > + > > +odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id) > > +{ > > + pktio_entry_t *pktio_entry = get_entry(id); > > + > > + if (pktio_entry == NULL) > > + return ODP_QUEUE_INVALID; > > + > > + return pktio_entry->s.inq_default; > > +} > > + > > +odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id) > > +{ > > + pktio_entry_t *pktio_entry = get_entry(id); > > + > > + if (pktio_entry == NULL) > > + return ODP_QUEUE_INVALID; > > + > > + return pktio_entry->s.outq_default; > > +} > > + > > +int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > > +{ > > + odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr); > > + int len = 1; > > + int nbr; > > + > > + nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); > > + return (nbr == len ? 0 : -1); > > +} > > + > > +odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry) > > +{ > > + (void)qentry; > > + return NULL; > > +} > > + > > +int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > > + int num) > > +{ > > + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > > + int nbr; > > + int i; > > + > > + for (i = 0; i < num; ++i) > > + pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) > buf_hdr[i]); > > + > > + nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > > + return (nbr == num ? 0 : -1); > > +} > > + > > +int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > > + int num) > > +{ > > + (void)qentry; > > + (void)buf_hdr; > > + (void)num; > > + > > + return 0; > > +} > > + > > +int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > > +{ > > + /* Use default action */ > > + return queue_enq(qentry, buf_hdr); > > +} > > + > > +odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry) > > +{ > > + odp_buffer_hdr_t *buf_hdr; > > + > > + buf_hdr = queue_deq(qentry); > > + > > + if (buf_hdr == NULL) { > > + odp_packet_t pkt; > > + odp_buffer_t buf; > > + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > > + odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > > + int pkts, i, j; > > + > > + pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > > + QUEUE_MULTI_MAX); > > + > > + if (pkts > 0) { > > + pkt = pkt_tbl[0]; > > + buf = odp_buffer_from_packet(pkt); > > + buf_hdr = odp_buf_to_hdr(buf); > > + > > + for (i = 1, j = 0; i < pkts; ++i) { > > + buf = odp_buffer_from_packet(pkt_tbl[i]); > > + tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf); > > + } > > + queue_enq_multi(qentry, tmp_hdr_tbl, j); > > + } > > + } > > + > > + return buf_hdr; > > +} > > + > > +int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > int num) > > +{ > > + /* Use default action */ > > + return queue_enq_multi(qentry, buf_hdr, num); > > +} > > + > > +int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > int num) > > +{ > > + int nbr; > > + > > + nbr = queue_deq_multi(qentry, buf_hdr, num); > > + > > + if (nbr < num) { > > + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > > + odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > > + odp_buffer_t buf; > > + int pkts, i; > > + > > + pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > > + QUEUE_MULTI_MAX); > > + if (pkts > 0) { > > + for (i = 0; i < pkts; ++i) { > > + buf = odp_buffer_from_packet(pkt_tbl[i]); > > + tmp_hdr_tbl[i] = odp_buf_to_hdr(buf); > > + } > > + queue_enq_multi(qentry, tmp_hdr_tbl, pkts); > > + } > > + } > > + > > + return nbr; > > +} > > diff --git a/platform/linux-dpdk/odp_queue.c > b/platform/linux-dpdk/odp_queue.c > > new file mode 100644 > > index 0000000..554b8ea > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_queue.c > > @@ -0,0 +1,435 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#include <odp_queue.h> > > +#include <odp_queue_internal.h> > > +#include <odp_std_types.h> > > +#include <odp_align.h> > > +#include <odp_buffer.h> > > +#include <odp_buffer_internal.h> > > +#include <odp_buffer_pool_internal.h> > > +#include <odp_internal.h> > > +#include <odp_shared_memory.h> > > +#include <odp_schedule_internal.h> > > +#include <odp_config.h> > > +#include <odp_packet_io_internal.h> > > +#include <odp_packet_io_queue.h> > > +#include <odp_debug.h> > > +#include <odp_hints.h> > > + > > +#ifdef USE_TICKETLOCK > > +#include <odp_ticketlock.h> > > +#define LOCK(a) odp_ticketlock_lock(a) > > +#define UNLOCK(a) odp_ticketlock_unlock(a) > > +#define LOCK_INIT(a) odp_ticketlock_init(a) > > +#else > > +#include <odp_spinlock.h> > > +#define LOCK(a) odp_spinlock_lock(a) > > +#define UNLOCK(a) odp_spinlock_unlock(a) > > +#define LOCK_INIT(a) odp_spinlock_init(a) > > +#endif > > + > > +#include <string.h> > > + > > + > > +typedef struct queue_table_t { > > + queue_entry_t queue[ODP_CONFIG_QUEUES]; > > +} queue_table_t; > > + > > +static queue_table_t *queue_tbl; > > + > > + > > +queue_entry_t *get_qentry(uint32_t queue_id) > > +{ > > + return &queue_tbl->queue[queue_id]; > > +} > > + > > +static void queue_init(queue_entry_t *queue, const char *name, > > + odp_queue_type_t type, odp_queue_param_t *param) > > +{ > > + strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1); > > + queue->s.type = type; > > + > > + if (param) { > > + memcpy(&queue->s.param, param, sizeof(odp_queue_param_t)); > > + } else { > > + /* Defaults */ > > + memset(&queue->s.param, 0, sizeof(odp_queue_param_t)); > > + queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT; > > + queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT; > > + queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT; > > + } > > + > > + switch (type) { > > + case ODP_QUEUE_TYPE_PKTIN: > > + queue->s.enqueue = pktin_enqueue; > > + queue->s.dequeue = pktin_dequeue; > > + queue->s.enqueue_multi = pktin_enq_multi; > > + queue->s.dequeue_multi = pktin_deq_multi; > > + break; > > + case ODP_QUEUE_TYPE_PKTOUT: > > + queue->s.enqueue = pktout_enqueue; > > + queue->s.dequeue = pktout_dequeue; > > + queue->s.enqueue_multi = pktout_enq_multi; > > + queue->s.dequeue_multi = pktout_deq_multi; > > + break; > > + default: > > + queue->s.enqueue = queue_enq; > > + queue->s.dequeue = queue_deq; > > + queue->s.enqueue_multi = queue_enq_multi; > > + queue->s.dequeue_multi = queue_deq_multi; > > + break; > > + } > > + > > + queue->s.head = NULL; > > + queue->s.tail = NULL; > > + queue->s.sched_buf = ODP_BUFFER_INVALID; > > +} > > + > > + > > +int odp_queue_init_global(void) > > +{ > > + uint32_t i; > > + > > + ODP_DBG("Queue init ... "); > > + > > + queue_tbl = odp_shm_reserve("odp_queues", > > + sizeof(queue_table_t), > > + sizeof(queue_entry_t)); > > + > > + if (queue_tbl == NULL) > > + return -1; > > + > > + memset(queue_tbl, 0, sizeof(queue_table_t)); > > + > > + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > > + /* init locks */ > > + queue_entry_t *queue = get_qentry(i); > > + LOCK_INIT(&queue->s.lock); > > + queue->s.handle = queue_from_id(i); > > + } > > + > > + ODP_DBG("done\n"); > > + ODP_DBG("Queue init global\n"); > > + ODP_DBG(" struct queue_entry_s size %zu\n", > > + sizeof(struct queue_entry_s)); > > + ODP_DBG(" queue_entry_t size %zu\n", > > + sizeof(queue_entry_t)); > > + ODP_DBG("\n"); > > + > > + return 0; > > +} > > + > > +odp_queue_type_t odp_queue_type(odp_queue_t handle) > > +{ > > + queue_entry_t *queue; > > + > > + queue = queue_to_qentry(handle); > > + > > + return queue->s.type; > > +} > > + > > +odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle) > > +{ > > + queue_entry_t *queue; > > + > > + queue = queue_to_qentry(handle); > > + > > + return queue->s.param.sched.sync; > > +} > > + > > +odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type, > > + odp_queue_param_t *param) > > +{ > > + uint32_t i; > > + queue_entry_t *queue; > > + odp_queue_t handle = ODP_QUEUE_INVALID; > > + > > + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > > + queue = &queue_tbl->queue[i]; > > + > > + if (queue->s.status != QUEUE_STATUS_FREE) > > + continue; > > + > > + LOCK(&queue->s.lock); > > + if (queue->s.status == QUEUE_STATUS_FREE) { > > + queue_init(queue, name, type, param); > > + > > + if (type == ODP_QUEUE_TYPE_SCHED || > > + type == ODP_QUEUE_TYPE_PKTIN) > > + queue->s.status = QUEUE_STATUS_NOTSCHED; > > + else > > + queue->s.status = QUEUE_STATUS_READY; > > + > > + handle = queue->s.handle; > > + UNLOCK(&queue->s.lock); > > + break; > > + } > > + UNLOCK(&queue->s.lock); > > + } > > + > > + if (handle != ODP_QUEUE_INVALID && > > + (type == ODP_QUEUE_TYPE_SCHED || type == > ODP_QUEUE_TYPE_PKTIN)) { > > + odp_buffer_t buf; > > + > > + buf = odp_schedule_buffer_alloc(handle); > > + if (buf == ODP_BUFFER_INVALID) { > > + ODP_ERR("queue_init: sched buf alloc failed\n"); > > + return ODP_QUEUE_INVALID; > > + } > > + > > + queue->s.sched_buf = buf; > > + odp_schedule_mask_set(handle, queue->s.param.sched.prio); > > + } > > + > > + return handle; > > +} > > + > > + > > +odp_buffer_t queue_sched_buf(odp_queue_t handle) > > +{ > > + queue_entry_t *queue; > > + queue = queue_to_qentry(handle); > > + > > + return queue->s.sched_buf; > > +} > > + > > + > > +int queue_sched_atomic(odp_queue_t handle) > > +{ > > + queue_entry_t *queue; > > + queue = queue_to_qentry(handle); > > + > > + return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC; > > +} > > + > > + > > +odp_queue_t odp_queue_lookup(const char *name) > > +{ > > + uint32_t i; > > + > > + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > > + queue_entry_t *queue = &queue_tbl->queue[i]; > > + > > + if (queue->s.status == QUEUE_STATUS_FREE) > > + continue; > > + > > + LOCK(&queue->s.lock); > > + if (strcmp(name, queue->s.name) == 0) { > > + /* found it */ > > + UNLOCK(&queue->s.lock); > > + return queue->s.handle; > > + } > > + UNLOCK(&queue->s.lock); > > + } > > + > > + return ODP_QUEUE_INVALID; > > +} > > + > > + > > +int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr) > > +{ > > + int sched = 0; > > + > > + LOCK(&queue->s.lock); > > + if (queue->s.head == NULL) { > > + /* Empty queue */ > > + queue->s.head = buf_hdr; > > + queue->s.tail = buf_hdr; > > + buf_hdr->pkt.next = NULL; > > + } else { > > + queue->s.tail->pkt.next = buf_hdr; > > + queue->s.tail = buf_hdr; > > + buf_hdr->pkt.next = NULL; > > + } > > + > > + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > > + queue->s.status = QUEUE_STATUS_SCHED; > > + sched = 1; /* retval: schedule queue */ > > + } > > + UNLOCK(&queue->s.lock); > > + > > + /* Add queue to scheduling */ > > + if (sched == 1) > > + odp_schedule_queue(queue->s.handle, > queue->s.param.sched.prio); > > + > > + return 0; > > +} > > + > > + > > +int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], > int num) > > +{ > > + int sched = 0; > > + int i; > > + odp_buffer_hdr_t *tail; > > + > > + for (i = 0; i < num - 1; i++) > > + buf_hdr[i]->pkt.next = buf_hdr[i+1]; > > + > > + tail = buf_hdr[num-1]; > > + buf_hdr[num-1]->pkt.next = NULL; > > + > > + LOCK(&queue->s.lock); > > + /* Empty queue */ > > + if (queue->s.head == NULL) > > + queue->s.head = buf_hdr[0]; > > + else > > + queue->s.tail->pkt.next = buf_hdr[0]; > > + > > + queue->s.tail = tail; > > + > > + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > > + queue->s.status = QUEUE_STATUS_SCHED; > > + sched = 1; /* retval: schedule queue */ > > + } > > + UNLOCK(&queue->s.lock); > > + > > + /* Add queue to scheduling */ > > + if (sched == 1) > > + odp_schedule_queue(queue->s.handle, > queue->s.param.sched.prio); > > + > > + return 0; > > +} > > + > > + > > +int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > > +{ > > + odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > > + queue_entry_t *queue; > > + int i; > > + > > + if (num > QUEUE_MULTI_MAX) > > + num = QUEUE_MULTI_MAX; > > + > > + queue = queue_to_qentry(handle); > > + > > + for (i = 0; i < num; i++) > > + buf_hdr[i] = odp_buf_to_hdr(buf[i]); > > + > > + return queue->s.enqueue_multi(queue, buf_hdr, num); > > +} > > + > > + > > +int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf) > > +{ > > + odp_buffer_hdr_t *buf_hdr; > > + queue_entry_t *queue; > > + > > + queue = queue_to_qentry(handle); > > + buf_hdr = odp_buf_to_hdr(buf); > > + > > + return queue->s.enqueue(queue, buf_hdr); > > +} > > + > > + > > +odp_buffer_hdr_t *queue_deq(queue_entry_t *queue) > > +{ > > + odp_buffer_hdr_t *buf_hdr = NULL; > > + > > + LOCK(&queue->s.lock); > > + > > + if (queue->s.head == NULL) { > > + /* Already empty queue */ > > + if (queue->s.status == QUEUE_STATUS_SCHED && > > + queue->s.type != ODP_QUEUE_TYPE_PKTIN) > > + queue->s.status = QUEUE_STATUS_NOTSCHED; > > + } else { > > + buf_hdr = queue->s.head; > > + queue->s.head = buf_hdr->pkt.next; > > + buf_hdr->pkt.next = NULL; > > + > > + if (queue->s.head == NULL) { > > + /* Queue is now empty */ > > + queue->s.tail = NULL; > > + } > > + } > > + > > + UNLOCK(&queue->s.lock); > > + > > + return buf_hdr; > > +} > > + > > + > > +int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], > int num) > > +{ > > + int i = 0; > > + > > + LOCK(&queue->s.lock); > > + > > + if (queue->s.head == NULL) { > > + /* Already empty queue */ > > + if (queue->s.status == QUEUE_STATUS_SCHED && > > + queue->s.type != ODP_QUEUE_TYPE_PKTIN) > > + queue->s.status = QUEUE_STATUS_NOTSCHED; > > + } else { > > + odp_buffer_hdr_t *hdr = queue->s.head; > > + > > + for (; i < num && hdr; i++) { > > + buf_hdr[i] = hdr; > > + /* odp_prefetch(hdr->addr); */ > > + hdr = hdr->pkt.next; > > + buf_hdr[i]->pkt.next = NULL; > > + } > > + > > + queue->s.head = hdr; > > + > > + if (hdr == NULL) { > > + /* Queue is now empty */ > > + queue->s.tail = NULL; > > + } > > + } > > + > > + UNLOCK(&queue->s.lock); > > + > > + return i; > > +} > > + > > + > > +int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > > +{ > > + queue_entry_t *queue; > > + odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > > + int i, ret; > > + > > + if (num > QUEUE_MULTI_MAX) > > + num = QUEUE_MULTI_MAX; > > + > > + queue = queue_to_qentry(handle); > > + > > + ret = queue->s.dequeue_multi(queue, buf_hdr, num); > > + > > + for (i = 0; i < ret; i++) > > + buf[i] = (odp_buffer_t) buf_hdr[i]; > > + > > + return ret; > > +} > > + > > + > > +odp_buffer_t odp_queue_deq(odp_queue_t handle) > > +{ > > + queue_entry_t *queue; > > + odp_buffer_hdr_t *buf_hdr; > > + > > + queue = queue_to_qentry(handle); > > + buf_hdr = queue->s.dequeue(queue); > > + > > + if (buf_hdr) > > + return (odp_buffer_t) buf_hdr; > > + > > + return ODP_BUFFER_INVALID; > > +} > > + > > + > > +void queue_lock(queue_entry_t *queue) > > +{ > > + LOCK(&queue->s.lock); > > +} > > + > > + > > +void queue_unlock(queue_entry_t *queue) > > +{ > > + UNLOCK(&queue->s.lock); > > +} > > diff --git a/platform/linux-dpdk/source/odp_buffer.c > b/platform/linux-dpdk/source/odp_buffer.c > > deleted file mode 100644 > > index bfb5ff6..0000000 > > --- a/platform/linux-dpdk/source/odp_buffer.c > > +++ /dev/null > > @@ -1,102 +0,0 @@ > > -/* Copyright (c) 2013, Linaro Limited > > - * All rights reserved. > > - * > > - * SPDX-License-Identifier: BSD-3-Clause > > - */ > > - > > -#include <odp_buffer.h> > > -#include <odp_buffer_internal.h> > > -#include <odp_buffer_pool_internal.h> > > - > > -#include <string.h> > > -#include <stdio.h> > > - > > - > > -void *odp_buffer_addr(odp_buffer_t buf) > > -{ > > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > > - > > - return hdr->buf_addr; > > -} > > - > > - > > -size_t odp_buffer_size(odp_buffer_t buf) > > -{ > > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > > - > > - return hdr->buf_len; > > -} > > - > > - > > -int odp_buffer_type(odp_buffer_t buf) > > -{ > > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > > - > > - return hdr->type; > > -} > > - > > - > > -int odp_buffer_is_scatter(odp_buffer_t buf) > > -{ > > - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); > > - > > - if (hdr->refcnt == 0) > > - return 0; > > - else > > - return 1; > > -} > > - > > - > > -int odp_buffer_is_valid(odp_buffer_t buf) > > -{ > > - odp_buffer_bits_t handle; > > - > > - handle.u32 = buf; > > - > > - return (handle.index != ODP_BUFFER_INVALID_INDEX); > > -} > > - > > - > > -int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) > > -{ > > - odp_buffer_hdr_t *hdr; > > - int len = 0; > > - > > - if (!odp_buffer_is_valid(buf)) { > > - printf("Buffer is not valid.\n"); > > - return len; > > - } > > - > > - hdr = odp_buf_to_hdr(buf); > > - > > - len += snprintf(&str[len], n-len, > > - "Buffer\n"); > > - len += snprintf(&str[len], n-len, > > - " pool %"PRIu64"\n", (int64_t) hdr->pool); > > - len += snprintf(&str[len], n-len, > > - " phy_addr %"PRIu64"\n", hdr->buf_physaddr); > > - len += snprintf(&str[len], n-len, > > - " addr %p\n", hdr->buf_addr); > > - len += snprintf(&str[len], n-len, > > - " size %u\n", hdr->buf_len); > > - len += snprintf(&str[len], n-len, > > - " ref_count %i\n", hdr->refcnt); > > - len += snprintf(&str[len], n-len, > > - " type %i\n", hdr->type); > > - > > - return len; > > -} > > - > > - > > -void odp_buffer_print(odp_buffer_t buf) > > -{ > > - int max_len = 512; > > - char str[max_len]; > > - int len; > > - > > - len = odp_buffer_snprint(str, max_len-1, buf); > > - str[len] = 0; > > - > > - printf("\n%s\n", str); > > -} > > - > > diff --git a/platform/linux-dpdk/source/odp_buffer_pool.c > b/platform/linux-dpdk/source/odp_buffer_pool.c > > deleted file mode 100644 > > index de90275..0000000 > > --- a/platform/linux-dpdk/source/odp_buffer_pool.c > > +++ /dev/null > > @@ -1,156 +0,0 @@ > > -/* Copyright (c) 2013, Linaro Limited > > - * All rights reserved. > > - * > > - * SPDX-License-Identifier: BSD-3-Clause > > - */ > > - > > -#include <odp_std_types.h> > > -#include <odp_buffer_pool.h> > > -#include <odp_buffer_pool_internal.h> > > -#include <odp_buffer_internal.h> > > -#include <odp_packet_internal.h> > > -#include <odp_shared_memory.h> > > -#include <odp_align.h> > > -#include <odp_internal.h> > > -#include <odp_config.h> > > -#include <odp_hints.h> > > -#include <odp_debug.h> > > - > > -#include <string.h> > > -#include <stdlib.h> > > - > > -/* for DPDK */ > > -#include <odp_packet_dpdk.h> > > - > > -#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + > RTE_PKTMBUF_HEADROOM) > > -#define NB_MBUF 8192 > > - > > -#ifdef POOL_USE_TICKETLOCK > > -#include <odp_ticketlock.h> > > -#define LOCK(a) odp_ticketlock_lock(a) > > -#define UNLOCK(a) odp_ticketlock_unlock(a) > > -#define LOCK_INIT(a) odp_ticketlock_init(a) > > -#else > > -#include <odp_spinlock.h> > > -#define LOCK(a) odp_spinlock_lock(a) > > -#define UNLOCK(a) odp_spinlock_unlock(a) > > -#define LOCK_INIT(a) odp_spinlock_init(a) > > -#endif > > - > > - > > -#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > > -#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS > > -#endif > > - > > -#define NULL_INDEX ((uint32_t)-1) > > - > > - > > -typedef union pool_entry_u { > > - struct pool_entry_s s; > > - > > - uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct > pool_entry_s))]; > > - > > -} pool_entry_t; > > - > > - > > -typedef struct pool_table_t { > > - pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS]; > > - > > -} pool_table_t; > > - > > - > > -/* The pool table */ > > -static pool_table_t *pool_tbl; > > - > > -/* Pool entry pointers (for inlining) */ > > -void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS]; > > - > > - > > -int odp_buffer_pool_init_global(void) > > -{ > > - odp_buffer_pool_t i; > > - > > - pool_tbl = odp_shm_reserve("odp_buffer_pools", > > - sizeof(pool_table_t), > > - sizeof(pool_entry_t)); > > - > > - if (pool_tbl == NULL) > > - return -1; > > - > > - memset(pool_tbl, 0, sizeof(pool_table_t)); > > - > > - > > - for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) { > > - /* init locks */ > > - pool_entry_t *pool = &pool_tbl->pool[i]; > > - LOCK_INIT(&pool->s.lock); > > - pool->s.pool = i; > > - > > - pool_entry_ptr[i] = pool; > > - } > > - > > - ODP_DBG("\nBuffer pool init global\n"); > > - ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct > pool_entry_s)); > > - ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t)); > > - ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t)); > > - ODP_DBG("\n"); > > - > > - return 0; > > -} > > - > > - > > -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; > > - 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, 32, > > - sizeof(struct rte_pktmbuf_pool_private), > > - rte_pktmbuf_pool_init, NULL, > > - rte_pktmbuf_init, NULL, > > - rte_socket_id(), 0); > > - if (pktmbuf_pool == NULL) { > > - ODP_ERR("Cannot init DPDK mbuf pool\n"); > > - return -1; > > - } > > - > > - return (odp_buffer_pool_t) pktmbuf_pool; > > -} > > - > > - > > -odp_buffer_pool_t odp_buffer_pool_lookup(const char *name) > > -{ > > - struct rte_mempool *mp = NULL; > > - > > - mp = rte_mempool_lookup(name); > > - if (mp == NULL) > > - return ODP_BUFFER_POOL_INVALID; > > - > > - return (odp_buffer_pool_t)mp; > > -} > > - > > - > > -odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id) > > -{ > > - return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool > *)pool_id); > > -} > > - > > - > > -void odp_buffer_free(odp_buffer_t buf) > > -{ > > - rte_pktmbuf_free((struct rte_mbuf *)buf); > > -} > > - > > - > > -void odp_buffer_pool_print(odp_buffer_pool_t pool_id) > > -{ > > - rte_mempool_dump((const struct rte_mempool *)pool_id); > > -} > > diff --git a/platform/linux-dpdk/source/odp_init.c > b/platform/linux-dpdk/source/odp_init.c > > deleted file mode 100644 > > index ecc2066..0000000 > > --- a/platform/linux-dpdk/source/odp_init.c > > +++ /dev/null > > @@ -1,113 +0,0 @@ > > -/* Copyright (c) 2013, Linaro Limited > > - * All rights reserved. > > - * > > - * SPDX-License-Identifier: BSD-3-Clause > > - */ > > - > > -#include <odp_init.h> > > -#include <odp_internal.h> > > -#include <odp_debug.h> > > -#include <odp_packet_dpdk.h> > > - > > -int odp_init_dpdk(void) > > -{ > > - int test_argc = 5; > > - char *test_argv[6]; > > - int core_count, i, num_cores = 0; > > - char core_mask[8]; > > - > > - core_count = odp_sys_core_count(); > > - for (i = 0; i < core_count; i++) > > - num_cores += (0x1 << i); > > - sprintf(core_mask, "%x", num_cores); > > - > > - test_argv[0] = malloc(sizeof("odp_dpdk")); > > - strcpy(test_argv[0], "odp_dpdk"); > > - test_argv[1] = malloc(sizeof("-c")); > > - strcpy(test_argv[1], "-c"); > > - test_argv[2] = malloc(sizeof(core_mask)); > > - strcpy(test_argv[2], core_mask); > > - test_argv[3] = malloc(sizeof("-n")); > > - strcpy(test_argv[3], "-n"); > > - test_argv[4] = malloc(sizeof("3")); > > - strcpy(test_argv[4], "3"); > > - > > - if (rte_eal_init(test_argc, (char **)test_argv) < 0) { > > - ODP_ERR("Cannot init the Intel DPDK EAL!"); > > - return -1; > > - } > > - > > - if (rte_pmd_init_all() < 0) { > > - ODP_ERR("Cannot init pmd\n"); > > - return -1; > > - } > > - > > - if (rte_eal_pci_probe() < 0) { > > - ODP_ERR("Cannot probe PCI\n"); > > - return -1; > > - } > > - > > - return 0; > > -} > > - > > -int odp_init_global(void) > > -{ > > - odp_thread_init_global(); > > - > > - odp_system_info_init(); > > - > > - if (odp_init_dpdk()) { > > - ODP_ERR("ODP dpdk init failed.\n"); > > - return -1; > > - } > > - > > - if (odp_shm_init_global()) { > > - ODP_ERR("ODP shm init failed.\n"); > > - return -1; > > - } > > - > > - if (odp_buffer_pool_init_global()) { > > - ODP_ERR("ODP buffer pool init failed.\n"); > > - return -1; > > - } > > - > > - if (odp_queue_init_global()) { > > - ODP_ERR("ODP queue init failed.\n"); > > - return -1; > > - } > > - > > - if (odp_schedule_init_global()) { > > - ODP_ERR("ODP schedule init failed.\n"); > > - return -1; > > - } > > - > > - if (odp_pktio_init_global()) { > > - ODP_ERR("ODP packet io init failed.\n"); > > - return -1; > > - } > > - > > - if (odp_timer_init_global()) { > > - ODP_ERR("ODP timer init failed.\n"); > > - return -1; > > - } > > - > > - return 0; > > -} > > - > > - > > -int odp_init_local(int thr_id) > > -{ > > - odp_thread_init_local(thr_id); > > - > > - if (odp_pktio_init_local()) { > > - ODP_ERR("ODP packet io local init failed.\n"); > > - return -1; > > - } > > - > > - if (odp_schedule_init_local()) { > > - ODP_ERR("ODP schedule local init failed.\n"); > > - return -1; > > - } > > - > > - return 0; > > -} > > diff --git a/platform/linux-dpdk/source/odp_packet.c > b/platform/linux-dpdk/source/odp_packet.c > > deleted file mode 100644 > > index c34e626..0000000 > > --- a/platform/linux-dpdk/source/odp_packet.c > > +++ /dev/null > > @@ -1,374 +0,0 @@ > > -/* Copyright (c) 2013, Linaro Limited > > - * All rights reserved. > > - * > > - * SPDX-License-Identifier: BSD-3-Clause > > - */ > > - > > -#include <odp_packet.h> > > -#include <odp_packet_internal.h> > > -#include <odp_hints.h> > > -#include <odp_byteorder.h> > > - > > -#include <helper/odp_eth.h> > > -#include <helper/odp_ip.h> > > - > > -#include <string.h> > > -#include <stdio.h> > > - > > -static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, > odp_ipv4hdr_t *ipv4, > > - size_t *offset_out); > > -static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, > odp_ipv6hdr_t *ipv6, > > - size_t *offset_out); > > - > > -void odp_packet_init(odp_packet_t pkt) > > -{ > > - odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > > - const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, > buf_hdr); > > - uint8_t *start; > > - size_t len; > > - > > - start = (uint8_t *)pkt_hdr + start_offset; > > - len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > > - memset(start, 0, len); > > - > > - pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > > - pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > > - pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; > > -} > > - > > -odp_packet_t odp_packet_from_buffer(odp_buffer_t buf) > > -{ > > - return (odp_packet_t)buf; > > -} > > - > > -odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt) > > -{ > > - return (odp_buffer_t)pkt; > > -} > > - > > -void odp_packet_set_len(odp_packet_t pkt, size_t len) > > -{ > > - /* for rte_pktmbuf */ > > - odp_buffer_hdr_t *buf_hdr = > odp_buf_to_hdr(odp_buffer_from_packet(pkt)); > > - buf_hdr->pkt.data_len = len; > > - > > - odp_packet_hdr(pkt)->frame_len = len; > > -} > > - > > -size_t odp_packet_get_len(odp_packet_t pkt) > > -{ > > - return odp_packet_hdr(pkt)->frame_len; > > -} > > - > > -uint8_t *odp_packet_buf_addr(odp_packet_t pkt) > > -{ > > - return odp_buffer_addr(odp_buffer_from_packet(pkt)); > > -} > > - > > -uint8_t *odp_packet_start(odp_packet_t pkt) > > -{ > > - return odp_packet_buf_addr(pkt) + > odp_packet_hdr(pkt)->frame_offset; > > -} > > - > > - > > -uint8_t *odp_packet_l2(odp_packet_t pkt) > > -{ > > - const size_t offset = odp_packet_l2_offset(pkt); > > - > > - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > > - return NULL; > > - > > - return odp_packet_buf_addr(pkt) + offset; > > -} > > - > > -size_t odp_packet_l2_offset(odp_packet_t pkt) > > -{ > > - return odp_packet_hdr(pkt)->l2_offset; > > -} > > - > > -void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset) > > -{ > > - odp_packet_hdr(pkt)->l2_offset = offset; > > -} > > - > > -uint8_t *odp_packet_l3(odp_packet_t pkt) > > -{ > > - const size_t offset = odp_packet_l3_offset(pkt); > > - > > - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > > - return NULL; > > - > > - return odp_packet_buf_addr(pkt) + offset; > > -} > > - > > -size_t odp_packet_l3_offset(odp_packet_t pkt) > > -{ > > - return odp_packet_hdr(pkt)->l3_offset; > > -} > > - > > -void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset) > > -{ > > - odp_packet_hdr(pkt)->l3_offset = offset; > > -} > > - > > -uint8_t *odp_packet_l4(odp_packet_t pkt) > > -{ > > - const size_t offset = odp_packet_l4_offset(pkt); > > - > > - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) > > - return NULL; > > - > > - return odp_packet_buf_addr(pkt) + offset; > > -} > > - > > -size_t odp_packet_l4_offset(odp_packet_t pkt) > > -{ > > - return odp_packet_hdr(pkt)->l4_offset; > > -} > > - > > -void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset) > > -{ > > - odp_packet_hdr(pkt)->l4_offset = offset; > > -} > > - > > -/** > > - * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP > > - * > > - * Internal function: caller is resposible for passing only valid > packet handles > > - * , lengths and offsets (usually done&called in packet input). > > - * > > - * @param pkt Packet handle > > - * @param len Packet length in bytes > > - * @param frame_offset Byte offset to L2 header > > - */ > > -void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset) > > -{ > > - odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); > > - odp_ethhdr_t *eth; > > - odp_vlanhdr_t *vlan; > > - odp_ipv4hdr_t *ipv4; > > - odp_ipv6hdr_t *ipv6; > > - uint16_t ethtype; > > - size_t offset = 0; > > - uint8_t ip_proto = 0; > > - > > - pkt_hdr->input_flags.eth = 1; > > - pkt_hdr->frame_offset = frame_offset; > > - pkt_hdr->frame_len = len; > > - > > - if (odp_unlikely(len < ODP_ETH_LEN_MIN)) { > > - pkt_hdr->error_flags.frame_len = 1; > > - return; > > - } else if (len > ODP_ETH_LEN_MAX) { > > - pkt_hdr->input_flags.jumbo = 1; > > - } > > - > > - /* Assume valid L2 header, no CRC/FCS check in SW */ > > - pkt_hdr->input_flags.l2 = 1; > > - pkt_hdr->l2_offset = frame_offset; > > - > > - eth = (odp_ethhdr_t *)odp_packet_start(pkt); > > - ethtype = odp_be_to_cpu_16(eth->type); > > - vlan = (odp_vlanhdr_t *)ð->type; > > - > > - if (ethtype == ODP_ETHTYPE_VLAN_OUTER) { > > - pkt_hdr->input_flags.vlan_qinq = 1; > > - ethtype = odp_be_to_cpu_16(vlan->tpid); > > - offset += sizeof(odp_vlanhdr_t); > > - vlan = &vlan[1]; > > - } > > - > > - if (ethtype == ODP_ETHTYPE_VLAN) { > > - pkt_hdr->input_flags.vlan = 1; > > - ethtype = odp_be_to_cpu_16(vlan->tpid); > > - offset += sizeof(odp_vlanhdr_t); > > - } > > - > > - /* Set l3_offset+flag only for known ethtypes */ > > - switch (ethtype) { > > - case ODP_ETHTYPE_IPV4: > > - pkt_hdr->input_flags.ipv4 = 1; > > - pkt_hdr->input_flags.l3 = 1; > > - pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + > offset; > > - ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt); > > - ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset); > > - break; > > - case ODP_ETHTYPE_IPV6: > > - pkt_hdr->input_flags.ipv6 = 1; > > - pkt_hdr->input_flags.l3 = 1; > > - pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + > offset; > > - ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt); > > - ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset); > > - break; > > - case ODP_ETHTYPE_ARP: > > - pkt_hdr->input_flags.arp = 1; > > - /* fall through */ > > - default: > > - ip_proto = 0; > > - break; > > - } > > - > > - switch (ip_proto) { > > - case ODP_IPPROTO_UDP: > > - pkt_hdr->input_flags.udp = 1; > > - pkt_hdr->input_flags.l4 = 1; > > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > - break; > > - case ODP_IPPROTO_TCP: > > - pkt_hdr->input_flags.tcp = 1; > > - pkt_hdr->input_flags.l4 = 1; > > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > - break; > > - case ODP_IPPROTO_SCTP: > > - pkt_hdr->input_flags.sctp = 1; > > - pkt_hdr->input_flags.l4 = 1; > > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > - break; > > - case ODP_IPPROTO_ICMP: > > - pkt_hdr->input_flags.icmp = 1; > > - pkt_hdr->input_flags.l4 = 1; > > - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; > > - break; > > - default: > > - /* 0 or unhandled IP protocols, don't set L4 flag+offset */ > > - if (pkt_hdr->input_flags.ipv6) { > > - /* IPv6 next_hdr is not L4, mark as IP-option > instead */ > > - pkt_hdr->input_flags.ipopt = 1; > > - } > > - break; > > - } > > -} > > - > > -static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, > odp_ipv4hdr_t *ipv4, > > - size_t *offset_out) > > -{ > > - uint8_t ihl; > > - uint16_t frag_offset; > > - > > - ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl); > > - if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) { > > - pkt_hdr->error_flags.ip_err = 1; > > - return 0; > > - } > > - > > - if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) { > > - pkt_hdr->input_flags.ipopt = 1; > > - return 0; > > - } > > - > > - /* A packet is a fragment if: > > - * "more fragments" flag is set (all fragments except the last) > > - * OR > > - * "fragment offset" field is nonzero (all fragments except the > first) > > - */ > > - frag_offset = odp_be_to_cpu_16(ipv4->frag_offset); > > - if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) { > > - pkt_hdr->input_flags.ipfrag = 1; > > - return 0; > > - } > > - > > - if (ipv4->proto == ODP_IPPROTO_ESP || > > - ipv4->proto == ODP_IPPROTO_AH) { > > - pkt_hdr->input_flags.ipsec = 1; > > - return 0; > > - } > > - > > - /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after > return */ > > - > > - *offset_out = sizeof(uint32_t) * ihl; > > - return ipv4->proto; > > -} > > - > > -static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, > odp_ipv6hdr_t *ipv6, > > - size_t *offset_out) > > -{ > > - if (ipv6->next_hdr == ODP_IPPROTO_ESP || > > - ipv6->next_hdr == ODP_IPPROTO_AH) { > > - pkt_hdr->input_flags.ipopt = 1; > > - pkt_hdr->input_flags.ipsec = 1; > > - return 0; > > - } > > - > > - if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) { > > - pkt_hdr->input_flags.ipopt = 1; > > - pkt_hdr->input_flags.ipfrag = 1; > > - return 0; > > - } > > - > > - /* Don't step through more extensions */ > > - *offset_out = ODP_IPV6HDR_LEN; > > - return ipv6->next_hdr; > > -} > > - > > -void odp_packet_print(odp_packet_t pkt) > > -{ > > - int max_len = 512; > > - char str[max_len]; > > - int len = 0; > > - int n = max_len-1; > > - odp_packet_hdr_t *hdr = odp_packet_hdr(pkt); > > - > > - len += snprintf(&str[len], n-len, "Packet "); > > - len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt); > > - len += snprintf(&str[len], n-len, > > - " input_flags 0x%x\n", hdr->input_flags.all); > > - len += snprintf(&str[len], n-len, > > - " error_flags 0x%x\n", hdr->error_flags.all); > > - len += snprintf(&str[len], n-len, > > - " output_flags 0x%x\n", hdr->output_flags.all); > > - len += snprintf(&str[len], n-len, > > - " frame_offset %u\n", hdr->frame_offset); > > - len += snprintf(&str[len], n-len, > > - " l2_offset %u\n", hdr->l2_offset); > > - len += snprintf(&str[len], n-len, > > - " l3_offset %u\n", hdr->l3_offset); > > - len += snprintf(&str[len], n-len, > > - " l4_offset %u\n", hdr->l4_offset); > > - len += snprintf(&str[len], n-len, > > - " frame_len %u\n", hdr->frame_len); > > - len += snprintf(&str[len], n-len, > > - " input %u\n", hdr->input); > > - str[len] = '\0'; > > - > > - printf("\n%s\n", str); > > -} > > - > > -int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src) > > -{ > > - odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst); > > - odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src); > > - const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, > buf_hdr); > > - uint8_t *start_src; > > - uint8_t *start_dst; > > - size_t len; > > - > > - if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID) > > - return -1; > > - > > - /* if (pkt_hdr_dst->buf_hdr.size < */ > > - /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */ > > - if (pkt_hdr_dst->buf_hdr.buf_len < > > - pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) > > - return -1; > > - > > - /* Copy packet header */ > > - start_dst = (uint8_t *)pkt_hdr_dst + start_offset; > > - start_src = (uint8_t *)pkt_hdr_src + start_offset; > > - len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; > > - memcpy(start_dst, start_src, len); > > - > > - /* Copy frame payload */ > > - start_dst = (uint8_t *)odp_packet_start(pkt_dst); > > - start_src = (uint8_t *)odp_packet_start(pkt_src); > > - len = pkt_hdr_src->frame_len; > > - memcpy(start_dst, start_src, len); > > - > > - /* Copy useful things from the buffer header */ > > - /* pkt_hdr_dst->buf_hdr.cur_offset = > pkt_hdr_src->buf_hdr.cur_offset; */ > > - > > - /* Create a copy of the scatter list */ > > - /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */ > > - /* odp_buffer_from_packet(pkt_src)); */ > > - > > - return 0; > > -} > > diff --git a/platform/linux-dpdk/source/odp_packet_dpdk.c > b/platform/linux-dpdk/source/odp_packet_dpdk.c > > deleted file mode 100644 > > index 6d16bbe..0000000 > > --- a/platform/linux-dpdk/source/odp_packet_dpdk.c > > +++ /dev/null > > @@ -1,177 +0,0 @@ > > -/* Copyright (c) 2013, Linaro Limited > > - * All rights reserved. > > - * > > - * SPDX-License-Identifier: BSD-3-Clause > > - */ > > - > > -#define _GNU_SOURCE > > -#include <stdio.h> > > -#include <errno.h> > > -#include <sys/types.h> > > -#include <sys/stat.h> > > -#include <sys/ioctl.h> > > -#include <sys/mman.h> > > -#include <poll.h> > > -#include <unistd.h> > > -#include <fcntl.h> > > -#include <string.h> > > -#include <stdlib.h> > > - > > -#include <linux/ethtool.h> > > -#include <linux/sockios.h> > > - > > -#include <odp_hints.h> > > -#include <odp_thread.h> > > - > > -#include <odp_packet_dpdk.h> > > -#include <net/if.h> > > - > > -/* > > - * RX and TX Prefetch, Host, and Write-back threshold values should be > > - * carefully set for optimal performance. Consult the network > > - * controller's datasheet and supporting DPDK documentation for guidance > > - * on how these parameters should be set. > > - */ > > -#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. > */ > > -#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ > > -#define RX_WTHRESH 4 /**< Default values of RX write-back threshold > reg. */ > > - > > -/* > > - * These default values are optimized for use with the Intel(R) 82599 > 10 GbE > > - * Controller and the DPDK ixgbe PMD. Consider using other values for > other > > - * network controllers and/or network drivers. > > - */ > > -#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. > */ > > -#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ > > -#define TX_WTHRESH 0 /**< Default values of TX write-back threshold > reg. */ > > - > > -#define MAX_PKT_BURST 32 > > -#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ > > -#define RTE_TEST_RX_DESC_DEFAULT 128 > > -#define RTE_TEST_TX_DESC_DEFAULT 512 > > -static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; > > -static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; > > - > > -static const struct rte_eth_conf port_conf = { > > - .rxmode = { > > - .split_hdr_size = 0, > > - .header_split = 0, /**< Header Split disabled */ > > - .hw_ip_checksum = 0, /**< IP checksum offload disabled */ > > - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ > > - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ > > - .hw_strip_crc = 0, /**< CRC stripped by hardware */ > > - }, > > - .txmode = { > > - .mq_mode = ETH_MQ_TX_NONE, > > - }, > > -}; > > - > > -static const struct rte_eth_rxconf rx_conf = { > > - .rx_thresh = { > > - .pthresh = RX_PTHRESH, > > - .hthresh = RX_HTHRESH, > > - .wthresh = RX_WTHRESH, > > - }, > > -}; > > - > > -static const struct rte_eth_txconf tx_conf = { > > - .tx_thresh = { > > - .pthresh = TX_PTHRESH, > > - .hthresh = TX_HTHRESH, > > - .wthresh = TX_WTHRESH, > > - }, > > - .tx_free_thresh = 0, /* Use PMD default values */ > > - .tx_rs_thresh = 0, /* Use PMD default values */ > > - /* > > - * As the example won't handle mult-segments and offload cases, > > - * set the flag by default. > > - */ > > - .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS, > > -}; > > - > > -int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, > > - odp_buffer_pool_t pool) > > -{ > > - ODP_DBG("setup_pkt_dpdk\n"); > > - > > - static struct ether_addr eth_addr[RTE_MAX_ETHPORTS]; > > - uint8_t portid = 0; > > - uint16_t queueid = 0; > > - int ret; > > - printf("vincent netdev: %s\n", netdev); > > - printf("vincent pool: %lx\n", pool); > > - > > - portid = atoi(netdev); > > - pkt_dpdk->portid = portid; > > - pkt_dpdk->queueid = queueid; > > - pkt_dpdk->pool = pool; > > - printf("vincent portid: %u\n", portid); > > - > > - fflush(stdout); > > - ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); > > - if (ret < 0) > > - ODP_ERR("Cannot configure device: err=%d, port=%u\n", > > - ret, (unsigned) portid); > > - > > - rte_eth_macaddr_get(portid, ð_addr[portid]); > > - ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", > > - (unsigned) portid, > > - eth_addr[portid].addr_bytes[0], > > - eth_addr[portid].addr_bytes[1], > > - eth_addr[portid].addr_bytes[2], > > - eth_addr[portid].addr_bytes[3], > > - eth_addr[portid].addr_bytes[4], > > - eth_addr[portid].addr_bytes[5]); > > - > > - /* init one RX queue on each port */ > > - fflush(stdout); > > - ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd, > > - rte_eth_dev_socket_id(portid), > &rx_conf, > > - (struct rte_mempool *)pool); > > - if (ret < 0) > > - ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n", > > - ret, (unsigned) portid); > > - ODP_DBG("dpdk rx queue setup done\n"); > > - > > - /* init one TX queue on each port */ > > - fflush(stdout); > > - ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, > > - rte_eth_dev_socket_id(portid), &tx_conf); > > - if (ret < 0) > > - ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n", > > - ret, (unsigned) portid); > > - ODP_DBG("dpdk tx queue setup done\n"); > > - > > - /* Start device */ > > - ret = rte_eth_dev_start(portid); > > - if (ret < 0) > > - ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n", > > - ret, (unsigned) portid); > > - ODP_DBG("dpdk setup done\n\n"); > > - > > - > > - return 0; > > -} > > - > > -int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk) > > -{ > > - ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid); > > - > > - return 0; > > -} > > - > > -int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > > - unsigned len) > > -{ > > - return rte_eth_rx_burst((uint8_t)pkt_dpdk->portid, > > - (uint16_t)pkt_dpdk->queueid, > > - (struct rte_mbuf **)pkt_table, > (uint16_t)len); > > -} > > - > > -int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > > - unsigned len) > > -{ > > - return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid, > > - (uint16_t)pkt_dpdk->queueid, > > - (struct rte_mbuf **)pkt_table, > (uint16_t)len); > > -} > > diff --git a/platform/linux-dpdk/source/odp_packet_io.c > b/platform/linux-dpdk/source/odp_packet_io.c > > deleted file mode 100644 > > index abea0ec..0000000 > > --- a/platform/linux-dpdk/source/odp_packet_io.c > > +++ /dev/null > > @@ -1,561 +0,0 @@ > > -/* Copyright (c) 2013, Linaro Limited > > - * All rights reserved. > > - * > > - * SPDX-License-Identifier: BSD-3-Clause > > - */ > > - > > -#include <odp_packet_io.h> > > -#include <odp_packet_io_internal.h> > > -#include <odp_packet_io_queue.h> > > -#include <odp_packet.h> > > -#include <odp_packet_internal.h> > > -#include <odp_internal.h> > > -#include <odp_spinlock.h> > > -#include <odp_shared_memory.h> > > -#include <odp_packet_socket.h> > > -#ifdef ODP_HAVE_NETMAP > > -#include <odp_packet_netmap.h> > > -#endif > > -#include <odp_hints.h> > > -#include <odp_config.h> > > -#include <odp_queue_internal.h> > > -#include <odp_schedule_internal.h> > > -#include <odp_debug.h> > > - > > -#include <odp_pktio_socket.h> > > -#ifdef ODP_HAVE_NETMAP > > -#include <odp_pktio_netmap.h> > > -#endif > > - > > -#include <string.h> > > - > > -typedef struct { > > - pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; > > -} pktio_table_t; > > - > > -static pktio_table_t *pktio_tbl; > > - > > - > > -static pktio_entry_t *get_entry(odp_pktio_t id) > > -{ > > - if (odp_unlikely(id == ODP_PKTIO_INVALID || > > - id > ODP_CONFIG_PKTIO_ENTRIES)) > > - return NULL; > > - > > - return &pktio_tbl->entries[id - 1]; > > -} > > - > > -int odp_pktio_init_global(void) > > -{ > > - char name[ODP_QUEUE_NAME_LEN]; > > - pktio_entry_t *pktio_entry; > > - queue_entry_t *queue_entry; > > - odp_queue_t qid; > > - int id; > > - > > - pktio_tbl = odp_shm_reserve("odp_pktio_entries", > > - sizeof(pktio_table_t), > > - sizeof(pktio_entry_t)); > > - if (pktio_tbl == NULL) > > - return -1; > > - > > - memset(pktio_tbl, 0, sizeof(pktio_table_t)); > > - > > - for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) { > > - pktio_entry = get_entry(id); > > - > > - odp_spinlock_init(&pktio_entry->s.lock); > > - > > - /* Create a default output queue for each pktio resource */ > > - snprintf(name, sizeof(name), "%i-pktio_outq_default", > (int)id); > > - name[ODP_QUEUE_NAME_LEN-1] = '\0'; > > - > > - qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL); > > - if (qid == ODP_QUEUE_INVALID) > > - return -1; > > - pktio_entry->s.outq_default = qid; > > - > > - queue_entry = queue_to_qentry(qid); > > - queue_entry->s.pktout = id; > > - } > > - > > - return 0; > > -} > > - > > -int odp_pktio_init_local(void) > > -{ > > - return 0; > > -} > > - > > -static int is_free(pktio_entry_t *entry) > > -{ > > - return (entry->s.taken == 0); > > -} > > - > > -static void set_free(pktio_entry_t *entry) > > -{ > > - entry->s.taken = 0; > > -} > > - > > -static void set_taken(pktio_entry_t *entry) > > -{ > > - entry->s.taken = 1; > > -} > > - > > -static void lock_entry(pktio_entry_t *entry) > > -{ > > - odp_spinlock_lock(&entry->s.lock); > > -} > > - > > -static void unlock_entry(pktio_entry_t *entry) > > -{ > > - odp_spinlock_unlock(&entry->s.lock); > > -} > > - > > -static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t > *params) > > -{ > > - set_taken(entry); > > - entry->s.inq_default = ODP_QUEUE_INVALID; > > - switch (params->type) { > > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > > - memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); > > - memset(&entry->s.pkt_sock_mmap, 0, > > - sizeof(entry->s.pkt_sock_mmap)); > > - break; > > -#ifdef ODP_HAVE_NETMAP > > - case ODP_PKTIO_TYPE_NETMAP: > > - memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); > > - break; > > -#endif > > - case ODP_PKTIO_TYPE_DPDK: > > - memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk)); > > - break; > > - default: > > - ODP_ERR("Packet I/O type not supported. Please > recompile\n"); > > - break; > > - } > > - /* Save pktio parameters, type is the most useful */ > > - memcpy(&entry->s.params, params, sizeof(*params)); > > -} > > - > > -static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params) > > -{ > > - odp_pktio_t id; > > - pktio_entry_t *entry; > > - int i; > > - > > - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { > > - entry = &pktio_tbl->entries[i]; > > - if (is_free(entry)) { > > - lock_entry(entry); > > - if (is_free(entry)) { > > - init_pktio_entry(entry, params); > > - id = i + 1; > > - return id; /* return with entry locked! */ > > - } > > - unlock_entry(entry); > > - } > > - } > > - > > - return ODP_PKTIO_INVALID; > > -} > > - > > -static int free_pktio_entry(odp_pktio_t id) > > -{ > > - pktio_entry_t *entry = get_entry(id); > > - > > - if (entry == NULL) > > - return -1; > > - > > - set_free(entry); > > - > > - return 0; > > -} > > - > > -odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool, > > - odp_pktio_params_t *params) > > -{ > > - odp_pktio_t id; > > - pktio_entry_t *pktio_entry; > > - int res; > > - > > - if (params == NULL) { > > - ODP_ERR("Invalid pktio params\n"); > > - return ODP_PKTIO_INVALID; > > - } > > - > > - switch (params->type) { > > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > > - ODP_DBG("Allocating socket pktio\n"); > > - break; > > -#ifdef ODP_HAVE_NETMAP > > - case ODP_PKTIO_TYPE_NETMAP: > > - ODP_DBG("Allocating netmap pktio\n"); > > - break; > > -#endif > > - case ODP_PKTIO_TYPE_DPDK: > > - ODP_DBG("Allocating dpdk pktio\n"); > > - break; > > - default: > > - ODP_ERR("Invalid pktio type: %02x\n", params->type); > > - return ODP_PKTIO_INVALID; > > - } > > - > > - id = alloc_lock_pktio_entry(params); > > - if (id == ODP_PKTIO_INVALID) { > > - ODP_ERR("No resources available.\n"); > > - return ODP_PKTIO_INVALID; > > - } > > - /* if successful, alloc_pktio_entry() returns with the entry > locked */ > > - > > - pktio_entry = get_entry(id); > > - > > - switch (params->type) { > > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > > - res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); > > - if (res == -1) { > > - close_pkt_sock(&pktio_entry->s.pkt_sock); > > - free_pktio_entry(id); > > - id = ODP_PKTIO_INVALID; > > - } > > - break; > > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > > - res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > dev, > > - pool, params->sock_params.fanout); > > - if (res == -1) { > > - close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); > > - free_pktio_entry(id); > > - id = ODP_PKTIO_INVALID; > > - } > > - break; > > -#ifdef ODP_HAVE_NETMAP > > - case ODP_PKTIO_TYPE_NETMAP: > > - > > - res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, > > - pool, ¶ms->nm_params); > > - if (res == -1) { > > - close_pkt_netmap(&pktio_entry->s.pkt_nm); > > - free_pktio_entry(id); > > - id = ODP_PKTIO_INVALID; > > - } > > - break; > > -#endif > > - case ODP_PKTIO_TYPE_DPDK: > > - res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool); > > - if (res == -1) { > > - close_pkt_dpdk(&pktio_entry->s.pkt_dpdk); > > - free_pktio_entry(id); > > - id = ODP_PKTIO_INVALID; > > - } > > - break; > > - default: > > - free_pktio_entry(id); > > - id = ODP_PKTIO_INVALID; > > - ODP_ERR("Invalid pktio type. Please recompile.\n"); > > - break; > > - } > > - > > - unlock_entry(pktio_entry); > > - return id; > > -} > > - > > -int odp_pktio_close(odp_pktio_t id) > > -{ > > - pktio_entry_t *entry; > > - int res = -1; > > - > > - entry = get_entry(id); > > - if (entry == NULL) > > - return -1; > > - > > - lock_entry(entry); > > - if (!is_free(entry)) { > > - switch (entry->s.params.type) { > > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > > - res = close_pkt_sock(&entry->s.pkt_sock); > > - break; > > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > > - res = > close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); > > - break; > > -#ifdef ODP_HAVE_NETMAP > > - case ODP_PKTIO_TYPE_NETMAP: > > - res = close_pkt_netmap(&entry->s.pkt_nm); > > - break; > > -#endif > > - case ODP_PKTIO_TYPE_DPDK: > > - res = close_pkt_dpdk(&entry->s.pkt_dpdk); > > - break; > > - default: > > - break; > > - res |= free_pktio_entry(id); > > - } > > - } > > - unlock_entry(entry); > > - > > - if (res != 0) > > - return -1; > > - > > - return 0; > > -} > > - > > -void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio) > > -{ > > - odp_packet_hdr(pkt)->input = pktio; > > -} > > - > > -odp_pktio_t odp_pktio_get_input(odp_packet_t pkt) > > -{ > > - return odp_packet_hdr(pkt)->input; > > -} > > - > > -int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned > len) > > -{ > > - pktio_entry_t *pktio_entry = get_entry(id); > > - int pkts; > > - int i; > > - > > - if (pktio_entry == NULL) > > - return -1; > > - > > - lock_entry(pktio_entry); > > - switch (pktio_entry->s.params.type) { > > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > > - pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, > > - pkt_table, len); > > - break; > > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > > - pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > > - pkt_table, len); > > - break; > > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > > - pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > > - pkt_table, len); > > - break; > > -#ifdef ODP_HAVE_NETMAP > > - case ODP_PKTIO_TYPE_NETMAP: > > - pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, > len); > > - break; > > -#endif > > - case ODP_PKTIO_TYPE_DPDK: > > - pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, > len); > > - break; > > - default: > > - pkts = -1; > > - break; > > - } > > - > > - unlock_entry(pktio_entry); > > - if (pkts < 0) > > - return pkts; > > - > > - for (i = 0; i < pkts; ++i) > > - odp_pktio_set_input(pkt_table[i], id); > > - > > - return pkts; > > -} > > - > > -int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned > len) > > -{ > > - pktio_entry_t *pktio_entry = get_entry(id); > > - int pkts; > > - > > - if (pktio_entry == NULL) > > - return -1; > > - > > - lock_entry(pktio_entry); > > - switch (pktio_entry->s.params.type) { > > - case ODP_PKTIO_TYPE_SOCKET_BASIC: > > - pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, > > - pkt_table, len); > > - break; > > - case ODP_PKTIO_TYPE_SOCKET_MMSG: > > - pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > > - pkt_table, len); > > - break; > > - case ODP_PKTIO_TYPE_SOCKET_MMAP: > > - pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > > - pkt_table, len); > > - break; > > -#ifdef ODP_HAVE_NETMAP > > - case ODP_PKTIO_TYPE_NETMAP: > > - pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, > > - pkt_table, len); > > - break; > > -#endif > > - case ODP_PKTIO_TYPE_DPDK: > > - pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk, > > - pkt_table, len); > > - break; > > - default: > > - pkts = -1; > > - } > > - unlock_entry(pktio_entry); > > - > > - return pkts; > > -} > > - > > -int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue) > > -{ > > - pktio_entry_t *pktio_entry = get_entry(id); > > - queue_entry_t *qentry = queue_to_qentry(queue); > > - > > - if (pktio_entry == NULL || qentry == NULL) > > - return -1; > > - > > - if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN) > > - return -1; > > - > > - lock_entry(pktio_entry); > > - pktio_entry->s.inq_default = queue; > > - unlock_entry(pktio_entry); > > - > > - queue_lock(qentry); > > - qentry->s.pktin = id; > > - qentry->s.status = QUEUE_STATUS_SCHED; > > - queue_unlock(qentry); > > - > > - odp_schedule_queue(queue, qentry->s.param.sched.prio); > > - > > - return 0; > > -} > > - > > -int odp_pktio_inq_remdef(odp_pktio_t id) > > -{ > > - return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID); > > -} > > - > > -odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id) > > -{ > > - pktio_entry_t *pktio_entry = get_entry(id); > > - > > - if (pktio_entry == NULL) > > - return ODP_QUEUE_INVALID; > > - > > - return pktio_entry->s.inq_default; > > -} > > - > > -odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id) > > -{ > > - pktio_entry_t *pktio_entry = get_entry(id); > > - > > - if (pktio_entry == NULL) > > - return ODP_QUEUE_INVALID; > > - > > - return pktio_entry->s.outq_default; > > -} > > - > > -int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > > -{ > > - odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr); > > - int len = 1; > > - int nbr; > > - > > - nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); > > - return (nbr == len ? 0 : -1); > > -} > > - > > -odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry) > > -{ > > - (void)qentry; > > - return NULL; > > -} > > - > > -int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > > - int num) > > -{ > > - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > > - int nbr; > > - int i; > > - > > - for (i = 0; i < num; ++i) > > - pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) > buf_hdr[i]); > > - > > - nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > > - return (nbr == num ? 0 : -1); > > -} > > - > > -int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > > - int num) > > -{ > > - (void)qentry; > > - (void)buf_hdr; > > - (void)num; > > - > > - return 0; > > -} > > - > > -int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > > -{ > > - /* Use default action */ > > - return queue_enq(qentry, buf_hdr); > > -} > > - > > -odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry) > > -{ > > - odp_buffer_hdr_t *buf_hdr; > > - > > - buf_hdr = queue_deq(qentry); > > - > > - if (buf_hdr == NULL) { > > - odp_packet_t pkt; > > - odp_buffer_t buf; > > - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > > - odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > > - int pkts, i, j; > > - > > - pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > > - QUEUE_MULTI_MAX); > > - > > - if (pkts > 0) { > > - pkt = pkt_tbl[0]; > > - buf = odp_buffer_from_packet(pkt); > > - buf_hdr = odp_buf_to_hdr(buf); > > - > > - for (i = 1, j = 0; i < pkts; ++i) { > > - buf = odp_buffer_from_packet(pkt_tbl[i]); > > - tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf); > > - } > > - queue_enq_multi(qentry, tmp_hdr_tbl, j); > > - } > > - } > > - > > - return buf_hdr; > > -} > > - > > -int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > int num) > > -{ > > - /* Use default action */ > > - return queue_enq_multi(qentry, buf_hdr, num); > > -} > > - > > -int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > int num) > > -{ > > - int nbr; > > - > > - nbr = queue_deq_multi(qentry, buf_hdr, num); > > - > > - if (nbr < num) { > > - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; > > - odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; > > - odp_buffer_t buf; > > - int pkts, i; > > - > > - pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, > > - QUEUE_MULTI_MAX); > > - if (pkts > 0) { > > - for (i = 0; i < pkts; ++i) { > > - buf = odp_buffer_from_packet(pkt_tbl[i]); > > - tmp_hdr_tbl[i] = odp_buf_to_hdr(buf); > > - } > > - queue_enq_multi(qentry, tmp_hdr_tbl, pkts); > > - } > > - } > > - > > - return nbr; > > -} > > diff --git a/platform/linux-dpdk/source/odp_queue.c > b/platform/linux-dpdk/source/odp_queue.c > > deleted file mode 100644 > > index 554b8ea..0000000 > > --- a/platform/linux-dpdk/source/odp_queue.c > > +++ /dev/null > > @@ -1,435 +0,0 @@ > > -/* Copyright (c) 2013, Linaro Limited > > - * All rights reserved. > > - * > > - * SPDX-License-Identifier: BSD-3-Clause > > - */ > > - > > -#include <odp_queue.h> > > -#include <odp_queue_internal.h> > > -#include <odp_std_types.h> > > -#include <odp_align.h> > > -#include <odp_buffer.h> > > -#include <odp_buffer_internal.h> > > -#include <odp_buffer_pool_internal.h> > > -#include <odp_internal.h> > > -#include <odp_shared_memory.h> > > -#include <odp_schedule_internal.h> > > -#include <odp_config.h> > > -#include <odp_packet_io_internal.h> > > -#include <odp_packet_io_queue.h> > > -#include <odp_debug.h> > > -#include <odp_hints.h> > > - > > -#ifdef USE_TICKETLOCK > > -#include <odp_ticketlock.h> > > -#define LOCK(a) odp_ticketlock_lock(a) > > -#define UNLOCK(a) odp_ticketlock_unlock(a) > > -#define LOCK_INIT(a) odp_ticketlock_init(a) > > -#else > > -#include <odp_spinlock.h> > > -#define LOCK(a) odp_spinlock_lock(a) > > -#define UNLOCK(a) odp_spinlock_unlock(a) > > -#define LOCK_INIT(a) odp_spinlock_init(a) > > -#endif > > - > > -#include <string.h> > > - > > - > > -typedef struct queue_table_t { > > - queue_entry_t queue[ODP_CONFIG_QUEUES]; > > -} queue_table_t; > > - > > -static queue_table_t *queue_tbl; > > - > > - > > -queue_entry_t *get_qentry(uint32_t queue_id) > > -{ > > - return &queue_tbl->queue[queue_id]; > > -} > > - > > -static void queue_init(queue_entry_t *queue, const char *name, > > - odp_queue_type_t type, odp_queue_param_t *param) > > -{ > > - strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1); > > - queue->s.type = type; > > - > > - if (param) { > > - memcpy(&queue->s.param, param, sizeof(odp_queue_param_t)); > > - } else { > > - /* Defaults */ > > - memset(&queue->s.param, 0, sizeof(odp_queue_param_t)); > > - queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT; > > - queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT; > > - queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT; > > - } > > - > > - switch (type) { > > - case ODP_QUEUE_TYPE_PKTIN: > > - queue->s.enqueue = pktin_enqueue; > > - queue->s.dequeue = pktin_dequeue; > > - queue->s.enqueue_multi = pktin_enq_multi; > > - queue->s.dequeue_multi = pktin_deq_multi; > > - break; > > - case ODP_QUEUE_TYPE_PKTOUT: > > - queue->s.enqueue = pktout_enqueue; > > - queue->s.dequeue = pktout_dequeue; > > - queue->s.enqueue_multi = pktout_enq_multi; > > - queue->s.dequeue_multi = pktout_deq_multi; > > - break; > > - default: > > - queue->s.enqueue = queue_enq; > > - queue->s.dequeue = queue_deq; > > - queue->s.enqueue_multi = queue_enq_multi; > > - queue->s.dequeue_multi = queue_deq_multi; > > - break; > > - } > > - > > - queue->s.head = NULL; > > - queue->s.tail = NULL; > > - queue->s.sched_buf = ODP_BUFFER_INVALID; > > -} > > - > > - > > -int odp_queue_init_global(void) > > -{ > > - uint32_t i; > > - > > - ODP_DBG("Queue init ... "); > > - > > - queue_tbl = odp_shm_reserve("odp_queues", > > - sizeof(queue_table_t), > > - sizeof(queue_entry_t)); > > - > > - if (queue_tbl == NULL) > > - return -1; > > - > > - memset(queue_tbl, 0, sizeof(queue_table_t)); > > - > > - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > > - /* init locks */ > > - queue_entry_t *queue = get_qentry(i); > > - LOCK_INIT(&queue->s.lock); > > - queue->s.handle = queue_from_id(i); > > - } > > - > > - ODP_DBG("done\n"); > > - ODP_DBG("Queue init global\n"); > > - ODP_DBG(" struct queue_entry_s size %zu\n", > > - sizeof(struct queue_entry_s)); > > - ODP_DBG(" queue_entry_t size %zu\n", > > - sizeof(queue_entry_t)); > > - ODP_DBG("\n"); > > - > > - return 0; > > -} > > - > > -odp_queue_type_t odp_queue_type(odp_queue_t handle) > > -{ > > - queue_entry_t *queue; > > - > > - queue = queue_to_qentry(handle); > > - > > - return queue->s.type; > > -} > > - > > -odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle) > > -{ > > - queue_entry_t *queue; > > - > > - queue = queue_to_qentry(handle); > > - > > - return queue->s.param.sched.sync; > > -} > > - > > -odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type, > > - odp_queue_param_t *param) > > -{ > > - uint32_t i; > > - queue_entry_t *queue; > > - odp_queue_t handle = ODP_QUEUE_INVALID; > > - > > - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > > - queue = &queue_tbl->queue[i]; > > - > > - if (queue->s.status != QUEUE_STATUS_FREE) > > - continue; > > - > > - LOCK(&queue->s.lock); > > - if (queue->s.status == QUEUE_STATUS_FREE) { > > - queue_init(queue, name, type, param); > > - > > - if (type == ODP_QUEUE_TYPE_SCHED || > > - type == ODP_QUEUE_TYPE_PKTIN) > > - queue->s.status = QUEUE_STATUS_NOTSCHED; > > - else > > - queue->s.status = QUEUE_STATUS_READY; > > - > > - handle = queue->s.handle; > > - UNLOCK(&queue->s.lock); > > - break; > > - } > > - UNLOCK(&queue->s.lock); > > - } > > - > > - if (handle != ODP_QUEUE_INVALID && > > - (type == ODP_QUEUE_TYPE_SCHED || type == > ODP_QUEUE_TYPE_PKTIN)) { > > - odp_buffer_t buf; > > - > > - buf = odp_schedule_buffer_alloc(handle); > > - if (buf == ODP_BUFFER_INVALID) { > > - ODP_ERR("queue_init: sched buf alloc failed\n"); > > - return ODP_QUEUE_INVALID; > > - } > > - > > - queue->s.sched_buf = buf; > > - odp_schedule_mask_set(handle, queue->s.param.sched.prio); > > - } > > - > > - return handle; > > -} > > - > > - > > -odp_buffer_t queue_sched_buf(odp_queue_t handle) > > -{ > > - queue_entry_t *queue; > > - queue = queue_to_qentry(handle); > > - > > - return queue->s.sched_buf; > > -} > > - > > - > > -int queue_sched_atomic(odp_queue_t handle) > > -{ > > - queue_entry_t *queue; > > - queue = queue_to_qentry(handle); > > - > > - return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC; > > -} > > - > > - > > -odp_queue_t odp_queue_lookup(const char *name) > > -{ > > - uint32_t i; > > - > > - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { > > - queue_entry_t *queue = &queue_tbl->queue[i]; > > - > > - if (queue->s.status == QUEUE_STATUS_FREE) > > - continue; > > - > > - LOCK(&queue->s.lock); > > - if (strcmp(name, queue->s.name) == 0) { > > - /* found it */ > > - UNLOCK(&queue->s.lock); > > - return queue->s.handle; > > - } > > - UNLOCK(&queue->s.lock); > > - } > > - > > - return ODP_QUEUE_INVALID; > > -} > > - > > - > > -int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr) > > -{ > > - int sched = 0; > > - > > - LOCK(&queue->s.lock); > > - if (queue->s.head == NULL) { > > - /* Empty queue */ > > - queue->s.head = buf_hdr; > > - queue->s.tail = buf_hdr; > > - buf_hdr->pkt.next = NULL; > > - } else { > > - queue->s.tail->pkt.next = buf_hdr; > > - queue->s.tail = buf_hdr; > > - buf_hdr->pkt.next = NULL; > > - } > > - > > - if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > > - queue->s.status = QUEUE_STATUS_SCHED; > > - sched = 1; /* retval: schedule queue */ > > - } > > - UNLOCK(&queue->s.lock); > > - > > - /* Add queue to scheduling */ > > - if (sched == 1) > > - odp_schedule_queue(queue->s.handle, > queue->s.param.sched.prio); > > - > > - return 0; > > -} > > - > > - > > -int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], > int num) > > -{ > > - int sched = 0; > > - int i; > > - odp_buffer_hdr_t *tail; > > - > > - for (i = 0; i < num - 1; i++) > > - buf_hdr[i]->pkt.next = buf_hdr[i+1]; > > - > > - tail = buf_hdr[num-1]; > > - buf_hdr[num-1]->pkt.next = NULL; > > - > > - LOCK(&queue->s.lock); > > - /* Empty queue */ > > - if (queue->s.head == NULL) > > - queue->s.head = buf_hdr[0]; > > - else > > - queue->s.tail->pkt.next = buf_hdr[0]; > > - > > - queue->s.tail = tail; > > - > > - if (queue->s.status == QUEUE_STATUS_NOTSCHED) { > > - queue->s.status = QUEUE_STATUS_SCHED; > > - sched = 1; /* retval: schedule queue */ > > - } > > - UNLOCK(&queue->s.lock); > > - > > - /* Add queue to scheduling */ > > - if (sched == 1) > > - odp_schedule_queue(queue->s.handle, > queue->s.param.sched.prio); > > - > > - return 0; > > -} > > - > > - > > -int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > > -{ > > - odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > > - queue_entry_t *queue; > > - int i; > > - > > - if (num > QUEUE_MULTI_MAX) > > - num = QUEUE_MULTI_MAX; > > - > > - queue = queue_to_qentry(handle); > > - > > - for (i = 0; i < num; i++) > > - buf_hdr[i] = odp_buf_to_hdr(buf[i]); > > - > > - return queue->s.enqueue_multi(queue, buf_hdr, num); > > -} > > - > > - > > -int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf) > > -{ > > - odp_buffer_hdr_t *buf_hdr; > > - queue_entry_t *queue; > > - > > - queue = queue_to_qentry(handle); > > - buf_hdr = odp_buf_to_hdr(buf); > > - > > - return queue->s.enqueue(queue, buf_hdr); > > -} > > - > > - > > -odp_buffer_hdr_t *queue_deq(queue_entry_t *queue) > > -{ > > - odp_buffer_hdr_t *buf_hdr = NULL; > > - > > - LOCK(&queue->s.lock); > > - > > - if (queue->s.head == NULL) { > > - /* Already empty queue */ > > - if (queue->s.status == QUEUE_STATUS_SCHED && > > - queue->s.type != ODP_QUEUE_TYPE_PKTIN) > > - queue->s.status = QUEUE_STATUS_NOTSCHED; > > - } else { > > - buf_hdr = queue->s.head; > > - queue->s.head = buf_hdr->pkt.next; > > - buf_hdr->pkt.next = NULL; > > - > > - if (queue->s.head == NULL) { > > - /* Queue is now empty */ > > - queue->s.tail = NULL; > > - } > > - } > > - > > - UNLOCK(&queue->s.lock); > > - > > - return buf_hdr; > > -} > > - > > - > > -int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], > int num) > > -{ > > - int i = 0; > > - > > - LOCK(&queue->s.lock); > > - > > - if (queue->s.head == NULL) { > > - /* Already empty queue */ > > - if (queue->s.status == QUEUE_STATUS_SCHED && > > - queue->s.type != ODP_QUEUE_TYPE_PKTIN) > > - queue->s.status = QUEUE_STATUS_NOTSCHED; > > - } else { > > - odp_buffer_hdr_t *hdr = queue->s.head; > > - > > - for (; i < num && hdr; i++) { > > - buf_hdr[i] = hdr; > > - /* odp_prefetch(hdr->addr); */ > > - hdr = hdr->pkt.next; > > - buf_hdr[i]->pkt.next = NULL; > > - } > > - > > - queue->s.head = hdr; > > - > > - if (hdr == NULL) { > > - /* Queue is now empty */ > > - queue->s.tail = NULL; > > - } > > - } > > - > > - UNLOCK(&queue->s.lock); > > - > > - return i; > > -} > > - > > - > > -int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) > > -{ > > - queue_entry_t *queue; > > - odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; > > - int i, ret; > > - > > - if (num > QUEUE_MULTI_MAX) > > - num = QUEUE_MULTI_MAX; > > - > > - queue = queue_to_qentry(handle); > > - > > - ret = queue->s.dequeue_multi(queue, buf_hdr, num); > > - > > - for (i = 0; i < ret; i++) > > - buf[i] = (odp_buffer_t) buf_hdr[i]; > > - > > - return ret; > > -} > > - > > - > > -odp_buffer_t odp_queue_deq(odp_queue_t handle) > > -{ > > - queue_entry_t *queue; > > - odp_buffer_hdr_t *buf_hdr; > > - > > - queue = queue_to_qentry(handle); > > - buf_hdr = queue->s.dequeue(queue); > > - > > - if (buf_hdr) > > - return (odp_buffer_t) buf_hdr; > > - > > - return ODP_BUFFER_INVALID; > > -} > > - > > - > > -void queue_lock(queue_entry_t *queue) > > -{ > > - LOCK(&queue->s.lock); > > -} > > - > > - > > -void queue_unlock(queue_entry_t *queue) > > -{ > > - UNLOCK(&queue->s.lock); > > -} > > -- > > 1.9.1 > > > > > > _______________________________________________ > > lng-odp mailing list > > lng-odp@lists.linaro.org > > http://lists.linaro.org/mailman/listinfo/lng-odp > > -- > Anders Roxell > anders.roxell@linaro.org > M: +46 709 71 42 85 | IRC: roxell >
diff --git a/configure.ac b/configure.ac index 873ea9e..3d8481f 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,7 @@ AC_ARG_WITH([platform], AM_CONDITIONAL([ODP_PLATFORM_GENERIC], [test "x$with_platform" = xlinux-generic]) AM_CONDITIONAL([ODP_PLATFORM_KEYSTONE2], [test "x$with_platform" = xlinux-keystone2]) +AM_CONDITIONAL([ODP_PLATFORM_DPDK], [test "x$with_platform" = xlinux-dpdk]) AC_SUBST([with_platform]) @@ -111,6 +112,7 @@ AC_CONFIG_FILES([Makefile platform/Makefile platform/linux-generic/Makefile platform/linux-keystone2/Makefile + platform/linux-dpdk/Makefile test/Makefile test/api_test/Makefile test/example/Makefile diff --git a/platform/linux-dpdk/Makefile b/platform/linux-dpdk/Makefile deleted file mode 100644 index bf8d0b3..0000000 --- a/platform/linux-dpdk/Makefile +++ /dev/null @@ -1,158 +0,0 @@ -## Copyright (c) 2013, Linaro Limited -## All rights reserved. -## -## Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are met: -## -## * Redistributions of source code must retain the above copyright notice, this -## list of conditions and the following disclaimer. -## -## * Redistributions in binary form must reproduce the above copyright notice, this -## list of conditions and the following disclaimer in the documentation and/or -## other materials provided with the distribution. -## -## * Neither the name of Linaro Limited nor the names of its contributors may be -## used to endorse or promote products derived from this software without specific -## prior written permission. -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -.DEFAULT_GOAL := libs - -ODP_ROOT = ../.. -LIB_DIR = ./lib -DOC_DIR = ./doc - -LINUX_GENERIC_DIR = ../linux-generic - -RTE_SDK ?= $(abspath $(ODP_ROOT)/../dpdk) -RTE_OUTPUT ?= $(abspath $(RTE_SDK)/build) -RTE_LIB ?= $(abspath $(RTE_OUTPUT)/lib/libintel_dpdk.a) - -PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch -PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env -PLAT_CFLAGS += -msse4.2 - -EXTRA_CFLAGS += $(PLAT_CFLAGS) -EXTRA_CFLAGS += -I./include -EXTRA_CFLAGS += -I./include/api -EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include -EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include/api -EXTRA_CFLAGS += -I$(ODP_ROOT)/include - -include $(ODP_ROOT)/Makefile.inc -STATIC_LIB = ./lib/libodp.a - -# -# Object files -# -OBJS = -OBJS += $(OBJ_DIR)/odp_barrier.o -OBJS += $(OBJ_DIR)/odp_buffer.o -OBJS += $(OBJ_DIR)/odp_buffer_pool.o -OBJS += $(OBJ_DIR)/odp_coremask.o -OBJS += $(OBJ_DIR)/odp_init.o -OBJS += $(OBJ_DIR)/odp_linux.o -OBJS += $(OBJ_DIR)/odp_packet.o -OBJS += $(OBJ_DIR)/odp_packet_flags.o -OBJS += $(OBJ_DIR)/odp_packet_io.o -OBJS += $(OBJ_DIR)/odp_packet_socket.o -OBJS += $(OBJ_DIR)/odp_queue.o -OBJS += $(OBJ_DIR)/odp_schedule.o -OBJS += $(OBJ_DIR)/odp_shared_memory.o -OBJS += $(OBJ_DIR)/odp_spinlock.o -OBJS += $(OBJ_DIR)/odp_system_info.o -OBJS += $(OBJ_DIR)/odp_thread.o -OBJS += $(OBJ_DIR)/odp_ticketlock.o -OBJS += $(OBJ_DIR)/odp_time.o -OBJS += $(OBJ_DIR)/odp_timer.o -OBJS += $(OBJ_DIR)/odp_ring.o -OBJS += $(OBJ_DIR)/odp_rwlock.o -OBJS += $(OBJ_DIR)/odp_packet_dpdk.o - -DEPS = $(OBJS:.o=.d) - -.PHONY: all -all: libs docs - --include $(DEPS) - -#$(OBJ_DIR): -# $(MKDIR) $(OBJ_DIR) - -$(LIB_DIR): - $(MKDIR) $(LIB_DIR) - -$(DOC_DIR): - $(MKDIR) $(DOC_DIR)/html - $(MKDIR) $(DOC_DIR)/latex - -# -# Compile rules -# -vpath %.c source:$(LINUX_GENERIC_DIR)/source - -$(OBJ_DIR)/%.o: %.c - $(ECHO) " CC $<" - $(CC) -c -MD $(EXTRA_CFLAGS) $(CFLAGS) -o $@ $< - -# -# Lib rule -# -$(OBJ_DIR)/libodp.o: $(OBJS) - $(ECHO) " LD $@" - $(LD) -r -o $@ $(OBJS) $(RTE_LIB) - -$(STATIC_LIB): $(OBJ_DIR)/libodp.o - $(ECHO) " AR $@" - $(AR) -cr $@ $(OBJ_DIR)/libodp.o - - -clean: - $(RMDIR) $(OBJ_DIR) - $(RMDIR) $(LIB_DIR) - $(RMDIR) $(DOC_DIR) - $(RM) Doxyfile - -Doxyfile: Doxyfile.in - doxygen -u - < $< > $@ - -.PHONY: docs -docs: $(DOC_DIR) Doxyfile ./include/odp*.h - doxygen - -.PHONY: docs_install -docs_install: docs - $(COPY) doc $(DESTDIR) - -.PHONY: pdf -pdf: docs - make --directory doc/latex refman.pdf 1> /dev/null - -.PHONY: libs -libs: $(OBJ_DIR) $(LIB_DIR) $(STATIC_LIB) - -.PHONY: lib_install -lib_install: libs - install -d $(DESTDIR)/lib - install -m 0644 ${STATIC_LIB} $(DESTDIR)/lib/ - -.PHONY: headers_install -headers_install: libs - $(ECHO) Installing headers to $(DESTDIR)/include - $(COPY) $(ODP_ROOT)/include $(DESTDIR) - $(COPY) $(LINUX_GENERIC_DIR)/include/api/* $(DESTDIR)/include/ - $(COPY) include/api/* $(DESTDIR)/include/ - -install: lib_install headers_install diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am new file mode 100644 index 0000000..067c0bb --- /dev/null +++ b/platform/linux-dpdk/Makefile.am @@ -0,0 +1,100 @@ +include $(top_srcdir)/Makefile.inc +LIB = $(top_builddir)/lib + +dist_pkgdata_DATA = $(LIB)/libodp.la + +pkgconfigdir = pkgconfig +nodist_pkgconfig_DATA = $(top_builddir)/pkgconfig/libodp.pc + +.PHONY: pkgconfig/libodp.pc + +RTE_SDK ?= $(top_srcdir)/../dpdk +RTE_OUTPUT ?= $(RTE_SDK)/build +RTE_LIB ?= $(RTE_OUTPUT)/lib + +PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch +PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env +PLAT_CFLAGS += -msse4.2 + +AM_CFLAGS += $(PLAT_CFLAGS) +AM_CFLAGS += -I$(srcdir)/include +AM_CFLAGS += -I$(srcdir)/include/api +AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include +AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include/api +AM_CFLAGS += -I$(top_srcdir)/include + +AM_LDFLAGS += -L$(RTE_LIB) +VPATH = $(srcdir) $(builddir) +if ODP_PLATFORM_DPDK +lib_LTLIBRARIES = $(LIB)/libodp.la +DPDK_LIBS="-lintel_dpdk -ldl" +LIBS += $(DPDK_LIBS) + +include_HEADERS = \ + $(top_srcdir)/platform/linux-dpdk/include/api/odp_buffer.h \ + $(top_srcdir)/include/odp.h \ + $(top_srcdir)/include/odp_align.h \ + $(top_srcdir)/include/odp_atomic.h \ + $(top_srcdir)/include/odp_barrier.h \ + $(top_srcdir)/include/odp_buffer_pool.h \ + $(top_srcdir)/include/odp_byteorder.h \ + $(top_srcdir)/include/odp_compiler.h \ + $(top_srcdir)/include/odp_config.h \ + $(top_srcdir)/include/odp_coremask.h \ + $(top_srcdir)/include/odp_debug.h \ + $(top_srcdir)/include/odp_hints.h \ + $(top_srcdir)/include/odp_init.h \ + $(top_srcdir)/include/odp_packet_flags.h \ + $(top_srcdir)/include/odp_packet.h \ + $(top_srcdir)/include/odp_packet_io.h \ + $(top_srcdir)/include/odp_queue.h \ + $(top_srcdir)/include/odp_rwlock.h \ + $(top_srcdir)/include/odp_schedule.h \ + $(top_srcdir)/include/odp_shared_memory.h \ + $(top_srcdir)/include/odp_spinlock.h \ + $(top_srcdir)/include/odp_std_types.h \ + $(top_srcdir)/include/odp_sync.h \ + $(top_srcdir)/include/odp_system_info.h \ + $(top_srcdir)/include/odp_thread.h \ + $(top_srcdir)/include/odp_ticketlock.h \ + $(top_srcdir)/include/odp_time.h \ + $(top_srcdir)/include/odp_timer.h \ + $(top_srcdir)/include/odp_version.h + +subdirheadersdir = $(includedir)/helper +subdirheaders_HEADERS = \ + $(top_srcdir)/include/helper/odp_chksum.h \ + $(top_srcdir)/include/helper/odp_eth.h \ + $(top_srcdir)/include/helper/odp_ip.h \ + $(top_srcdir)/include/helper/odp_linux.h \ + $(top_srcdir)/include/helper/odp_packet_helper.h \ + $(top_srcdir)/include/helper/odp_ring.h \ + $(top_srcdir)/include/helper/odp_udp.h + +__LIB__libodp_la_SOURCES = \ + ../linux-generic/odp_barrier.c \ + odp_buffer.c \ + odp_buffer_pool.c \ + ../linux-generic/odp_coremask.c \ + odp_init.c \ + odp_linux.c \ + odp_packet.c \ + odp_packet_dpdk.c \ + ../linux-generic/odp_packet_flags.c \ + odp_packet_io.c \ + ../linux-generic/odp_packet_socket.c \ + odp_queue.c \ + ../linux-generic/odp_ring.c \ + ../linux-generic/odp_rwlock.c \ + ../linux-generic/odp_schedule.c \ + ../linux-generic/odp_shared_memory.c \ + ../linux-generic/odp_spinlock.c \ + ../linux-generic/odp_system_info.c \ + ../linux-generic/odp_thread.c \ + ../linux-generic/odp_ticketlock.c \ + ../linux-generic/odp_time.c \ + ../linux-generic/odp_timer.c + +endif diff --git a/platform/linux-dpdk/Makefile.inc b/platform/linux-dpdk/Makefile.inc deleted file mode 100644 index fe7679b..0000000 --- a/platform/linux-dpdk/Makefile.inc +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2013, Linaro Limited -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -STD_LIBS += -ldl - diff --git a/platform/linux-dpdk/include/api/odp_buffer.h b/platform/linux-dpdk/include/api/odp_buffer.h index 286d9e6..9ea1ed8 100644 --- a/platform/linux-dpdk/include/api/odp_buffer.h +++ b/platform/linux-dpdk/include/api/odp_buffer.h @@ -63,18 +63,11 @@ size_t odp_buffer_size(odp_buffer_t buf); int odp_buffer_type(odp_buffer_t buf); #define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */ -#define ODP_BUFFER_TYPE_RAW 0 /**< Raw buffer */ -#define ODP_BUFFER_TYPE_PACKET 1 /**< Packet buffer */ -#define ODP_BUFFER_TYPE_TIMER 2 /**< Timer buffer */ - -/** - * Tests if buffer is part of a scatter/gather list - * - * @param buf Buffer handle - * - * @return 1 if belongs to a scatter list, otherwise 0 - */ -int odp_buffer_is_scatter(odp_buffer_t buf); +#define ODP_BUFFER_TYPE_ANY 0 /**< Buffer that can hold any other + buffer type */ +#define ODP_BUFFER_TYPE_RAW 1 /**< Raw buffer, no additional metadata */ +#define ODP_BUFFER_TYPE_PACKET 2 /**< Packet buffer */ +#define ODP_BUFFER_TYPE_TIMEOUT 3 /**< Timeout buffer */ /** * Tests if buffer is valid diff --git a/platform/linux-dpdk/odp_buffer.c b/platform/linux-dpdk/odp_buffer.c new file mode 100644 index 0000000..133658f --- /dev/null +++ b/platform/linux-dpdk/odp_buffer.c @@ -0,0 +1,91 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_buffer.h> +#include <odp_buffer_internal.h> +#include <odp_buffer_pool_internal.h> + +#include <string.h> +#include <stdio.h> + + +void *odp_buffer_addr(odp_buffer_t buf) +{ + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + return hdr->buf_addr; +} + + +size_t odp_buffer_size(odp_buffer_t buf) +{ + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + return hdr->buf_len; +} + + +int odp_buffer_type(odp_buffer_t buf) +{ + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + return hdr->type; +} + + +int odp_buffer_is_valid(odp_buffer_t buf) +{ + odp_buffer_bits_t handle; + + handle.u32 = buf; + + return (handle.index != ODP_BUFFER_INVALID_INDEX); +} + + +int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) +{ + odp_buffer_hdr_t *hdr; + int len = 0; + + if (!odp_buffer_is_valid(buf)) { + printf("Buffer is not valid.\n"); + return len; + } + + hdr = odp_buf_to_hdr(buf); + + len += snprintf(&str[len], n-len, + "Buffer\n"); + len += snprintf(&str[len], n-len, + " pool %"PRIu64"\n", (int64_t) hdr->pool); + len += snprintf(&str[len], n-len, + " phy_addr %"PRIu64"\n", hdr->buf_physaddr); + len += snprintf(&str[len], n-len, + " addr %p\n", hdr->buf_addr); + len += snprintf(&str[len], n-len, + " size %u\n", hdr->buf_len); + len += snprintf(&str[len], n-len, + " ref_count %i\n", hdr->refcnt); + len += snprintf(&str[len], n-len, + " type %i\n", hdr->type); + + return len; +} + + +void odp_buffer_print(odp_buffer_t buf) +{ + int max_len = 512; + char str[max_len]; + int len; + + len = odp_buffer_snprint(str, max_len-1, buf); + str[len] = 0; + + printf("\n%s\n", str); +} + diff --git a/platform/linux-dpdk/odp_buffer_pool.c b/platform/linux-dpdk/odp_buffer_pool.c new file mode 100644 index 0000000..de90275 --- /dev/null +++ b/platform/linux-dpdk/odp_buffer_pool.c @@ -0,0 +1,156 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_std_types.h> +#include <odp_buffer_pool.h> +#include <odp_buffer_pool_internal.h> +#include <odp_buffer_internal.h> +#include <odp_packet_internal.h> +#include <odp_shared_memory.h> +#include <odp_align.h> +#include <odp_internal.h> +#include <odp_config.h> +#include <odp_hints.h> +#include <odp_debug.h> + +#include <string.h> +#include <stdlib.h> + +/* for DPDK */ +#include <odp_packet_dpdk.h> + +#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) +#define NB_MBUF 8192 + +#ifdef POOL_USE_TICKETLOCK +#include <odp_ticketlock.h> +#define LOCK(a) odp_ticketlock_lock(a) +#define UNLOCK(a) odp_ticketlock_unlock(a) +#define LOCK_INIT(a) odp_ticketlock_init(a) +#else +#include <odp_spinlock.h> +#define LOCK(a) odp_spinlock_lock(a) +#define UNLOCK(a) odp_spinlock_unlock(a) +#define LOCK_INIT(a) odp_spinlock_init(a) +#endif + + +#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS +#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS +#endif + +#define NULL_INDEX ((uint32_t)-1) + + +typedef union pool_entry_u { + struct pool_entry_s s; + + uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))]; + +} pool_entry_t; + + +typedef struct pool_table_t { + pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS]; + +} pool_table_t; + + +/* The pool table */ +static pool_table_t *pool_tbl; + +/* Pool entry pointers (for inlining) */ +void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS]; + + +int odp_buffer_pool_init_global(void) +{ + odp_buffer_pool_t i; + + pool_tbl = odp_shm_reserve("odp_buffer_pools", + sizeof(pool_table_t), + sizeof(pool_entry_t)); + + if (pool_tbl == NULL) + return -1; + + memset(pool_tbl, 0, sizeof(pool_table_t)); + + + for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) { + /* init locks */ + pool_entry_t *pool = &pool_tbl->pool[i]; + LOCK_INIT(&pool->s.lock); + pool->s.pool = i; + + pool_entry_ptr[i] = pool; + } + + ODP_DBG("\nBuffer pool init global\n"); + ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct pool_entry_s)); + ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t)); + ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t)); + ODP_DBG("\n"); + + return 0; +} + + +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; + 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, 32, + sizeof(struct rte_pktmbuf_pool_private), + rte_pktmbuf_pool_init, NULL, + rte_pktmbuf_init, NULL, + rte_socket_id(), 0); + if (pktmbuf_pool == NULL) { + ODP_ERR("Cannot init DPDK mbuf pool\n"); + return -1; + } + + return (odp_buffer_pool_t) pktmbuf_pool; +} + + +odp_buffer_pool_t odp_buffer_pool_lookup(const char *name) +{ + struct rte_mempool *mp = NULL; + + mp = rte_mempool_lookup(name); + if (mp == NULL) + return ODP_BUFFER_POOL_INVALID; + + return (odp_buffer_pool_t)mp; +} + + +odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id) +{ + return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool *)pool_id); +} + + +void odp_buffer_free(odp_buffer_t buf) +{ + rte_pktmbuf_free((struct rte_mbuf *)buf); +} + + +void odp_buffer_pool_print(odp_buffer_pool_t pool_id) +{ + rte_mempool_dump((const struct rte_mempool *)pool_id); +} diff --git a/platform/linux-dpdk/odp_init.c b/platform/linux-dpdk/odp_init.c new file mode 100644 index 0000000..ecc2066 --- /dev/null +++ b/platform/linux-dpdk/odp_init.c @@ -0,0 +1,113 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_init.h> +#include <odp_internal.h> +#include <odp_debug.h> +#include <odp_packet_dpdk.h> + +int odp_init_dpdk(void) +{ + int test_argc = 5; + char *test_argv[6]; + int core_count, i, num_cores = 0; + char core_mask[8]; + + core_count = odp_sys_core_count(); + for (i = 0; i < core_count; i++) + num_cores += (0x1 << i); + sprintf(core_mask, "%x", num_cores); + + test_argv[0] = malloc(sizeof("odp_dpdk")); + strcpy(test_argv[0], "odp_dpdk"); + test_argv[1] = malloc(sizeof("-c")); + strcpy(test_argv[1], "-c"); + test_argv[2] = malloc(sizeof(core_mask)); + strcpy(test_argv[2], core_mask); + test_argv[3] = malloc(sizeof("-n")); + strcpy(test_argv[3], "-n"); + test_argv[4] = malloc(sizeof("3")); + strcpy(test_argv[4], "3"); + + if (rte_eal_init(test_argc, (char **)test_argv) < 0) { + ODP_ERR("Cannot init the Intel DPDK EAL!"); + return -1; + } + + if (rte_pmd_init_all() < 0) { + ODP_ERR("Cannot init pmd\n"); + return -1; + } + + if (rte_eal_pci_probe() < 0) { + ODP_ERR("Cannot probe PCI\n"); + return -1; + } + + return 0; +} + +int odp_init_global(void) +{ + odp_thread_init_global(); + + odp_system_info_init(); + + if (odp_init_dpdk()) { + ODP_ERR("ODP dpdk init failed.\n"); + return -1; + } + + if (odp_shm_init_global()) { + ODP_ERR("ODP shm init failed.\n"); + return -1; + } + + if (odp_buffer_pool_init_global()) { + ODP_ERR("ODP buffer pool init failed.\n"); + return -1; + } + + if (odp_queue_init_global()) { + ODP_ERR("ODP queue init failed.\n"); + return -1; + } + + if (odp_schedule_init_global()) { + ODP_ERR("ODP schedule init failed.\n"); + return -1; + } + + if (odp_pktio_init_global()) { + ODP_ERR("ODP packet io init failed.\n"); + return -1; + } + + if (odp_timer_init_global()) { + ODP_ERR("ODP timer init failed.\n"); + return -1; + } + + return 0; +} + + +int odp_init_local(int thr_id) +{ + odp_thread_init_local(thr_id); + + if (odp_pktio_init_local()) { + ODP_ERR("ODP packet io local init failed.\n"); + return -1; + } + + if (odp_schedule_init_local()) { + ODP_ERR("ODP schedule local init failed.\n"); + return -1; + } + + return 0; +} diff --git a/platform/linux-dpdk/odp_linux.c b/platform/linux-dpdk/odp_linux.c new file mode 100644 index 0000000..067bd99 --- /dev/null +++ b/platform/linux-dpdk/odp_linux.c @@ -0,0 +1,96 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <sched.h> + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> + +#include <helper/odp_linux.h> +#include <odp_internal.h> +#include <odp_thread.h> +#include <odp_init.h> +#include <odp_system_info.h> + +#include <rte_lcore.h> + +typedef struct { + int thr_id; + void *(*start_routine) (void *); + void *arg; + +} odp_start_args_t; + + +static void *odp_run_start_routine(void *arg) +{ + odp_start_args_t *start_args = arg; + + /* ODP thread local init */ + odp_init_local(start_args->thr_id); + + return start_args->start_routine(start_args->arg); +} + + +void odp_linux_pthread_create(odp_linux_pthread_t *thread_tbl, int num, + int first_core, void *(*start_routine) (void *), void *arg) +{ + int i; + cpu_set_t cpu_set; + odp_start_args_t *start_args; + int core_count; + int cpu; + + (void) cpu_set; + (void) thread_tbl; + + core_count = odp_sys_core_count(); + + assert((first_core >= 0) && (first_core < core_count)); + assert((num >= 0) && (num <= core_count)); + + for (i = 0; i < num; i++) { + cpu = (first_core + i) % core_count; + + start_args = malloc(sizeof(odp_start_args_t)); + memset(start_args, 0, sizeof(odp_start_args_t)); + start_args->start_routine = start_routine; + start_args->arg = arg; + + odp_thread_create(cpu); + start_args->thr_id = cpu; + /* If not master core */ + if (cpu != 0) { + rte_eal_remote_launch( + (int(*)(void *))odp_run_start_routine, + start_args, cpu); + } else { + lcore_config[cpu].ret = (int)(uint64_t) + odp_run_start_routine(start_args); + lcore_config[cpu].state = FINISHED; + } + } +} + + +void odp_linux_pthread_join(odp_linux_pthread_t *thread_tbl, int num) +{ + uint32_t lcore_id; + + (void) thread_tbl; + (void) num; + + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + return; + } +} diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c new file mode 100644 index 0000000..c34e626 --- /dev/null +++ b/platform/linux-dpdk/odp_packet.c @@ -0,0 +1,374 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_packet.h> +#include <odp_packet_internal.h> +#include <odp_hints.h> +#include <odp_byteorder.h> + +#include <helper/odp_eth.h> +#include <helper/odp_ip.h> + +#include <string.h> +#include <stdio.h> + +static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, + size_t *offset_out); +static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, + size_t *offset_out); + +void odp_packet_init(odp_packet_t pkt) +{ + odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); + const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); + uint8_t *start; + size_t len; + + start = (uint8_t *)pkt_hdr + start_offset; + len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; + memset(start, 0, len); + + pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; + pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; + pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; +} + +odp_packet_t odp_packet_from_buffer(odp_buffer_t buf) +{ + return (odp_packet_t)buf; +} + +odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt) +{ + return (odp_buffer_t)pkt; +} + +void odp_packet_set_len(odp_packet_t pkt, size_t len) +{ + /* for rte_pktmbuf */ + odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(odp_buffer_from_packet(pkt)); + buf_hdr->pkt.data_len = len; + + odp_packet_hdr(pkt)->frame_len = len; +} + +size_t odp_packet_get_len(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->frame_len; +} + +uint8_t *odp_packet_buf_addr(odp_packet_t pkt) +{ + return odp_buffer_addr(odp_buffer_from_packet(pkt)); +} + +uint8_t *odp_packet_start(odp_packet_t pkt) +{ + return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset; +} + + +uint8_t *odp_packet_l2(odp_packet_t pkt) +{ + const size_t offset = odp_packet_l2_offset(pkt); + + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) + return NULL; + + return odp_packet_buf_addr(pkt) + offset; +} + +size_t odp_packet_l2_offset(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->l2_offset; +} + +void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset) +{ + odp_packet_hdr(pkt)->l2_offset = offset; +} + +uint8_t *odp_packet_l3(odp_packet_t pkt) +{ + const size_t offset = odp_packet_l3_offset(pkt); + + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) + return NULL; + + return odp_packet_buf_addr(pkt) + offset; +} + +size_t odp_packet_l3_offset(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->l3_offset; +} + +void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset) +{ + odp_packet_hdr(pkt)->l3_offset = offset; +} + +uint8_t *odp_packet_l4(odp_packet_t pkt) +{ + const size_t offset = odp_packet_l4_offset(pkt); + + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) + return NULL; + + return odp_packet_buf_addr(pkt) + offset; +} + +size_t odp_packet_l4_offset(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->l4_offset; +} + +void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset) +{ + odp_packet_hdr(pkt)->l4_offset = offset; +} + +/** + * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP + * + * Internal function: caller is resposible for passing only valid packet handles + * , lengths and offsets (usually done&called in packet input). + * + * @param pkt Packet handle + * @param len Packet length in bytes + * @param frame_offset Byte offset to L2 header + */ +void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset) +{ + odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); + odp_ethhdr_t *eth; + odp_vlanhdr_t *vlan; + odp_ipv4hdr_t *ipv4; + odp_ipv6hdr_t *ipv6; + uint16_t ethtype; + size_t offset = 0; + uint8_t ip_proto = 0; + + pkt_hdr->input_flags.eth = 1; + pkt_hdr->frame_offset = frame_offset; + pkt_hdr->frame_len = len; + + if (odp_unlikely(len < ODP_ETH_LEN_MIN)) { + pkt_hdr->error_flags.frame_len = 1; + return; + } else if (len > ODP_ETH_LEN_MAX) { + pkt_hdr->input_flags.jumbo = 1; + } + + /* Assume valid L2 header, no CRC/FCS check in SW */ + pkt_hdr->input_flags.l2 = 1; + pkt_hdr->l2_offset = frame_offset; + + eth = (odp_ethhdr_t *)odp_packet_start(pkt); + ethtype = odp_be_to_cpu_16(eth->type); + vlan = (odp_vlanhdr_t *)ð->type; + + if (ethtype == ODP_ETHTYPE_VLAN_OUTER) { + pkt_hdr->input_flags.vlan_qinq = 1; + ethtype = odp_be_to_cpu_16(vlan->tpid); + offset += sizeof(odp_vlanhdr_t); + vlan = &vlan[1]; + } + + if (ethtype == ODP_ETHTYPE_VLAN) { + pkt_hdr->input_flags.vlan = 1; + ethtype = odp_be_to_cpu_16(vlan->tpid); + offset += sizeof(odp_vlanhdr_t); + } + + /* Set l3_offset+flag only for known ethtypes */ + switch (ethtype) { + case ODP_ETHTYPE_IPV4: + pkt_hdr->input_flags.ipv4 = 1; + pkt_hdr->input_flags.l3 = 1; + pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; + ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt); + ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset); + break; + case ODP_ETHTYPE_IPV6: + pkt_hdr->input_flags.ipv6 = 1; + pkt_hdr->input_flags.l3 = 1; + pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; + ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt); + ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset); + break; + case ODP_ETHTYPE_ARP: + pkt_hdr->input_flags.arp = 1; + /* fall through */ + default: + ip_proto = 0; + break; + } + + switch (ip_proto) { + case ODP_IPPROTO_UDP: + pkt_hdr->input_flags.udp = 1; + pkt_hdr->input_flags.l4 = 1; + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; + break; + case ODP_IPPROTO_TCP: + pkt_hdr->input_flags.tcp = 1; + pkt_hdr->input_flags.l4 = 1; + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; + break; + case ODP_IPPROTO_SCTP: + pkt_hdr->input_flags.sctp = 1; + pkt_hdr->input_flags.l4 = 1; + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; + break; + case ODP_IPPROTO_ICMP: + pkt_hdr->input_flags.icmp = 1; + pkt_hdr->input_flags.l4 = 1; + pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; + break; + default: + /* 0 or unhandled IP protocols, don't set L4 flag+offset */ + if (pkt_hdr->input_flags.ipv6) { + /* IPv6 next_hdr is not L4, mark as IP-option instead */ + pkt_hdr->input_flags.ipopt = 1; + } + break; + } +} + +static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, + size_t *offset_out) +{ + uint8_t ihl; + uint16_t frag_offset; + + ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl); + if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) { + pkt_hdr->error_flags.ip_err = 1; + return 0; + } + + if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) { + pkt_hdr->input_flags.ipopt = 1; + return 0; + } + + /* A packet is a fragment if: + * "more fragments" flag is set (all fragments except the last) + * OR + * "fragment offset" field is nonzero (all fragments except the first) + */ + frag_offset = odp_be_to_cpu_16(ipv4->frag_offset); + if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) { + pkt_hdr->input_flags.ipfrag = 1; + return 0; + } + + if (ipv4->proto == ODP_IPPROTO_ESP || + ipv4->proto == ODP_IPPROTO_AH) { + pkt_hdr->input_flags.ipsec = 1; + return 0; + } + + /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after return */ + + *offset_out = sizeof(uint32_t) * ihl; + return ipv4->proto; +} + +static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, + size_t *offset_out) +{ + if (ipv6->next_hdr == ODP_IPPROTO_ESP || + ipv6->next_hdr == ODP_IPPROTO_AH) { + pkt_hdr->input_flags.ipopt = 1; + pkt_hdr->input_flags.ipsec = 1; + return 0; + } + + if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) { + pkt_hdr->input_flags.ipopt = 1; + pkt_hdr->input_flags.ipfrag = 1; + return 0; + } + + /* Don't step through more extensions */ + *offset_out = ODP_IPV6HDR_LEN; + return ipv6->next_hdr; +} + +void odp_packet_print(odp_packet_t pkt) +{ + int max_len = 512; + char str[max_len]; + int len = 0; + int n = max_len-1; + odp_packet_hdr_t *hdr = odp_packet_hdr(pkt); + + len += snprintf(&str[len], n-len, "Packet "); + len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt); + len += snprintf(&str[len], n-len, + " input_flags 0x%x\n", hdr->input_flags.all); + len += snprintf(&str[len], n-len, + " error_flags 0x%x\n", hdr->error_flags.all); + len += snprintf(&str[len], n-len, + " output_flags 0x%x\n", hdr->output_flags.all); + len += snprintf(&str[len], n-len, + " frame_offset %u\n", hdr->frame_offset); + len += snprintf(&str[len], n-len, + " l2_offset %u\n", hdr->l2_offset); + len += snprintf(&str[len], n-len, + " l3_offset %u\n", hdr->l3_offset); + len += snprintf(&str[len], n-len, + " l4_offset %u\n", hdr->l4_offset); + len += snprintf(&str[len], n-len, + " frame_len %u\n", hdr->frame_len); + len += snprintf(&str[len], n-len, + " input %u\n", hdr->input); + str[len] = '\0'; + + printf("\n%s\n", str); +} + +int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src) +{ + odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst); + odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src); + const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); + uint8_t *start_src; + uint8_t *start_dst; + size_t len; + + if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID) + return -1; + + /* if (pkt_hdr_dst->buf_hdr.size < */ + /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */ + if (pkt_hdr_dst->buf_hdr.buf_len < + pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) + return -1; + + /* Copy packet header */ + start_dst = (uint8_t *)pkt_hdr_dst + start_offset; + start_src = (uint8_t *)pkt_hdr_src + start_offset; + len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; + memcpy(start_dst, start_src, len); + + /* Copy frame payload */ + start_dst = (uint8_t *)odp_packet_start(pkt_dst); + start_src = (uint8_t *)odp_packet_start(pkt_src); + len = pkt_hdr_src->frame_len; + memcpy(start_dst, start_src, len); + + /* Copy useful things from the buffer header */ + /* pkt_hdr_dst->buf_hdr.cur_offset = pkt_hdr_src->buf_hdr.cur_offset; */ + + /* Create a copy of the scatter list */ + /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */ + /* odp_buffer_from_packet(pkt_src)); */ + + return 0; +} diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c new file mode 100644 index 0000000..31bfa30 --- /dev/null +++ b/platform/linux-dpdk/odp_packet_dpdk.c @@ -0,0 +1,189 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <poll.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> + +#include <linux/ethtool.h> +#include <linux/sockios.h> + +#include <odp_hints.h> +#include <odp_thread.h> + +#include <odp_packet_dpdk.h> +#include <net/if.h> + +/* + * RX and TX Prefetch, Host, and Write-back threshold values should be + * carefully set for optimal performance. Consult the network + * controller's datasheet and supporting DPDK documentation for guidance + * on how these parameters should be set. + */ +#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ +#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ +#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */ + +/* + * These default values are optimized for use with the Intel(R) 82599 10 GbE + * Controller and the DPDK ixgbe PMD. Consider using other values for other + * network controllers and/or network drivers. + */ +#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */ +#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ +#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ + +#define MAX_PKT_BURST 16 +#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ +#define RTE_TEST_RX_DESC_DEFAULT 128 +#define RTE_TEST_TX_DESC_DEFAULT 512 +static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; +static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; + +static const struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload disabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /**< CRC stripped by hardware */ + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, +}; + +static const struct rte_eth_rxconf rx_conf = { + .rx_thresh = { + .pthresh = RX_PTHRESH, + .hthresh = RX_HTHRESH, + .wthresh = RX_WTHRESH, + }, +}; + +static const struct rte_eth_txconf tx_conf = { + .tx_thresh = { + .pthresh = TX_PTHRESH, + .hthresh = TX_HTHRESH, + .wthresh = TX_WTHRESH, + }, + .tx_free_thresh = 0, /* Use PMD default values */ + .tx_rs_thresh = 0, /* Use PMD default values */ + /* + * As the example won't handle mult-segments and offload cases, + * set the flag by default. + */ + .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS, +}; + +int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, + odp_buffer_pool_t pool) +{ + ODP_DBG("setup_pkt_dpdk\n"); + + static struct ether_addr eth_addr[RTE_MAX_ETHPORTS]; + uint8_t portid = 0; + uint16_t queueid = 0; + int ret; + printf("dpdk netdev: %s\n", netdev); + printf("dpdk pool: %lx\n", pool); + + portid = atoi(netdev); + pkt_dpdk->portid = portid; + pkt_dpdk->queueid = queueid; + pkt_dpdk->pool = pool; + printf("dpdk portid: %u\n", portid); + + fflush(stdout); + ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); + if (ret < 0) + ODP_ERR("Cannot configure device: err=%d, port=%u\n", + ret, (unsigned) portid); + + rte_eth_macaddr_get(portid, ð_addr[portid]); + ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", + (unsigned) portid, + eth_addr[portid].addr_bytes[0], + eth_addr[portid].addr_bytes[1], + eth_addr[portid].addr_bytes[2], + eth_addr[portid].addr_bytes[3], + eth_addr[portid].addr_bytes[4], + eth_addr[portid].addr_bytes[5]); + + /* init one RX queue on each port */ + fflush(stdout); + ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd, + rte_eth_dev_socket_id(portid), &rx_conf, + (struct rte_mempool *)pool); + if (ret < 0) + ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n", + ret, (unsigned) portid); + ODP_DBG("dpdk rx queue setup done\n"); + + /* init one TX queue on each port */ + fflush(stdout); + ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, + rte_eth_dev_socket_id(portid), &tx_conf); + if (ret < 0) + ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n", + ret, (unsigned) portid); + ODP_DBG("dpdk tx queue setup done\n"); + + /* Start device */ + ret = rte_eth_dev_start(portid); + if (ret < 0) + ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n", + ret, (unsigned) portid); + ODP_DBG("dpdk setup done\n\n"); + + + return 0; +} + +int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk) +{ + ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid); + + return 0; +} + +int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], + unsigned len) +{ + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + uint16_t nb_rx, i = 0; + + memset(pkts_burst, 0 , sizeof(pkts_burst)); + nb_rx = rte_eth_rx_burst((uint8_t)pkt_dpdk->portid, + (uint16_t)pkt_dpdk->queueid, + (struct rte_mbuf **)pkts_burst, (uint16_t)len); + for (i = 0; i < nb_rx; i++) + pkt_table[i] = (odp_packet_t)pkts_burst[i]; + return nb_rx; +} + +int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], + unsigned len) +{ + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + uint16_t i; + + for (i = 0; i < len; i++) + pkts_burst[i] = (struct rte_mbuf *)pkt_table[i]; + return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid, + (uint16_t)pkt_dpdk->queueid, + (struct rte_mbuf **)pkts_burst, (uint16_t)len); +} diff --git a/platform/linux-dpdk/odp_packet_io.c b/platform/linux-dpdk/odp_packet_io.c new file mode 100644 index 0000000..abea0ec --- /dev/null +++ b/platform/linux-dpdk/odp_packet_io.c @@ -0,0 +1,561 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_packet_io.h> +#include <odp_packet_io_internal.h> +#include <odp_packet_io_queue.h> +#include <odp_packet.h> +#include <odp_packet_internal.h> +#include <odp_internal.h> +#include <odp_spinlock.h> +#include <odp_shared_memory.h> +#include <odp_packet_socket.h> +#ifdef ODP_HAVE_NETMAP +#include <odp_packet_netmap.h> +#endif +#include <odp_hints.h> +#include <odp_config.h> +#include <odp_queue_internal.h> +#include <odp_schedule_internal.h> +#include <odp_debug.h> + +#include <odp_pktio_socket.h> +#ifdef ODP_HAVE_NETMAP +#include <odp_pktio_netmap.h> +#endif + +#include <string.h> + +typedef struct { + pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; +} pktio_table_t; + +static pktio_table_t *pktio_tbl; + + +static pktio_entry_t *get_entry(odp_pktio_t id) +{ + if (odp_unlikely(id == ODP_PKTIO_INVALID || + id > ODP_CONFIG_PKTIO_ENTRIES)) + return NULL; + + return &pktio_tbl->entries[id - 1]; +} + +int odp_pktio_init_global(void) +{ + char name[ODP_QUEUE_NAME_LEN]; + pktio_entry_t *pktio_entry; + queue_entry_t *queue_entry; + odp_queue_t qid; + int id; + + pktio_tbl = odp_shm_reserve("odp_pktio_entries", + sizeof(pktio_table_t), + sizeof(pktio_entry_t)); + if (pktio_tbl == NULL) + return -1; + + memset(pktio_tbl, 0, sizeof(pktio_table_t)); + + for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) { + pktio_entry = get_entry(id); + + odp_spinlock_init(&pktio_entry->s.lock); + + /* Create a default output queue for each pktio resource */ + snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id); + name[ODP_QUEUE_NAME_LEN-1] = '\0'; + + qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL); + if (qid == ODP_QUEUE_INVALID) + return -1; + pktio_entry->s.outq_default = qid; + + queue_entry = queue_to_qentry(qid); + queue_entry->s.pktout = id; + } + + return 0; +} + +int odp_pktio_init_local(void) +{ + return 0; +} + +static int is_free(pktio_entry_t *entry) +{ + return (entry->s.taken == 0); +} + +static void set_free(pktio_entry_t *entry) +{ + entry->s.taken = 0; +} + +static void set_taken(pktio_entry_t *entry) +{ + entry->s.taken = 1; +} + +static void lock_entry(pktio_entry_t *entry) +{ + odp_spinlock_lock(&entry->s.lock); +} + +static void unlock_entry(pktio_entry_t *entry) +{ + odp_spinlock_unlock(&entry->s.lock); +} + +static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params) +{ + set_taken(entry); + entry->s.inq_default = ODP_QUEUE_INVALID; + switch (params->type) { + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: + case ODP_PKTIO_TYPE_SOCKET_MMAP: + memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); + memset(&entry->s.pkt_sock_mmap, 0, + sizeof(entry->s.pkt_sock_mmap)); + break; +#ifdef ODP_HAVE_NETMAP + case ODP_PKTIO_TYPE_NETMAP: + memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); + break; +#endif + case ODP_PKTIO_TYPE_DPDK: + memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk)); + break; + default: + ODP_ERR("Packet I/O type not supported. Please recompile\n"); + break; + } + /* Save pktio parameters, type is the most useful */ + memcpy(&entry->s.params, params, sizeof(*params)); +} + +static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params) +{ + odp_pktio_t id; + pktio_entry_t *entry; + int i; + + for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { + entry = &pktio_tbl->entries[i]; + if (is_free(entry)) { + lock_entry(entry); + if (is_free(entry)) { + init_pktio_entry(entry, params); + id = i + 1; + return id; /* return with entry locked! */ + } + unlock_entry(entry); + } + } + + return ODP_PKTIO_INVALID; +} + +static int free_pktio_entry(odp_pktio_t id) +{ + pktio_entry_t *entry = get_entry(id); + + if (entry == NULL) + return -1; + + set_free(entry); + + return 0; +} + +odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool, + odp_pktio_params_t *params) +{ + odp_pktio_t id; + pktio_entry_t *pktio_entry; + int res; + + if (params == NULL) { + ODP_ERR("Invalid pktio params\n"); + return ODP_PKTIO_INVALID; + } + + switch (params->type) { + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: + case ODP_PKTIO_TYPE_SOCKET_MMAP: + ODP_DBG("Allocating socket pktio\n"); + break; +#ifdef ODP_HAVE_NETMAP + case ODP_PKTIO_TYPE_NETMAP: + ODP_DBG("Allocating netmap pktio\n"); + break; +#endif + case ODP_PKTIO_TYPE_DPDK: + ODP_DBG("Allocating dpdk pktio\n"); + break; + default: + ODP_ERR("Invalid pktio type: %02x\n", params->type); + return ODP_PKTIO_INVALID; + } + + id = alloc_lock_pktio_entry(params); + if (id == ODP_PKTIO_INVALID) { + ODP_ERR("No resources available.\n"); + return ODP_PKTIO_INVALID; + } + /* if successful, alloc_pktio_entry() returns with the entry locked */ + + pktio_entry = get_entry(id); + + switch (params->type) { + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: + res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); + if (res == -1) { + close_pkt_sock(&pktio_entry->s.pkt_sock); + free_pktio_entry(id); + id = ODP_PKTIO_INVALID; + } + break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev, + pool, params->sock_params.fanout); + if (res == -1) { + close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); + free_pktio_entry(id); + id = ODP_PKTIO_INVALID; + } + break; +#ifdef ODP_HAVE_NETMAP + case ODP_PKTIO_TYPE_NETMAP: + + res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, + pool, ¶ms->nm_params); + if (res == -1) { + close_pkt_netmap(&pktio_entry->s.pkt_nm); + free_pktio_entry(id); + id = ODP_PKTIO_INVALID; + } + break; +#endif + case ODP_PKTIO_TYPE_DPDK: + res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool); + if (res == -1) { + close_pkt_dpdk(&pktio_entry->s.pkt_dpdk); + free_pktio_entry(id); + id = ODP_PKTIO_INVALID; + } + break; + default: + free_pktio_entry(id); + id = ODP_PKTIO_INVALID; + ODP_ERR("Invalid pktio type. Please recompile.\n"); + break; + } + + unlock_entry(pktio_entry); + return id; +} + +int odp_pktio_close(odp_pktio_t id) +{ + pktio_entry_t *entry; + int res = -1; + + entry = get_entry(id); + if (entry == NULL) + return -1; + + lock_entry(entry); + if (!is_free(entry)) { + switch (entry->s.params.type) { + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: + res = close_pkt_sock(&entry->s.pkt_sock); + break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); + break; +#ifdef ODP_HAVE_NETMAP + case ODP_PKTIO_TYPE_NETMAP: + res = close_pkt_netmap(&entry->s.pkt_nm); + break; +#endif + case ODP_PKTIO_TYPE_DPDK: + res = close_pkt_dpdk(&entry->s.pkt_dpdk); + break; + default: + break; + res |= free_pktio_entry(id); + } + } + unlock_entry(entry); + + if (res != 0) + return -1; + + return 0; +} + +void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio) +{ + odp_packet_hdr(pkt)->input = pktio; +} + +odp_pktio_t odp_pktio_get_input(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input; +} + +int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) +{ + pktio_entry_t *pktio_entry = get_entry(id); + int pkts; + int i; + + if (pktio_entry == NULL) + return -1; + + lock_entry(pktio_entry); + switch (pktio_entry->s.params.type) { + case ODP_PKTIO_TYPE_SOCKET_BASIC: + pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMSG: + pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, + pkt_table, len); + break; +#ifdef ODP_HAVE_NETMAP + case ODP_PKTIO_TYPE_NETMAP: + pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len); + break; +#endif + case ODP_PKTIO_TYPE_DPDK: + pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, len); + break; + default: + pkts = -1; + break; + } + + unlock_entry(pktio_entry); + if (pkts < 0) + return pkts; + + for (i = 0; i < pkts; ++i) + odp_pktio_set_input(pkt_table[i], id); + + return pkts; +} + +int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) +{ + pktio_entry_t *pktio_entry = get_entry(id); + int pkts; + + if (pktio_entry == NULL) + return -1; + + lock_entry(pktio_entry); + switch (pktio_entry->s.params.type) { + case ODP_PKTIO_TYPE_SOCKET_BASIC: + pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMSG: + pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, + pkt_table, len); + break; +#ifdef ODP_HAVE_NETMAP + case ODP_PKTIO_TYPE_NETMAP: + pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, + pkt_table, len); + break; +#endif + case ODP_PKTIO_TYPE_DPDK: + pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk, + pkt_table, len); + break; + default: + pkts = -1; + } + unlock_entry(pktio_entry); + + return pkts; +} + +int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue) +{ + pktio_entry_t *pktio_entry = get_entry(id); + queue_entry_t *qentry = queue_to_qentry(queue); + + if (pktio_entry == NULL || qentry == NULL) + return -1; + + if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN) + return -1; + + lock_entry(pktio_entry); + pktio_entry->s.inq_default = queue; + unlock_entry(pktio_entry); + + queue_lock(qentry); + qentry->s.pktin = id; + qentry->s.status = QUEUE_STATUS_SCHED; + queue_unlock(qentry); + + odp_schedule_queue(queue, qentry->s.param.sched.prio); + + return 0; +} + +int odp_pktio_inq_remdef(odp_pktio_t id) +{ + return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID); +} + +odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id) +{ + pktio_entry_t *pktio_entry = get_entry(id); + + if (pktio_entry == NULL) + return ODP_QUEUE_INVALID; + + return pktio_entry->s.inq_default; +} + +odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id) +{ + pktio_entry_t *pktio_entry = get_entry(id); + + if (pktio_entry == NULL) + return ODP_QUEUE_INVALID; + + return pktio_entry->s.outq_default; +} + +int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) +{ + odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr); + int len = 1; + int nbr; + + nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); + return (nbr == len ? 0 : -1); +} + +odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry) +{ + (void)qentry; + return NULL; +} + +int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], + int num) +{ + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; + int nbr; + int i; + + for (i = 0; i < num; ++i) + pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) buf_hdr[i]); + + nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); + return (nbr == num ? 0 : -1); +} + +int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], + int num) +{ + (void)qentry; + (void)buf_hdr; + (void)num; + + return 0; +} + +int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) +{ + /* Use default action */ + return queue_enq(qentry, buf_hdr); +} + +odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry) +{ + odp_buffer_hdr_t *buf_hdr; + + buf_hdr = queue_deq(qentry); + + if (buf_hdr == NULL) { + odp_packet_t pkt; + odp_buffer_t buf; + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; + odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; + int pkts, i, j; + + pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, + QUEUE_MULTI_MAX); + + if (pkts > 0) { + pkt = pkt_tbl[0]; + buf = odp_buffer_from_packet(pkt); + buf_hdr = odp_buf_to_hdr(buf); + + for (i = 1, j = 0; i < pkts; ++i) { + buf = odp_buffer_from_packet(pkt_tbl[i]); + tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf); + } + queue_enq_multi(qentry, tmp_hdr_tbl, j); + } + } + + return buf_hdr; +} + +int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) +{ + /* Use default action */ + return queue_enq_multi(qentry, buf_hdr, num); +} + +int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) +{ + int nbr; + + nbr = queue_deq_multi(qentry, buf_hdr, num); + + if (nbr < num) { + odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; + odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; + odp_buffer_t buf; + int pkts, i; + + pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, + QUEUE_MULTI_MAX); + if (pkts > 0) { + for (i = 0; i < pkts; ++i) { + buf = odp_buffer_from_packet(pkt_tbl[i]); + tmp_hdr_tbl[i] = odp_buf_to_hdr(buf); + } + queue_enq_multi(qentry, tmp_hdr_tbl, pkts); + } + } + + return nbr; +} diff --git a/platform/linux-dpdk/odp_queue.c b/platform/linux-dpdk/odp_queue.c new file mode 100644 index 0000000..554b8ea --- /dev/null +++ b/platform/linux-dpdk/odp_queue.c @@ -0,0 +1,435 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_queue.h> +#include <odp_queue_internal.h> +#include <odp_std_types.h> +#include <odp_align.h> +#include <odp_buffer.h> +#include <odp_buffer_internal.h> +#include <odp_buffer_pool_internal.h> +#include <odp_internal.h> +#include <odp_shared_memory.h> +#include <odp_schedule_internal.h> +#include <odp_config.h> +#include <odp_packet_io_internal.h> +#include <odp_packet_io_queue.h> +#include <odp_debug.h> +#include <odp_hints.h> + +#ifdef USE_TICKETLOCK +#include <odp_ticketlock.h> +#define LOCK(a) odp_ticketlock_lock(a) +#define UNLOCK(a) odp_ticketlock_unlock(a) +#define LOCK_INIT(a) odp_ticketlock_init(a) +#else +#include <odp_spinlock.h> +#define LOCK(a) odp_spinlock_lock(a) +#define UNLOCK(a) odp_spinlock_unlock(a) +#define LOCK_INIT(a) odp_spinlock_init(a) +#endif + +#include <string.h> + + +typedef struct queue_table_t { + queue_entry_t queue[ODP_CONFIG_QUEUES]; +} queue_table_t; + +static queue_table_t *queue_tbl; + + +queue_entry_t *get_qentry(uint32_t queue_id) +{ + return &queue_tbl->queue[queue_id]; +} + +static void queue_init(queue_entry_t *queue, const char *name, + odp_queue_type_t type, odp_queue_param_t *param) +{ + strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1); + queue->s.type = type; + + if (param) { + memcpy(&queue->s.param, param, sizeof(odp_queue_param_t)); + } else { + /* Defaults */ + memset(&queue->s.param, 0, sizeof(odp_queue_param_t)); + queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT; + queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT; + queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT; + } + + switch (type) { + case ODP_QUEUE_TYPE_PKTIN: + queue->s.enqueue = pktin_enqueue; + queue->s.dequeue = pktin_dequeue; + queue->s.enqueue_multi = pktin_enq_multi; + queue->s.dequeue_multi = pktin_deq_multi; + break; + case ODP_QUEUE_TYPE_PKTOUT: + queue->s.enqueue = pktout_enqueue; + queue->s.dequeue = pktout_dequeue; + queue->s.enqueue_multi = pktout_enq_multi; + queue->s.dequeue_multi = pktout_deq_multi; + break; + default: + queue->s.enqueue = queue_enq; + queue->s.dequeue = queue_deq; + queue->s.enqueue_multi = queue_enq_multi; + queue->s.dequeue_multi = queue_deq_multi; + break; + } + + queue->s.head = NULL; + queue->s.tail = NULL; + queue->s.sched_buf = ODP_BUFFER_INVALID; +} + + +int odp_queue_init_global(void) +{ + uint32_t i; + + ODP_DBG("Queue init ... "); + + queue_tbl = odp_shm_reserve("odp_queues", + sizeof(queue_table_t), + sizeof(queue_entry_t)); + + if (queue_tbl == NULL) + return -1; + + memset(queue_tbl, 0, sizeof(queue_table_t)); + + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { + /* init locks */ + queue_entry_t *queue = get_qentry(i); + LOCK_INIT(&queue->s.lock); + queue->s.handle = queue_from_id(i); + } + + ODP_DBG("done\n"); + ODP_DBG("Queue init global\n"); + ODP_DBG(" struct queue_entry_s size %zu\n", + sizeof(struct queue_entry_s)); + ODP_DBG(" queue_entry_t size %zu\n", + sizeof(queue_entry_t)); + ODP_DBG("\n"); + + return 0; +} + +odp_queue_type_t odp_queue_type(odp_queue_t handle) +{ + queue_entry_t *queue; + + queue = queue_to_qentry(handle); + + return queue->s.type; +} + +odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle) +{ + queue_entry_t *queue; + + queue = queue_to_qentry(handle); + + return queue->s.param.sched.sync; +} + +odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type, + odp_queue_param_t *param) +{ + uint32_t i; + queue_entry_t *queue; + odp_queue_t handle = ODP_QUEUE_INVALID; + + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { + queue = &queue_tbl->queue[i]; + + if (queue->s.status != QUEUE_STATUS_FREE) + continue; + + LOCK(&queue->s.lock); + if (queue->s.status == QUEUE_STATUS_FREE) { + queue_init(queue, name, type, param); + + if (type == ODP_QUEUE_TYPE_SCHED || + type == ODP_QUEUE_TYPE_PKTIN) + queue->s.status = QUEUE_STATUS_NOTSCHED; + else + queue->s.status = QUEUE_STATUS_READY; + + handle = queue->s.handle; + UNLOCK(&queue->s.lock); + break; + } + UNLOCK(&queue->s.lock); + } + + if (handle != ODP_QUEUE_INVALID && + (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) { + odp_buffer_t buf; + + buf = odp_schedule_buffer_alloc(handle); + if (buf == ODP_BUFFER_INVALID) { + ODP_ERR("queue_init: sched buf alloc failed\n"); + return ODP_QUEUE_INVALID; + } + + queue->s.sched_buf = buf; + odp_schedule_mask_set(handle, queue->s.param.sched.prio); + } + + return handle; +} + + +odp_buffer_t queue_sched_buf(odp_queue_t handle) +{ + queue_entry_t *queue; + queue = queue_to_qentry(handle); + + return queue->s.sched_buf; +} + + +int queue_sched_atomic(odp_queue_t handle) +{ + queue_entry_t *queue; + queue = queue_to_qentry(handle); + + return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC; +} + + +odp_queue_t odp_queue_lookup(const char *name) +{ + uint32_t i; + + for (i = 0; i < ODP_CONFIG_QUEUES; i++) { + queue_entry_t *queue = &queue_tbl->queue[i]; + + if (queue->s.status == QUEUE_STATUS_FREE) + continue; + + LOCK(&queue->s.lock); + if (strcmp(name, queue->s.name) == 0) { + /* found it */ + UNLOCK(&queue->s.lock); + return queue->s.handle; + } + UNLOCK(&queue->s.lock); + } + + return ODP_QUEUE_INVALID; +} + + +int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr) +{ + int sched = 0; + + LOCK(&queue->s.lock); + if (queue->s.head == NULL) { + /* Empty queue */ + queue->s.head = buf_hdr; + queue->s.tail = buf_hdr; + buf_hdr->pkt.next = NULL; + } else { + queue->s.tail->pkt.next = buf_hdr; + queue->s.tail = buf_hdr; + buf_hdr->pkt.next = NULL; + } + + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { + queue->s.status = QUEUE_STATUS_SCHED; + sched = 1; /* retval: schedule queue */ + } + UNLOCK(&queue->s.lock); + + /* Add queue to scheduling */ + if (sched == 1) + odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); + + return 0; +} + + +int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) +{ + int sched = 0; + int i; + odp_buffer_hdr_t *tail; + + for (i = 0; i < num - 1; i++) + buf_hdr[i]->pkt.next = buf_hdr[i+1]; + + tail = buf_hdr[num-1]; + buf_hdr[num-1]->pkt.next = NULL; + + LOCK(&queue->s.lock); + /* Empty queue */ + if (queue->s.head == NULL) + queue->s.head = buf_hdr[0]; + else + queue->s.tail->pkt.next = buf_hdr[0]; + + queue->s.tail = tail; + + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { + queue->s.status = QUEUE_STATUS_SCHED; + sched = 1; /* retval: schedule queue */ + } + UNLOCK(&queue->s.lock); + + /* Add queue to scheduling */ + if (sched == 1) + odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); + + return 0; +} + + +int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) +{ + odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; + queue_entry_t *queue; + int i; + + if (num > QUEUE_MULTI_MAX) + num = QUEUE_MULTI_MAX; + + queue = queue_to_qentry(handle); + + for (i = 0; i < num; i++) + buf_hdr[i] = odp_buf_to_hdr(buf[i]); + + return queue->s.enqueue_multi(queue, buf_hdr, num); +} + + +int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf) +{ + odp_buffer_hdr_t *buf_hdr; + queue_entry_t *queue; + + queue = queue_to_qentry(handle); + buf_hdr = odp_buf_to_hdr(buf); + + return queue->s.enqueue(queue, buf_hdr); +} + + +odp_buffer_hdr_t *queue_deq(queue_entry_t *queue) +{ + odp_buffer_hdr_t *buf_hdr = NULL; + + LOCK(&queue->s.lock); + + if (queue->s.head == NULL) { + /* Already empty queue */ + if (queue->s.status == QUEUE_STATUS_SCHED && + queue->s.type != ODP_QUEUE_TYPE_PKTIN) + queue->s.status = QUEUE_STATUS_NOTSCHED; + } else { + buf_hdr = queue->s.head; + queue->s.head = buf_hdr->pkt.next; + buf_hdr->pkt.next = NULL; + + if (queue->s.head == NULL) { + /* Queue is now empty */ + queue->s.tail = NULL; + } + } + + UNLOCK(&queue->s.lock); + + return buf_hdr; +} + + +int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) +{ + int i = 0; + + LOCK(&queue->s.lock); + + if (queue->s.head == NULL) { + /* Already empty queue */ + if (queue->s.status == QUEUE_STATUS_SCHED && + queue->s.type != ODP_QUEUE_TYPE_PKTIN) + queue->s.status = QUEUE_STATUS_NOTSCHED; + } else { + odp_buffer_hdr_t *hdr = queue->s.head; + + for (; i < num && hdr; i++) { + buf_hdr[i] = hdr; + /* odp_prefetch(hdr->addr); */ + hdr = hdr->pkt.next; + buf_hdr[i]->pkt.next = NULL; + } + + queue->s.head = hdr; + + if (hdr == NULL) { + /* Queue is now empty */ + queue->s.tail = NULL; + } + } + + UNLOCK(&queue->s.lock); + + return i; +} + + +int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) +{ + queue_entry_t *queue; + odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; + int i, ret; + + if (num > QUEUE_MULTI_MAX) + num = QUEUE_MULTI_MAX; + + queue = queue_to_qentry(handle); + + ret = queue->s.dequeue_multi(queue, buf_hdr, num); + + for (i = 0; i < ret; i++) + buf[i] = (odp_buffer_t) buf_hdr[i]; + + return ret; +} + + +odp_buffer_t odp_queue_deq(odp_queue_t handle) +{ + queue_entry_t *queue; + odp_buffer_hdr_t *buf_hdr; + + queue = queue_to_qentry(handle); + buf_hdr = queue->s.dequeue(queue); + + if (buf_hdr) + return (odp_buffer_t) buf_hdr; + + return ODP_BUFFER_INVALID; +} + + +void queue_lock(queue_entry_t *queue) +{ + LOCK(&queue->s.lock); +} + + +void queue_unlock(queue_entry_t *queue) +{ + UNLOCK(&queue->s.lock); +} diff --git a/platform/linux-dpdk/source/odp_buffer.c b/platform/linux-dpdk/source/odp_buffer.c deleted file mode 100644 index bfb5ff6..0000000 --- a/platform/linux-dpdk/source/odp_buffer.c +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <odp_buffer.h> -#include <odp_buffer_internal.h> -#include <odp_buffer_pool_internal.h> - -#include <string.h> -#include <stdio.h> - - -void *odp_buffer_addr(odp_buffer_t buf) -{ - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); - - return hdr->buf_addr; -} - - -size_t odp_buffer_size(odp_buffer_t buf) -{ - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); - - return hdr->buf_len; -} - - -int odp_buffer_type(odp_buffer_t buf) -{ - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); - - return hdr->type; -} - - -int odp_buffer_is_scatter(odp_buffer_t buf) -{ - odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); - - if (hdr->refcnt == 0) - return 0; - else - return 1; -} - - -int odp_buffer_is_valid(odp_buffer_t buf) -{ - odp_buffer_bits_t handle; - - handle.u32 = buf; - - return (handle.index != ODP_BUFFER_INVALID_INDEX); -} - - -int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) -{ - odp_buffer_hdr_t *hdr; - int len = 0; - - if (!odp_buffer_is_valid(buf)) { - printf("Buffer is not valid.\n"); - return len; - } - - hdr = odp_buf_to_hdr(buf); - - len += snprintf(&str[len], n-len, - "Buffer\n"); - len += snprintf(&str[len], n-len, - " pool %"PRIu64"\n", (int64_t) hdr->pool); - len += snprintf(&str[len], n-len, - " phy_addr %"PRIu64"\n", hdr->buf_physaddr); - len += snprintf(&str[len], n-len, - " addr %p\n", hdr->buf_addr); - len += snprintf(&str[len], n-len, - " size %u\n", hdr->buf_len); - len += snprintf(&str[len], n-len, - " ref_count %i\n", hdr->refcnt); - len += snprintf(&str[len], n-len, - " type %i\n", hdr->type); - - return len; -} - - -void odp_buffer_print(odp_buffer_t buf) -{ - int max_len = 512; - char str[max_len]; - int len; - - len = odp_buffer_snprint(str, max_len-1, buf); - str[len] = 0; - - printf("\n%s\n", str); -} - diff --git a/platform/linux-dpdk/source/odp_buffer_pool.c b/platform/linux-dpdk/source/odp_buffer_pool.c deleted file mode 100644 index de90275..0000000 --- a/platform/linux-dpdk/source/odp_buffer_pool.c +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <odp_std_types.h> -#include <odp_buffer_pool.h> -#include <odp_buffer_pool_internal.h> -#include <odp_buffer_internal.h> -#include <odp_packet_internal.h> -#include <odp_shared_memory.h> -#include <odp_align.h> -#include <odp_internal.h> -#include <odp_config.h> -#include <odp_hints.h> -#include <odp_debug.h> - -#include <string.h> -#include <stdlib.h> - -/* for DPDK */ -#include <odp_packet_dpdk.h> - -#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) -#define NB_MBUF 8192 - -#ifdef POOL_USE_TICKETLOCK -#include <odp_ticketlock.h> -#define LOCK(a) odp_ticketlock_lock(a) -#define UNLOCK(a) odp_ticketlock_unlock(a) -#define LOCK_INIT(a) odp_ticketlock_init(a) -#else -#include <odp_spinlock.h> -#define LOCK(a) odp_spinlock_lock(a) -#define UNLOCK(a) odp_spinlock_unlock(a) -#define LOCK_INIT(a) odp_spinlock_init(a) -#endif - - -#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS -#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS -#endif - -#define NULL_INDEX ((uint32_t)-1) - - -typedef union pool_entry_u { - struct pool_entry_s s; - - uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))]; - -} pool_entry_t; - - -typedef struct pool_table_t { - pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS]; - -} pool_table_t; - - -/* The pool table */ -static pool_table_t *pool_tbl; - -/* Pool entry pointers (for inlining) */ -void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS]; - - -int odp_buffer_pool_init_global(void) -{ - odp_buffer_pool_t i; - - pool_tbl = odp_shm_reserve("odp_buffer_pools", - sizeof(pool_table_t), - sizeof(pool_entry_t)); - - if (pool_tbl == NULL) - return -1; - - memset(pool_tbl, 0, sizeof(pool_table_t)); - - - for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) { - /* init locks */ - pool_entry_t *pool = &pool_tbl->pool[i]; - LOCK_INIT(&pool->s.lock); - pool->s.pool = i; - - pool_entry_ptr[i] = pool; - } - - ODP_DBG("\nBuffer pool init global\n"); - ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct pool_entry_s)); - ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t)); - ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t)); - ODP_DBG("\n"); - - return 0; -} - - -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; - 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, 32, - sizeof(struct rte_pktmbuf_pool_private), - rte_pktmbuf_pool_init, NULL, - rte_pktmbuf_init, NULL, - rte_socket_id(), 0); - if (pktmbuf_pool == NULL) { - ODP_ERR("Cannot init DPDK mbuf pool\n"); - return -1; - } - - return (odp_buffer_pool_t) pktmbuf_pool; -} - - -odp_buffer_pool_t odp_buffer_pool_lookup(const char *name) -{ - struct rte_mempool *mp = NULL; - - mp = rte_mempool_lookup(name); - if (mp == NULL) - return ODP_BUFFER_POOL_INVALID; - - return (odp_buffer_pool_t)mp; -} - - -odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id) -{ - return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool *)pool_id); -} - - -void odp_buffer_free(odp_buffer_t buf) -{ - rte_pktmbuf_free((struct rte_mbuf *)buf); -} - - -void odp_buffer_pool_print(odp_buffer_pool_t pool_id) -{ - rte_mempool_dump((const struct rte_mempool *)pool_id); -} diff --git a/platform/linux-dpdk/source/odp_init.c b/platform/linux-dpdk/source/odp_init.c deleted file mode 100644 index ecc2066..0000000 --- a/platform/linux-dpdk/source/odp_init.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <odp_init.h> -#include <odp_internal.h> -#include <odp_debug.h> -#include <odp_packet_dpdk.h> - -int odp_init_dpdk(void) -{ - int test_argc = 5; - char *test_argv[6]; - int core_count, i, num_cores = 0; - char core_mask[8]; - - core_count = odp_sys_core_count(); - for (i = 0; i < core_count; i++) - num_cores += (0x1 << i); - sprintf(core_mask, "%x", num_cores); - - test_argv[0] = malloc(sizeof("odp_dpdk")); - strcpy(test_argv[0], "odp_dpdk"); - test_argv[1] = malloc(sizeof("-c")); - strcpy(test_argv[1], "-c"); - test_argv[2] = malloc(sizeof(core_mask)); - strcpy(test_argv[2], core_mask); - test_argv[3] = malloc(sizeof("-n")); - strcpy(test_argv[3], "-n"); - test_argv[4] = malloc(sizeof("3")); - strcpy(test_argv[4], "3"); - - if (rte_eal_init(test_argc, (char **)test_argv) < 0) { - ODP_ERR("Cannot init the Intel DPDK EAL!"); - return -1; - } - - if (rte_pmd_init_all() < 0) { - ODP_ERR("Cannot init pmd\n"); - return -1; - } - - if (rte_eal_pci_probe() < 0) { - ODP_ERR("Cannot probe PCI\n"); - return -1; - } - - return 0; -} - -int odp_init_global(void) -{ - odp_thread_init_global(); - - odp_system_info_init(); - - if (odp_init_dpdk()) { - ODP_ERR("ODP dpdk init failed.\n"); - return -1; - } - - if (odp_shm_init_global()) { - ODP_ERR("ODP shm init failed.\n"); - return -1; - } - - if (odp_buffer_pool_init_global()) { - ODP_ERR("ODP buffer pool init failed.\n"); - return -1; - } - - if (odp_queue_init_global()) { - ODP_ERR("ODP queue init failed.\n"); - return -1; - } - - if (odp_schedule_init_global()) { - ODP_ERR("ODP schedule init failed.\n"); - return -1; - } - - if (odp_pktio_init_global()) { - ODP_ERR("ODP packet io init failed.\n"); - return -1; - } - - if (odp_timer_init_global()) { - ODP_ERR("ODP timer init failed.\n"); - return -1; - } - - return 0; -} - - -int odp_init_local(int thr_id) -{ - odp_thread_init_local(thr_id); - - if (odp_pktio_init_local()) { - ODP_ERR("ODP packet io local init failed.\n"); - return -1; - } - - if (odp_schedule_init_local()) { - ODP_ERR("ODP schedule local init failed.\n"); - return -1; - } - - return 0; -} diff --git a/platform/linux-dpdk/source/odp_packet.c b/platform/linux-dpdk/source/odp_packet.c deleted file mode 100644 index c34e626..0000000 --- a/platform/linux-dpdk/source/odp_packet.c +++ /dev/null @@ -1,374 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <odp_packet.h> -#include <odp_packet_internal.h> -#include <odp_hints.h> -#include <odp_byteorder.h> - -#include <helper/odp_eth.h> -#include <helper/odp_ip.h> - -#include <string.h> -#include <stdio.h> - -static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, - size_t *offset_out); -static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, - size_t *offset_out); - -void odp_packet_init(odp_packet_t pkt) -{ - odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); - const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); - uint8_t *start; - size_t len; - - start = (uint8_t *)pkt_hdr + start_offset; - len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; - memset(start, 0, len); - - pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; - pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; - pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID; -} - -odp_packet_t odp_packet_from_buffer(odp_buffer_t buf) -{ - return (odp_packet_t)buf; -} - -odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt) -{ - return (odp_buffer_t)pkt; -} - -void odp_packet_set_len(odp_packet_t pkt, size_t len) -{ - /* for rte_pktmbuf */ - odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(odp_buffer_from_packet(pkt)); - buf_hdr->pkt.data_len = len; - - odp_packet_hdr(pkt)->frame_len = len; -} - -size_t odp_packet_get_len(odp_packet_t pkt) -{ - return odp_packet_hdr(pkt)->frame_len; -} - -uint8_t *odp_packet_buf_addr(odp_packet_t pkt) -{ - return odp_buffer_addr(odp_buffer_from_packet(pkt)); -} - -uint8_t *odp_packet_start(odp_packet_t pkt) -{ - return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset; -} - - -uint8_t *odp_packet_l2(odp_packet_t pkt) -{ - const size_t offset = odp_packet_l2_offset(pkt); - - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) - return NULL; - - return odp_packet_buf_addr(pkt) + offset; -} - -size_t odp_packet_l2_offset(odp_packet_t pkt) -{ - return odp_packet_hdr(pkt)->l2_offset; -} - -void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset) -{ - odp_packet_hdr(pkt)->l2_offset = offset; -} - -uint8_t *odp_packet_l3(odp_packet_t pkt) -{ - const size_t offset = odp_packet_l3_offset(pkt); - - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) - return NULL; - - return odp_packet_buf_addr(pkt) + offset; -} - -size_t odp_packet_l3_offset(odp_packet_t pkt) -{ - return odp_packet_hdr(pkt)->l3_offset; -} - -void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset) -{ - odp_packet_hdr(pkt)->l3_offset = offset; -} - -uint8_t *odp_packet_l4(odp_packet_t pkt) -{ - const size_t offset = odp_packet_l4_offset(pkt); - - if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) - return NULL; - - return odp_packet_buf_addr(pkt) + offset; -} - -size_t odp_packet_l4_offset(odp_packet_t pkt) -{ - return odp_packet_hdr(pkt)->l4_offset; -} - -void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset) -{ - odp_packet_hdr(pkt)->l4_offset = offset; -} - -/** - * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP - * - * Internal function: caller is resposible for passing only valid packet handles - * , lengths and offsets (usually done&called in packet input). - * - * @param pkt Packet handle - * @param len Packet length in bytes - * @param frame_offset Byte offset to L2 header - */ -void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset) -{ - odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); - odp_ethhdr_t *eth; - odp_vlanhdr_t *vlan; - odp_ipv4hdr_t *ipv4; - odp_ipv6hdr_t *ipv6; - uint16_t ethtype; - size_t offset = 0; - uint8_t ip_proto = 0; - - pkt_hdr->input_flags.eth = 1; - pkt_hdr->frame_offset = frame_offset; - pkt_hdr->frame_len = len; - - if (odp_unlikely(len < ODP_ETH_LEN_MIN)) { - pkt_hdr->error_flags.frame_len = 1; - return; - } else if (len > ODP_ETH_LEN_MAX) { - pkt_hdr->input_flags.jumbo = 1; - } - - /* Assume valid L2 header, no CRC/FCS check in SW */ - pkt_hdr->input_flags.l2 = 1; - pkt_hdr->l2_offset = frame_offset; - - eth = (odp_ethhdr_t *)odp_packet_start(pkt); - ethtype = odp_be_to_cpu_16(eth->type); - vlan = (odp_vlanhdr_t *)ð->type; - - if (ethtype == ODP_ETHTYPE_VLAN_OUTER) { - pkt_hdr->input_flags.vlan_qinq = 1; - ethtype = odp_be_to_cpu_16(vlan->tpid); - offset += sizeof(odp_vlanhdr_t); - vlan = &vlan[1]; - } - - if (ethtype == ODP_ETHTYPE_VLAN) { - pkt_hdr->input_flags.vlan = 1; - ethtype = odp_be_to_cpu_16(vlan->tpid); - offset += sizeof(odp_vlanhdr_t); - } - - /* Set l3_offset+flag only for known ethtypes */ - switch (ethtype) { - case ODP_ETHTYPE_IPV4: - pkt_hdr->input_flags.ipv4 = 1; - pkt_hdr->input_flags.l3 = 1; - pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; - ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt); - ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset); - break; - case ODP_ETHTYPE_IPV6: - pkt_hdr->input_flags.ipv6 = 1; - pkt_hdr->input_flags.l3 = 1; - pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset; - ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt); - ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset); - break; - case ODP_ETHTYPE_ARP: - pkt_hdr->input_flags.arp = 1; - /* fall through */ - default: - ip_proto = 0; - break; - } - - switch (ip_proto) { - case ODP_IPPROTO_UDP: - pkt_hdr->input_flags.udp = 1; - pkt_hdr->input_flags.l4 = 1; - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; - break; - case ODP_IPPROTO_TCP: - pkt_hdr->input_flags.tcp = 1; - pkt_hdr->input_flags.l4 = 1; - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; - break; - case ODP_IPPROTO_SCTP: - pkt_hdr->input_flags.sctp = 1; - pkt_hdr->input_flags.l4 = 1; - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; - break; - case ODP_IPPROTO_ICMP: - pkt_hdr->input_flags.icmp = 1; - pkt_hdr->input_flags.l4 = 1; - pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset; - break; - default: - /* 0 or unhandled IP protocols, don't set L4 flag+offset */ - if (pkt_hdr->input_flags.ipv6) { - /* IPv6 next_hdr is not L4, mark as IP-option instead */ - pkt_hdr->input_flags.ipopt = 1; - } - break; - } -} - -static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4, - size_t *offset_out) -{ - uint8_t ihl; - uint16_t frag_offset; - - ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl); - if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) { - pkt_hdr->error_flags.ip_err = 1; - return 0; - } - - if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) { - pkt_hdr->input_flags.ipopt = 1; - return 0; - } - - /* A packet is a fragment if: - * "more fragments" flag is set (all fragments except the last) - * OR - * "fragment offset" field is nonzero (all fragments except the first) - */ - frag_offset = odp_be_to_cpu_16(ipv4->frag_offset); - if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) { - pkt_hdr->input_flags.ipfrag = 1; - return 0; - } - - if (ipv4->proto == ODP_IPPROTO_ESP || - ipv4->proto == ODP_IPPROTO_AH) { - pkt_hdr->input_flags.ipsec = 1; - return 0; - } - - /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after return */ - - *offset_out = sizeof(uint32_t) * ihl; - return ipv4->proto; -} - -static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6, - size_t *offset_out) -{ - if (ipv6->next_hdr == ODP_IPPROTO_ESP || - ipv6->next_hdr == ODP_IPPROTO_AH) { - pkt_hdr->input_flags.ipopt = 1; - pkt_hdr->input_flags.ipsec = 1; - return 0; - } - - if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) { - pkt_hdr->input_flags.ipopt = 1; - pkt_hdr->input_flags.ipfrag = 1; - return 0; - } - - /* Don't step through more extensions */ - *offset_out = ODP_IPV6HDR_LEN; - return ipv6->next_hdr; -} - -void odp_packet_print(odp_packet_t pkt) -{ - int max_len = 512; - char str[max_len]; - int len = 0; - int n = max_len-1; - odp_packet_hdr_t *hdr = odp_packet_hdr(pkt); - - len += snprintf(&str[len], n-len, "Packet "); - len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt); - len += snprintf(&str[len], n-len, - " input_flags 0x%x\n", hdr->input_flags.all); - len += snprintf(&str[len], n-len, - " error_flags 0x%x\n", hdr->error_flags.all); - len += snprintf(&str[len], n-len, - " output_flags 0x%x\n", hdr->output_flags.all); - len += snprintf(&str[len], n-len, - " frame_offset %u\n", hdr->frame_offset); - len += snprintf(&str[len], n-len, - " l2_offset %u\n", hdr->l2_offset); - len += snprintf(&str[len], n-len, - " l3_offset %u\n", hdr->l3_offset); - len += snprintf(&str[len], n-len, - " l4_offset %u\n", hdr->l4_offset); - len += snprintf(&str[len], n-len, - " frame_len %u\n", hdr->frame_len); - len += snprintf(&str[len], n-len, - " input %u\n", hdr->input); - str[len] = '\0'; - - printf("\n%s\n", str); -} - -int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src) -{ - odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst); - odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src); - const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr); - uint8_t *start_src; - uint8_t *start_dst; - size_t len; - - if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID) - return -1; - - /* if (pkt_hdr_dst->buf_hdr.size < */ - /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */ - if (pkt_hdr_dst->buf_hdr.buf_len < - pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) - return -1; - - /* Copy packet header */ - start_dst = (uint8_t *)pkt_hdr_dst + start_offset; - start_src = (uint8_t *)pkt_hdr_src + start_offset; - len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset; - memcpy(start_dst, start_src, len); - - /* Copy frame payload */ - start_dst = (uint8_t *)odp_packet_start(pkt_dst); - start_src = (uint8_t *)odp_packet_start(pkt_src); - len = pkt_hdr_src->frame_len; - memcpy(start_dst, start_src, len); - - /* Copy useful things from the buffer header */ - /* pkt_hdr_dst->buf_hdr.cur_offset = pkt_hdr_src->buf_hdr.cur_offset; */ - - /* Create a copy of the scatter list */ - /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */ - /* odp_buffer_from_packet(pkt_src)); */ - - return 0; -} diff --git a/platform/linux-dpdk/source/odp_packet_dpdk.c b/platform/linux-dpdk/source/odp_packet_dpdk.c deleted file mode 100644 index 6d16bbe..0000000 --- a/platform/linux-dpdk/source/odp_packet_dpdk.c +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <poll.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> - -#include <linux/ethtool.h> -#include <linux/sockios.h> - -#include <odp_hints.h> -#include <odp_thread.h> - -#include <odp_packet_dpdk.h> -#include <net/if.h> - -/* - * RX and TX Prefetch, Host, and Write-back threshold values should be - * carefully set for optimal performance. Consult the network - * controller's datasheet and supporting DPDK documentation for guidance - * on how these parameters should be set. - */ -#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ -#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ -#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */ - -/* - * These default values are optimized for use with the Intel(R) 82599 10 GbE - * Controller and the DPDK ixgbe PMD. Consider using other values for other - * network controllers and/or network drivers. - */ -#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */ -#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ -#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ - -#define MAX_PKT_BURST 32 -#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ -#define RTE_TEST_RX_DESC_DEFAULT 128 -#define RTE_TEST_TX_DESC_DEFAULT 512 -static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; -static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; - -static const struct rte_eth_conf port_conf = { - .rxmode = { - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled */ - .hw_ip_checksum = 0, /**< IP checksum offload disabled */ - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, -}; - -static const struct rte_eth_rxconf rx_conf = { - .rx_thresh = { - .pthresh = RX_PTHRESH, - .hthresh = RX_HTHRESH, - .wthresh = RX_WTHRESH, - }, -}; - -static const struct rte_eth_txconf tx_conf = { - .tx_thresh = { - .pthresh = TX_PTHRESH, - .hthresh = TX_HTHRESH, - .wthresh = TX_WTHRESH, - }, - .tx_free_thresh = 0, /* Use PMD default values */ - .tx_rs_thresh = 0, /* Use PMD default values */ - /* - * As the example won't handle mult-segments and offload cases, - * set the flag by default. - */ - .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS, -}; - -int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, - odp_buffer_pool_t pool) -{ - ODP_DBG("setup_pkt_dpdk\n"); - - static struct ether_addr eth_addr[RTE_MAX_ETHPORTS]; - uint8_t portid = 0; - uint16_t queueid = 0; - int ret; - printf("vincent netdev: %s\n", netdev); - printf("vincent pool: %lx\n", pool); - - portid = atoi(netdev); - pkt_dpdk->portid = portid; - pkt_dpdk->queueid = queueid; - pkt_dpdk->pool = pool; - printf("vincent portid: %u\n", portid); - - fflush(stdout); - ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); - if (ret < 0) - ODP_ERR("Cannot configure device: err=%d, port=%u\n", - ret, (unsigned) portid); - - rte_eth_macaddr_get(portid, ð_addr[portid]); - ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", - (unsigned) portid, - eth_addr[portid].addr_bytes[0], - eth_addr[portid].addr_bytes[1], - eth_addr[portid].addr_bytes[2], - eth_addr[portid].addr_bytes[3], - eth_addr[portid].addr_bytes[4], - eth_addr[portid].addr_bytes[5]); - - /* init one RX queue on each port */ - fflush(stdout); - ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd, - rte_eth_dev_socket_id(portid), &rx_conf, - (struct rte_mempool *)pool); - if (ret < 0) - ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n", - ret, (unsigned) portid); - ODP_DBG("dpdk rx queue setup done\n"); - - /* init one TX queue on each port */ - fflush(stdout); - ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, - rte_eth_dev_socket_id(portid), &tx_conf); - if (ret < 0) - ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n", - ret, (unsigned) portid); - ODP_DBG("dpdk tx queue setup done\n"); - - /* Start device */ - ret = rte_eth_dev_start(portid); - if (ret < 0) - ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n", - ret, (unsigned) portid); - ODP_DBG("dpdk setup done\n\n"); - - - return 0; -} - -int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk) -{ - ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid); - - return 0; -} - -int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], - unsigned len) -{ - return rte_eth_rx_burst((uint8_t)pkt_dpdk->portid, - (uint16_t)pkt_dpdk->queueid, - (struct rte_mbuf **)pkt_table, (uint16_t)len); -} - -int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], - unsigned len) -{ - return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid, - (uint16_t)pkt_dpdk->queueid, - (struct rte_mbuf **)pkt_table, (uint16_t)len); -} diff --git a/platform/linux-dpdk/source/odp_packet_io.c b/platform/linux-dpdk/source/odp_packet_io.c deleted file mode 100644 index abea0ec..0000000 --- a/platform/linux-dpdk/source/odp_packet_io.c +++ /dev/null @@ -1,561 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <odp_packet_io.h> -#include <odp_packet_io_internal.h> -#include <odp_packet_io_queue.h> -#include <odp_packet.h> -#include <odp_packet_internal.h> -#include <odp_internal.h> -#include <odp_spinlock.h> -#include <odp_shared_memory.h> -#include <odp_packet_socket.h> -#ifdef ODP_HAVE_NETMAP -#include <odp_packet_netmap.h> -#endif -#include <odp_hints.h> -#include <odp_config.h> -#include <odp_queue_internal.h> -#include <odp_schedule_internal.h> -#include <odp_debug.h> - -#include <odp_pktio_socket.h> -#ifdef ODP_HAVE_NETMAP -#include <odp_pktio_netmap.h> -#endif - -#include <string.h> - -typedef struct { - pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; -} pktio_table_t; - -static pktio_table_t *pktio_tbl; - - -static pktio_entry_t *get_entry(odp_pktio_t id) -{ - if (odp_unlikely(id == ODP_PKTIO_INVALID || - id > ODP_CONFIG_PKTIO_ENTRIES)) - return NULL; - - return &pktio_tbl->entries[id - 1]; -} - -int odp_pktio_init_global(void) -{ - char name[ODP_QUEUE_NAME_LEN]; - pktio_entry_t *pktio_entry; - queue_entry_t *queue_entry; - odp_queue_t qid; - int id; - - pktio_tbl = odp_shm_reserve("odp_pktio_entries", - sizeof(pktio_table_t), - sizeof(pktio_entry_t)); - if (pktio_tbl == NULL) - return -1; - - memset(pktio_tbl, 0, sizeof(pktio_table_t)); - - for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) { - pktio_entry = get_entry(id); - - odp_spinlock_init(&pktio_entry->s.lock); - - /* Create a default output queue for each pktio resource */ - snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id); - name[ODP_QUEUE_NAME_LEN-1] = '\0'; - - qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL); - if (qid == ODP_QUEUE_INVALID) - return -1; - pktio_entry->s.outq_default = qid; - - queue_entry = queue_to_qentry(qid); - queue_entry->s.pktout = id; - } - - return 0; -} - -int odp_pktio_init_local(void) -{ - return 0; -} - -static int is_free(pktio_entry_t *entry) -{ - return (entry->s.taken == 0); -} - -static void set_free(pktio_entry_t *entry) -{ - entry->s.taken = 0; -} - -static void set_taken(pktio_entry_t *entry) -{ - entry->s.taken = 1; -} - -static void lock_entry(pktio_entry_t *entry) -{ - odp_spinlock_lock(&entry->s.lock); -} - -static void unlock_entry(pktio_entry_t *entry) -{ - odp_spinlock_unlock(&entry->s.lock); -} - -static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params) -{ - set_taken(entry); - entry->s.inq_default = ODP_QUEUE_INVALID; - switch (params->type) { - case ODP_PKTIO_TYPE_SOCKET_BASIC: - case ODP_PKTIO_TYPE_SOCKET_MMSG: - case ODP_PKTIO_TYPE_SOCKET_MMAP: - memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); - memset(&entry->s.pkt_sock_mmap, 0, - sizeof(entry->s.pkt_sock_mmap)); - break; -#ifdef ODP_HAVE_NETMAP - case ODP_PKTIO_TYPE_NETMAP: - memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); - break; -#endif - case ODP_PKTIO_TYPE_DPDK: - memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk)); - break; - default: - ODP_ERR("Packet I/O type not supported. Please recompile\n"); - break; - } - /* Save pktio parameters, type is the most useful */ - memcpy(&entry->s.params, params, sizeof(*params)); -} - -static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params) -{ - odp_pktio_t id; - pktio_entry_t *entry; - int i; - - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { - entry = &pktio_tbl->entries[i]; - if (is_free(entry)) { - lock_entry(entry); - if (is_free(entry)) { - init_pktio_entry(entry, params); - id = i + 1; - return id; /* return with entry locked! */ - } - unlock_entry(entry); - } - } - - return ODP_PKTIO_INVALID; -} - -static int free_pktio_entry(odp_pktio_t id) -{ - pktio_entry_t *entry = get_entry(id); - - if (entry == NULL) - return -1; - - set_free(entry); - - return 0; -} - -odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool, - odp_pktio_params_t *params) -{ - odp_pktio_t id; - pktio_entry_t *pktio_entry; - int res; - - if (params == NULL) { - ODP_ERR("Invalid pktio params\n"); - return ODP_PKTIO_INVALID; - } - - switch (params->type) { - case ODP_PKTIO_TYPE_SOCKET_BASIC: - case ODP_PKTIO_TYPE_SOCKET_MMSG: - case ODP_PKTIO_TYPE_SOCKET_MMAP: - ODP_DBG("Allocating socket pktio\n"); - break; -#ifdef ODP_HAVE_NETMAP - case ODP_PKTIO_TYPE_NETMAP: - ODP_DBG("Allocating netmap pktio\n"); - break; -#endif - case ODP_PKTIO_TYPE_DPDK: - ODP_DBG("Allocating dpdk pktio\n"); - break; - default: - ODP_ERR("Invalid pktio type: %02x\n", params->type); - return ODP_PKTIO_INVALID; - } - - id = alloc_lock_pktio_entry(params); - if (id == ODP_PKTIO_INVALID) { - ODP_ERR("No resources available.\n"); - return ODP_PKTIO_INVALID; - } - /* if successful, alloc_pktio_entry() returns with the entry locked */ - - pktio_entry = get_entry(id); - - switch (params->type) { - case ODP_PKTIO_TYPE_SOCKET_BASIC: - case ODP_PKTIO_TYPE_SOCKET_MMSG: - res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); - if (res == -1) { - close_pkt_sock(&pktio_entry->s.pkt_sock); - free_pktio_entry(id); - id = ODP_PKTIO_INVALID; - } - break; - case ODP_PKTIO_TYPE_SOCKET_MMAP: - res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev, - pool, params->sock_params.fanout); - if (res == -1) { - close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); - free_pktio_entry(id); - id = ODP_PKTIO_INVALID; - } - break; -#ifdef ODP_HAVE_NETMAP - case ODP_PKTIO_TYPE_NETMAP: - - res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, - pool, ¶ms->nm_params); - if (res == -1) { - close_pkt_netmap(&pktio_entry->s.pkt_nm); - free_pktio_entry(id); - id = ODP_PKTIO_INVALID; - } - break; -#endif - case ODP_PKTIO_TYPE_DPDK: - res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool); - if (res == -1) { - close_pkt_dpdk(&pktio_entry->s.pkt_dpdk); - free_pktio_entry(id); - id = ODP_PKTIO_INVALID; - } - break; - default: - free_pktio_entry(id); - id = ODP_PKTIO_INVALID; - ODP_ERR("Invalid pktio type. Please recompile.\n"); - break; - } - - unlock_entry(pktio_entry); - return id; -} - -int odp_pktio_close(odp_pktio_t id) -{ - pktio_entry_t *entry; - int res = -1; - - entry = get_entry(id); - if (entry == NULL) - return -1; - - lock_entry(entry); - if (!is_free(entry)) { - switch (entry->s.params.type) { - case ODP_PKTIO_TYPE_SOCKET_BASIC: - case ODP_PKTIO_TYPE_SOCKET_MMSG: - res = close_pkt_sock(&entry->s.pkt_sock); - break; - case ODP_PKTIO_TYPE_SOCKET_MMAP: - res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); - break; -#ifdef ODP_HAVE_NETMAP - case ODP_PKTIO_TYPE_NETMAP: - res = close_pkt_netmap(&entry->s.pkt_nm); - break; -#endif - case ODP_PKTIO_TYPE_DPDK: - res = close_pkt_dpdk(&entry->s.pkt_dpdk); - break; - default: - break; - res |= free_pktio_entry(id); - } - } - unlock_entry(entry); - - if (res != 0) - return -1; - - return 0; -} - -void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio) -{ - odp_packet_hdr(pkt)->input = pktio; -} - -odp_pktio_t odp_pktio_get_input(odp_packet_t pkt) -{ - return odp_packet_hdr(pkt)->input; -} - -int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) -{ - pktio_entry_t *pktio_entry = get_entry(id); - int pkts; - int i; - - if (pktio_entry == NULL) - return -1; - - lock_entry(pktio_entry); - switch (pktio_entry->s.params.type) { - case ODP_PKTIO_TYPE_SOCKET_BASIC: - pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, - pkt_table, len); - break; - case ODP_PKTIO_TYPE_SOCKET_MMSG: - pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, - pkt_table, len); - break; - case ODP_PKTIO_TYPE_SOCKET_MMAP: - pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, - pkt_table, len); - break; -#ifdef ODP_HAVE_NETMAP - case ODP_PKTIO_TYPE_NETMAP: - pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len); - break; -#endif - case ODP_PKTIO_TYPE_DPDK: - pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, len); - break; - default: - pkts = -1; - break; - } - - unlock_entry(pktio_entry); - if (pkts < 0) - return pkts; - - for (i = 0; i < pkts; ++i) - odp_pktio_set_input(pkt_table[i], id); - - return pkts; -} - -int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) -{ - pktio_entry_t *pktio_entry = get_entry(id); - int pkts; - - if (pktio_entry == NULL) - return -1; - - lock_entry(pktio_entry); - switch (pktio_entry->s.params.type) { - case ODP_PKTIO_TYPE_SOCKET_BASIC: - pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, - pkt_table, len); - break; - case ODP_PKTIO_TYPE_SOCKET_MMSG: - pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, - pkt_table, len); - break; - case ODP_PKTIO_TYPE_SOCKET_MMAP: - pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, - pkt_table, len); - break; -#ifdef ODP_HAVE_NETMAP - case ODP_PKTIO_TYPE_NETMAP: - pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, - pkt_table, len); - break; -#endif - case ODP_PKTIO_TYPE_DPDK: - pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk, - pkt_table, len); - break; - default: - pkts = -1; - } - unlock_entry(pktio_entry); - - return pkts; -} - -int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue) -{ - pktio_entry_t *pktio_entry = get_entry(id); - queue_entry_t *qentry = queue_to_qentry(queue); - - if (pktio_entry == NULL || qentry == NULL) - return -1; - - if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN) - return -1; - - lock_entry(pktio_entry); - pktio_entry->s.inq_default = queue; - unlock_entry(pktio_entry); - - queue_lock(qentry); - qentry->s.pktin = id; - qentry->s.status = QUEUE_STATUS_SCHED; - queue_unlock(qentry); - - odp_schedule_queue(queue, qentry->s.param.sched.prio); - - return 0; -} - -int odp_pktio_inq_remdef(odp_pktio_t id) -{ - return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID); -} - -odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id) -{ - pktio_entry_t *pktio_entry = get_entry(id); - - if (pktio_entry == NULL) - return ODP_QUEUE_INVALID; - - return pktio_entry->s.inq_default; -} - -odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id) -{ - pktio_entry_t *pktio_entry = get_entry(id); - - if (pktio_entry == NULL) - return ODP_QUEUE_INVALID; - - return pktio_entry->s.outq_default; -} - -int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) -{ - odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr); - int len = 1; - int nbr; - - nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); - return (nbr == len ? 0 : -1); -} - -odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry) -{ - (void)qentry; - return NULL; -} - -int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], - int num) -{ - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; - int nbr; - int i; - - for (i = 0; i < num; ++i) - pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) buf_hdr[i]); - - nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); - return (nbr == num ? 0 : -1); -} - -int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], - int num) -{ - (void)qentry; - (void)buf_hdr; - (void)num; - - return 0; -} - -int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) -{ - /* Use default action */ - return queue_enq(qentry, buf_hdr); -} - -odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry) -{ - odp_buffer_hdr_t *buf_hdr; - - buf_hdr = queue_deq(qentry); - - if (buf_hdr == NULL) { - odp_packet_t pkt; - odp_buffer_t buf; - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; - odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; - int pkts, i, j; - - pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, - QUEUE_MULTI_MAX); - - if (pkts > 0) { - pkt = pkt_tbl[0]; - buf = odp_buffer_from_packet(pkt); - buf_hdr = odp_buf_to_hdr(buf); - - for (i = 1, j = 0; i < pkts; ++i) { - buf = odp_buffer_from_packet(pkt_tbl[i]); - tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf); - } - queue_enq_multi(qentry, tmp_hdr_tbl, j); - } - } - - return buf_hdr; -} - -int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) -{ - /* Use default action */ - return queue_enq_multi(qentry, buf_hdr, num); -} - -int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) -{ - int nbr; - - nbr = queue_deq_multi(qentry, buf_hdr, num); - - if (nbr < num) { - odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; - odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; - odp_buffer_t buf; - int pkts, i; - - pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, - QUEUE_MULTI_MAX); - if (pkts > 0) { - for (i = 0; i < pkts; ++i) { - buf = odp_buffer_from_packet(pkt_tbl[i]); - tmp_hdr_tbl[i] = odp_buf_to_hdr(buf); - } - queue_enq_multi(qentry, tmp_hdr_tbl, pkts); - } - } - - return nbr; -} diff --git a/platform/linux-dpdk/source/odp_queue.c b/platform/linux-dpdk/source/odp_queue.c deleted file mode 100644 index 554b8ea..0000000 --- a/platform/linux-dpdk/source/odp_queue.c +++ /dev/null @@ -1,435 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <odp_queue.h> -#include <odp_queue_internal.h> -#include <odp_std_types.h> -#include <odp_align.h> -#include <odp_buffer.h> -#include <odp_buffer_internal.h> -#include <odp_buffer_pool_internal.h> -#include <odp_internal.h> -#include <odp_shared_memory.h> -#include <odp_schedule_internal.h> -#include <odp_config.h> -#include <odp_packet_io_internal.h> -#include <odp_packet_io_queue.h> -#include <odp_debug.h> -#include <odp_hints.h> - -#ifdef USE_TICKETLOCK -#include <odp_ticketlock.h> -#define LOCK(a) odp_ticketlock_lock(a) -#define UNLOCK(a) odp_ticketlock_unlock(a) -#define LOCK_INIT(a) odp_ticketlock_init(a) -#else -#include <odp_spinlock.h> -#define LOCK(a) odp_spinlock_lock(a) -#define UNLOCK(a) odp_spinlock_unlock(a) -#define LOCK_INIT(a) odp_spinlock_init(a) -#endif - -#include <string.h> - - -typedef struct queue_table_t { - queue_entry_t queue[ODP_CONFIG_QUEUES]; -} queue_table_t; - -static queue_table_t *queue_tbl; - - -queue_entry_t *get_qentry(uint32_t queue_id) -{ - return &queue_tbl->queue[queue_id]; -} - -static void queue_init(queue_entry_t *queue, const char *name, - odp_queue_type_t type, odp_queue_param_t *param) -{ - strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1); - queue->s.type = type; - - if (param) { - memcpy(&queue->s.param, param, sizeof(odp_queue_param_t)); - } else { - /* Defaults */ - memset(&queue->s.param, 0, sizeof(odp_queue_param_t)); - queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT; - queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT; - queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT; - } - - switch (type) { - case ODP_QUEUE_TYPE_PKTIN: - queue->s.enqueue = pktin_enqueue; - queue->s.dequeue = pktin_dequeue; - queue->s.enqueue_multi = pktin_enq_multi; - queue->s.dequeue_multi = pktin_deq_multi; - break; - case ODP_QUEUE_TYPE_PKTOUT: - queue->s.enqueue = pktout_enqueue; - queue->s.dequeue = pktout_dequeue; - queue->s.enqueue_multi = pktout_enq_multi; - queue->s.dequeue_multi = pktout_deq_multi; - break; - default: - queue->s.enqueue = queue_enq; - queue->s.dequeue = queue_deq; - queue->s.enqueue_multi = queue_enq_multi; - queue->s.dequeue_multi = queue_deq_multi; - break; - } - - queue->s.head = NULL; - queue->s.tail = NULL; - queue->s.sched_buf = ODP_BUFFER_INVALID; -} - - -int odp_queue_init_global(void) -{ - uint32_t i; - - ODP_DBG("Queue init ... "); - - queue_tbl = odp_shm_reserve("odp_queues", - sizeof(queue_table_t), - sizeof(queue_entry_t)); - - if (queue_tbl == NULL) - return -1; - - memset(queue_tbl, 0, sizeof(queue_table_t)); - - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { - /* init locks */ - queue_entry_t *queue = get_qentry(i); - LOCK_INIT(&queue->s.lock); - queue->s.handle = queue_from_id(i); - } - - ODP_DBG("done\n"); - ODP_DBG("Queue init global\n"); - ODP_DBG(" struct queue_entry_s size %zu\n", - sizeof(struct queue_entry_s)); - ODP_DBG(" queue_entry_t size %zu\n", - sizeof(queue_entry_t)); - ODP_DBG("\n"); - - return 0; -} - -odp_queue_type_t odp_queue_type(odp_queue_t handle) -{ - queue_entry_t *queue; - - queue = queue_to_qentry(handle); - - return queue->s.type; -} - -odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle) -{ - queue_entry_t *queue; - - queue = queue_to_qentry(handle); - - return queue->s.param.sched.sync; -} - -odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type, - odp_queue_param_t *param) -{ - uint32_t i; - queue_entry_t *queue; - odp_queue_t handle = ODP_QUEUE_INVALID; - - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { - queue = &queue_tbl->queue[i]; - - if (queue->s.status != QUEUE_STATUS_FREE) - continue; - - LOCK(&queue->s.lock); - if (queue->s.status == QUEUE_STATUS_FREE) { - queue_init(queue, name, type, param); - - if (type == ODP_QUEUE_TYPE_SCHED || - type == ODP_QUEUE_TYPE_PKTIN) - queue->s.status = QUEUE_STATUS_NOTSCHED; - else - queue->s.status = QUEUE_STATUS_READY; - - handle = queue->s.handle; - UNLOCK(&queue->s.lock); - break; - } - UNLOCK(&queue->s.lock); - } - - if (handle != ODP_QUEUE_INVALID && - (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) { - odp_buffer_t buf; - - buf = odp_schedule_buffer_alloc(handle); - if (buf == ODP_BUFFER_INVALID) { - ODP_ERR("queue_init: sched buf alloc failed\n"); - return ODP_QUEUE_INVALID; - } - - queue->s.sched_buf = buf; - odp_schedule_mask_set(handle, queue->s.param.sched.prio); - } - - return handle; -} - - -odp_buffer_t queue_sched_buf(odp_queue_t handle) -{ - queue_entry_t *queue; - queue = queue_to_qentry(handle); - - return queue->s.sched_buf; -} - - -int queue_sched_atomic(odp_queue_t handle) -{ - queue_entry_t *queue; - queue = queue_to_qentry(handle); - - return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC; -} - - -odp_queue_t odp_queue_lookup(const char *name) -{ - uint32_t i; - - for (i = 0; i < ODP_CONFIG_QUEUES; i++) { - queue_entry_t *queue = &queue_tbl->queue[i]; - - if (queue->s.status == QUEUE_STATUS_FREE) - continue; - - LOCK(&queue->s.lock); - if (strcmp(name, queue->s.name) == 0) { - /* found it */ - UNLOCK(&queue->s.lock); - return queue->s.handle; - } - UNLOCK(&queue->s.lock); - } - - return ODP_QUEUE_INVALID; -} - - -int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr) -{ - int sched = 0; - - LOCK(&queue->s.lock); - if (queue->s.head == NULL) { - /* Empty queue */ - queue->s.head = buf_hdr; - queue->s.tail = buf_hdr; - buf_hdr->pkt.next = NULL; - } else { - queue->s.tail->pkt.next = buf_hdr; - queue->s.tail = buf_hdr; - buf_hdr->pkt.next = NULL; - } - - if (queue->s.status == QUEUE_STATUS_NOTSCHED) { - queue->s.status = QUEUE_STATUS_SCHED; - sched = 1; /* retval: schedule queue */ - } - UNLOCK(&queue->s.lock); - - /* Add queue to scheduling */ - if (sched == 1) - odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); - - return 0; -} - - -int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) -{ - int sched = 0; - int i; - odp_buffer_hdr_t *tail; - - for (i = 0; i < num - 1; i++) - buf_hdr[i]->pkt.next = buf_hdr[i+1]; - - tail = buf_hdr[num-1]; - buf_hdr[num-1]->pkt.next = NULL; - - LOCK(&queue->s.lock); - /* Empty queue */ - if (queue->s.head == NULL) - queue->s.head = buf_hdr[0]; - else - queue->s.tail->pkt.next = buf_hdr[0]; - - queue->s.tail = tail; - - if (queue->s.status == QUEUE_STATUS_NOTSCHED) { - queue->s.status = QUEUE_STATUS_SCHED; - sched = 1; /* retval: schedule queue */ - } - UNLOCK(&queue->s.lock); - - /* Add queue to scheduling */ - if (sched == 1) - odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio); - - return 0; -} - - -int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) -{ - odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; - queue_entry_t *queue; - int i; - - if (num > QUEUE_MULTI_MAX) - num = QUEUE_MULTI_MAX; - - queue = queue_to_qentry(handle); - - for (i = 0; i < num; i++) - buf_hdr[i] = odp_buf_to_hdr(buf[i]); - - return queue->s.enqueue_multi(queue, buf_hdr, num); -} - - -int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf) -{ - odp_buffer_hdr_t *buf_hdr; - queue_entry_t *queue; - - queue = queue_to_qentry(handle); - buf_hdr = odp_buf_to_hdr(buf); - - return queue->s.enqueue(queue, buf_hdr); -} - - -odp_buffer_hdr_t *queue_deq(queue_entry_t *queue) -{ - odp_buffer_hdr_t *buf_hdr = NULL; - - LOCK(&queue->s.lock); - - if (queue->s.head == NULL) { - /* Already empty queue */ - if (queue->s.status == QUEUE_STATUS_SCHED && - queue->s.type != ODP_QUEUE_TYPE_PKTIN) - queue->s.status = QUEUE_STATUS_NOTSCHED; - } else { - buf_hdr = queue->s.head; - queue->s.head = buf_hdr->pkt.next; - buf_hdr->pkt.next = NULL; - - if (queue->s.head == NULL) { - /* Queue is now empty */ - queue->s.tail = NULL; - } - } - - UNLOCK(&queue->s.lock); - - return buf_hdr; -} - - -int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) -{ - int i = 0; - - LOCK(&queue->s.lock); - - if (queue->s.head == NULL) { - /* Already empty queue */ - if (queue->s.status == QUEUE_STATUS_SCHED && - queue->s.type != ODP_QUEUE_TYPE_PKTIN) - queue->s.status = QUEUE_STATUS_NOTSCHED; - } else { - odp_buffer_hdr_t *hdr = queue->s.head; - - for (; i < num && hdr; i++) { - buf_hdr[i] = hdr; - /* odp_prefetch(hdr->addr); */ - hdr = hdr->pkt.next; - buf_hdr[i]->pkt.next = NULL; - } - - queue->s.head = hdr; - - if (hdr == NULL) { - /* Queue is now empty */ - queue->s.tail = NULL; - } - } - - UNLOCK(&queue->s.lock); - - return i; -} - - -int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num) -{ - queue_entry_t *queue; - odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX]; - int i, ret; - - if (num > QUEUE_MULTI_MAX) - num = QUEUE_MULTI_MAX; - - queue = queue_to_qentry(handle); - - ret = queue->s.dequeue_multi(queue, buf_hdr, num); - - for (i = 0; i < ret; i++) - buf[i] = (odp_buffer_t) buf_hdr[i]; - - return ret; -} - - -odp_buffer_t odp_queue_deq(odp_queue_t handle) -{ - queue_entry_t *queue; - odp_buffer_hdr_t *buf_hdr; - - queue = queue_to_qentry(handle); - buf_hdr = queue->s.dequeue(queue); - - if (buf_hdr) - return (odp_buffer_t) buf_hdr; - - return ODP_BUFFER_INVALID; -} - - -void queue_lock(queue_entry_t *queue) -{ - LOCK(&queue->s.lock); -} - - -void queue_unlock(queue_entry_t *queue) -{ - UNLOCK(&queue->s.lock); -}