Message ID | 1405430419-23001-1-git-send-email-venkatesh.vivekanandan@linaro.org |
---|---|
State | New |
Headers | show |
On 15 July 2014 09:20, <venkatesh.vivekanandan@linaro.org> wrote: > From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> > > - Added platform/linux-dpdk/README on how to clone, compile DPDK and > commands to execute on ODP. > - 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. > > 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 | 6 - > platform/linux-dpdk/README | 67 ++++ > platform/linux-dpdk/include/api/odp_buffer.h | 17 +- > platform/linux-dpdk/odp_buffer.c | 90 +++++ > 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 | 101 ----- > 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 --------------------- > 21 files changed, 2188 insertions(+), 2093 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/README > 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 27e4391..0000000 > --- a/platform/linux-dpdk/Makefile.inc > +++ /dev/null > @@ -1,6 +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/README b/platform/linux-dpdk/README > new file mode 100644 > index 0000000..098a0b4 > --- /dev/null > +++ b/platform/linux-dpdk/README > @@ -0,0 +1,67 @@ > +ODP-DPDK: > +--------- > + This effort is to port ODP on top of DPDK and use dpdk as the > +accelerator for all intel NIC's. Pre-requisite is DPDK should be cloned > and > +compiled. > + > +# To Clone DPDK > +$ git clone http://92.243.14.124/git/dpdk ./dpdk > +# Ensure that dpdk is present at the same directory level as odp, that > is, ./odp and ./dpdk > + > +set CONFIG_RTE_BUILD_COMBINE_LIBS=y in my_sdk_build_dir/.config > + > +Note: If you are using not-intel SFP's on NIC, then go to > my_sdk_build_dir/.config and set > CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=y > + > +$ cd ./dpdk > +# Only for the first time > +$ make config T=x86_64-default-linuxapp-gcc O=my_sdk_build_dir > I don't have "defconfig_x86_64-default-linuxapp-gcc" after cloning the dpdk repo, I do have: common_bsdapp defconfig_i686-native-linuxapp-icc defconfig_x86_64-native-bsdapp-gcc common_linuxapp defconfig_x86_64-ivshmem-linuxapp-gcc defconfig_x86_64-native-linuxapp-gcc defconfig_i686-native-linuxapp-gcc defconfig_x86_64-ivshmem-linuxapp-icc defconfig_x86_64-native-linuxapp-icc Did I make a mistake or has the list of configs changed ? > +$ cd my_sdk_build_dir/ > +$ make clean; make > + > +# To reserve huge pages which is needed for dpdk execute following command > +$ echo 1024 > > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages > +# If you are running on a multi-node machine then, hugepages should be > reserved on each node > +$ echo 1024 > > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages > + > +$ sudo mkdir /mnt/huge > +$ sudo mount -t hugetlbfs nodev /mnt/huge > +# To load uio driver > +$ sudo /sbin/modprobe uio > +$ ulimit -Sn 2048 > + > +# sudo insmod igb_uio.ko > +$ cd ./dpdk > +$ insmod ./build/build/lib/librte_eal/linuxapp/igb_uio/igb_uio.ko > + > +$ rmmod ixgbe > +$ modprobe ixgbe > +# If the SFP's used are non-intel, then > +$ modprobe ixgbe allow_unsupported_sfp=1 > + > +$ cd ./dpdk > +$ ./tools/igb_uio_bind.py --status > + > +Now you should look for pci id listed and give it in the following > command in > +place of 42:00.0 > + > +# To give the interfaces to dpdk, use following command > +$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.0 > +$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.1 > +# To restore it back to kernel, use following command > +$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.0 > +$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.1 > + > +# To compile ODP with linux-dpdk > +$ ./bootstrap > +$ ./configure --with-platform=linux-dpdk > +$ 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 - interface number > + -t 5 - dpdk type > + -m 0 - burst mode > + -c 2 - number of cpus > 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..e2f8942 > --- /dev/null > +++ b/platform/linux-dpdk/odp_buffer.c > @@ -0,0 +1,90 @@ > +/* 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 db683b8..0000000 > --- a/platform/linux-dpdk/source/odp_buffer.c > +++ /dev/null > @@ -1,101 +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 15 July 2014 19:26, Mike Holmes <mike.holmes@linaro.org> wrote: > > > > On 15 July 2014 09:20, <venkatesh.vivekanandan@linaro.org> wrote: > >> From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> >> >> - Added platform/linux-dpdk/README on how to clone, compile DPDK and >> commands to execute on ODP. >> - 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. >> >> 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 | 6 - >> platform/linux-dpdk/README | 67 ++++ >> platform/linux-dpdk/include/api/odp_buffer.h | 17 +- >> platform/linux-dpdk/odp_buffer.c | 90 +++++ >> 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 | 101 ----- >> 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 --------------------- >> 21 files changed, 2188 insertions(+), 2093 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/README >> 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 27e4391..0000000 >> --- a/platform/linux-dpdk/Makefile.inc >> +++ /dev/null >> @@ -1,6 +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/README b/platform/linux-dpdk/README >> new file mode 100644 >> index 0000000..098a0b4 >> --- /dev/null >> +++ b/platform/linux-dpdk/README >> @@ -0,0 +1,67 @@ >> +ODP-DPDK: >> +--------- >> + This effort is to port ODP on top of DPDK and use dpdk as the >> +accelerator for all intel NIC's. Pre-requisite is DPDK should be cloned >> and >> +compiled. >> + >> +# To Clone DPDK >> +$ git clone http://92.243.14.124/git/dpdk ./dpdk >> +# Ensure that dpdk is present at the same directory level as odp, that >> is, ./odp and ./dpdk >> + >> +set CONFIG_RTE_BUILD_COMBINE_LIBS=y in my_sdk_build_dir/.config >> + >> +Note: If you are using not-intel SFP's on NIC, then go to >> my_sdk_build_dir/.config and set >> CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=y >> + >> +$ cd ./dpdk >> +# Only for the first time >> +$ make config T=x86_64-default-linuxapp-gcc O=my_sdk_build_dir >> > > I don't have "defconfig_x86_64-default-linuxapp-gcc" after cloning the > dpdk repo, I do have: > > common_bsdapp defconfig_i686-native-linuxapp-icc > defconfig_x86_64-native-bsdapp-gcc > common_linuxapp defconfig_x86_64-ivshmem-linuxapp-gcc > defconfig_x86_64-native-linuxapp-gcc > defconfig_i686-native-linuxapp-gcc defconfig_x86_64-ivshmem-linuxapp-icc > defconfig_x86_64-native-linuxapp-icc > > Did I make a mistake or has the list of configs changed ? > oops!! sorry missed the tag. After checking out dpdk, $ git checkout tags/v1.6.0r2 > > > >> +$ cd my_sdk_build_dir/ >> +$ make clean; make >> + >> +# To reserve huge pages which is needed for dpdk execute following >> command >> +$ echo 1024 > >> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages >> +# If you are running on a multi-node machine then, hugepages should be >> reserved on each node >> +$ echo 1024 > >> /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages >> + >> +$ sudo mkdir /mnt/huge >> +$ sudo mount -t hugetlbfs nodev /mnt/huge >> +# To load uio driver >> +$ sudo /sbin/modprobe uio >> +$ ulimit -Sn 2048 >> + >> +# sudo insmod igb_uio.ko >> +$ cd ./dpdk >> +$ insmod ./build/build/lib/librte_eal/linuxapp/igb_uio/igb_uio.ko >> + >> +$ rmmod ixgbe >> +$ modprobe ixgbe >> +# If the SFP's used are non-intel, then >> +$ modprobe ixgbe allow_unsupported_sfp=1 >> + >> +$ cd ./dpdk >> +$ ./tools/igb_uio_bind.py --status >> + >> +Now you should look for pci id listed and give it in the following >> command in >> +place of 42:00.0 >> + >> +# To give the interfaces to dpdk, use following command >> +$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.0 >> +$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.1 >> +# To restore it back to kernel, use following command >> +$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.0 >> +$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.1 >> + >> +# To compile ODP with linux-dpdk >> +$ ./bootstrap >> +$ ./configure --with-platform=linux-dpdk >> +$ 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 - interface number >> + -t 5 - dpdk type >> + -m 0 - burst mode >> + -c 2 - number of cpus >> 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..e2f8942 >> --- /dev/null >> +++ b/platform/linux-dpdk/odp_buffer.c >> @@ -0,0 +1,90 @@ >> +/* 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 db683b8..0000000 >> --- a/platform/linux-dpdk/source/odp_buffer.c >> +++ /dev/null >> @@ -1,101 +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 >> > > > > -- > *Mike Holmes* > Linaro Technical Manager / Lead > LNG - ODP >
On 07/15/2014 04:20 PM, venkatesh.vivekanandan@linaro.org wrote: > From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> > > - Added platform/linux-dpdk/README on how to clone, compile DPDK and > commands to execute on ODP. > - 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. Please merge first two patches together and format subject line properly.
On 15 July 2014 21:41, Taras Kondratiuk <taras.kondratiuk@linaro.org> wrote: > On 07/15/2014 04:20 PM, venkatesh.vivekanandan@linaro.org wrote: > > From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> > > > > - Added platform/linux-dpdk/README on how to clone, compile DPDK and > > commands to execute on ODP. > > - 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. > > Please merge first two patches together and format subject line properly. > First patch was contributed by Vincent, that is the reason why it wasn't merged with second. I will format those subject line and send out patch v3.
On 07/16/2014 09:39 AM, Venkatesh Vivekanandan wrote: > > > > On 15 July 2014 21:41, Taras Kondratiuk <taras.kondratiuk@linaro.org > <mailto:taras.kondratiuk@linaro.org>> wrote: > > On 07/15/2014 04:20 PM, venkatesh.vivekanandan@linaro.org > <mailto:venkatesh.vivekanandan@linaro.org> wrote: > > From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org > <mailto:venkatesh.vivekanandan@linaro.org>> > > > > - Added platform/linux-dpdk/README on how to clone, compile DPDK and > > commands to execute on ODP. > > - 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. > > Please merge first two patches together and format subject line > properly. > > > First patch was contributed by Vincent, that is the reason why it wasn't > merged with second. I will format those subject line and send out patch v3. I understand, but this creates a lot of unnecessary noise in the history and makes patches hard to review. They should be merged. You have several options: 1. If merged patch have most of changes from Vincent, then leave his authorship and describe your contribution above signed-off tag: [venkatesh.vivekanandan@linaro.org: - Add/modify files to support linux-dpdk compilation in new automake environment. - Added platform/linux-dpdk/README on how to clone, compile DPDK and commands to execute on ODP. - 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.] Signed-off-by: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> 2. If you have modified most of Vincent's code, then put your authorship and mention that the patch is based on initial Vincent's series.
On 16 July 2014 13:47, Taras Kondratiuk <taras.kondratiuk@linaro.org> wrote: > On 07/16/2014 09:39 AM, Venkatesh Vivekanandan wrote: > > > > > > > > On 15 July 2014 21:41, Taras Kondratiuk <taras.kondratiuk@linaro.org > > <mailto:taras.kondratiuk@linaro.org>> wrote: > > > > On 07/15/2014 04:20 PM, venkatesh.vivekanandan@linaro.org > > <mailto:venkatesh.vivekanandan@linaro.org> wrote: > > > From: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org > > <mailto:venkatesh.vivekanandan@linaro.org>> > > > > > > - Added platform/linux-dpdk/README on how to clone, compile DPDK > and > > > commands to execute on ODP. > > > - 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. > > > > Please merge first two patches together and format subject line > > properly. > > > > > > First patch was contributed by Vincent, that is the reason why it wasn't > > merged with second. I will format those subject line and send out patch > v3. > > I understand, but this creates a lot of unnecessary noise in the history > and makes patches hard to review. They should be merged. > > You have several options: > 1. If merged patch have most of changes from Vincent, then leave his > authorship and describe your contribution above signed-off tag: > > [venkatesh.vivekanandan@linaro.org: > - Add/modify files to support linux-dpdk compilation in new automake > environment. > - Added platform/linux-dpdk/README on how to clone, compile DPDK and > commands to execute on ODP. > - 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.] > Signed-off-by: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org> > > 2. If you have modified most of Vincent's code, then put your authorship > and mention that the patch is based on initial Vincent's series. > Both patches are squashed and sent as v4.
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 27e4391..0000000 --- a/platform/linux-dpdk/Makefile.inc +++ /dev/null @@ -1,6 +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/README b/platform/linux-dpdk/README new file mode 100644 index 0000000..098a0b4 --- /dev/null +++ b/platform/linux-dpdk/README @@ -0,0 +1,67 @@ +ODP-DPDK: +--------- + This effort is to port ODP on top of DPDK and use dpdk as the +accelerator for all intel NIC's. Pre-requisite is DPDK should be cloned and +compiled. + +# To Clone DPDK +$ git clone http://92.243.14.124/git/dpdk ./dpdk +# Ensure that dpdk is present at the same directory level as odp, that is, ./odp and ./dpdk + +set CONFIG_RTE_BUILD_COMBINE_LIBS=y in my_sdk_build_dir/.config + +Note: If you are using not-intel SFP's on NIC, then go to my_sdk_build_dir/.config and set CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=y + +$ cd ./dpdk +# Only for the first time +$ make config T=x86_64-default-linuxapp-gcc O=my_sdk_build_dir +$ cd my_sdk_build_dir/ +$ make clean; make + +# To reserve huge pages which is needed for dpdk execute following command +$ echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages +# If you are running on a multi-node machine then, hugepages should be reserved on each node +$ echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages + +$ sudo mkdir /mnt/huge +$ sudo mount -t hugetlbfs nodev /mnt/huge +# To load uio driver +$ sudo /sbin/modprobe uio +$ ulimit -Sn 2048 + +# sudo insmod igb_uio.ko +$ cd ./dpdk +$ insmod ./build/build/lib/librte_eal/linuxapp/igb_uio/igb_uio.ko + +$ rmmod ixgbe +$ modprobe ixgbe +# If the SFP's used are non-intel, then +$ modprobe ixgbe allow_unsupported_sfp=1 + +$ cd ./dpdk +$ ./tools/igb_uio_bind.py --status + +Now you should look for pci id listed and give it in the following command in +place of 42:00.0 + +# To give the interfaces to dpdk, use following command +$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.0 +$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.1 +# To restore it back to kernel, use following command +$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.0 +$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.1 + +# To compile ODP with linux-dpdk +$ ./bootstrap +$ ./configure --with-platform=linux-dpdk +$ 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 - interface number + -t 5 - dpdk type + -m 0 - burst mode + -c 2 - number of cpus 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..e2f8942 --- /dev/null +++ b/platform/linux-dpdk/odp_buffer.c @@ -0,0 +1,90 @@ +/* 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 db683b8..0000000 --- a/platform/linux-dpdk/source/odp_buffer.c +++ /dev/null @@ -1,101 +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); -}