Message ID | 20140717204204.GA28802@8470w |
---|---|
State | New |
Headers | show |
On 18 July 2014 02:12, Anders Roxell <anders.roxell@linaro.org> wrote: > On 2014-07-18 00:33, venkatesh.vivekanandan@linaro.org wrote: > > From: Vincent Hsu <vincent.hsu@linaro.org> > > > > Signed-off-by: Vincent Hsu <vincent.hsu@linaro.org> > > > > Make it clear what you did and what Vincent did. > Modify the commit message and will try to add what vincent did. > > > - Add/modify files to support linux-dpdk compilation in new automake > > environment. > > * Modified configure.ac > > * Added platform/linux-dpdk/Makefile.am > > * Moved all files from platform/linux-dpdk/source to > > platform/linux-dpdk/. > > > > - 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. > > > > Vincents s-o-b should be here. > Will leave the vincent's signoff above, as this will differentiate what I did and what he did. > > > Signed-off-by: Venkatesh Vivekanandan <venkatesh.vivekanandan@linaro.org > > > > --- > > configure.ac | 2 + > > platform/linux-dpdk/Makefile.am | 100 +++++ > > platform/linux-dpdk/README | 76 ++++ > > platform/linux-dpdk/include/api/odp_buffer.h | 94 +++++ > > platform/linux-dpdk/include/api/odp_buffer_pool.h | 99 +++++ > > platform/linux-dpdk/include/api/odp_packet.h | 228 +++++++++++ > > platform/linux-dpdk/include/api/odp_pktio_types.h | 45 +++ > > platform/linux-dpdk/include/odp_buffer_internal.h | 72 ++++ > > .../linux-dpdk/include/odp_buffer_pool_internal.h | 90 +++++ > > platform/linux-dpdk/include/odp_packet_dpdk.h | 87 +++++ > > platform/linux-dpdk/include/odp_packet_internal.h | 139 +++++++ > > .../linux-dpdk/include/odp_packet_io_internal.h | 51 +++ > > 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 | 419 > ++++++++++++++++++++ > > platform/linux-dpdk/odp_queue.c | 435 > +++++++++++++++++++++ > > 20 files changed, 2955 insertions(+) > > create mode 100644 platform/linux-dpdk/Makefile.am > > create mode 100644 platform/linux-dpdk/README > > create mode 100644 platform/linux-dpdk/include/api/odp_buffer.h > > create mode 100644 platform/linux-dpdk/include/api/odp_buffer_pool.h > > create mode 100644 platform/linux-dpdk/include/api/odp_packet.h > > create mode 100644 platform/linux-dpdk/include/api/odp_pktio_types.h > > create mode 100644 platform/linux-dpdk/include/odp_buffer_internal.h > > create mode 100644 > platform/linux-dpdk/include/odp_buffer_pool_internal.h > > create mode 100644 platform/linux-dpdk/include/odp_packet_dpdk.h > > create mode 100644 platform/linux-dpdk/include/odp_packet_internal.h > > create mode 100644 platform/linux-dpdk/include/odp_packet_io_internal.h > > 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 > > > > 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.am > b/platform/linux-dpdk/Makefile.am > > new file mode 100644 > > index 0000000..8f5b94b > > --- /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/README b/platform/linux-dpdk/README > > new file mode 100644 > > index 0000000..3578512 > > --- /dev/null > > +++ b/platform/linux-dpdk/README > > @@ -0,0 +1,76 @@ > > +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. > > + > > Shouldn't we say anything about kernel versions that works and how you > can fix it if you have a kernel version you can't build dpdk? > > I had to patch dpdk with this to get my kernel to work. > My kernel is: > $ uname -a > Linux 8470w 3.13.0-30-generic #55-Ubuntu SMP Fri Jul 4 21:40:53 UTC > 2014 x86_64 x86_64 x86_64 GNU/Linux > > $ git df > diff --git a/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h > b/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h > index 19df483..78a794a 100644 > --- a/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h > +++ b/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h > @@ -3845,11 +3845,6 @@ static inline struct sk_buff > *__kc__vlan_hwaccel_put_tag(struct sk_buff *skb, > #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) ) > #ifdef NETIF_F_RXHASH > #define PKT_HASH_TYPE_L3 0 > -static inline void > -skb_set_hash(struct sk_buff *skb, __u32 hash, __always_unused int type) > -{ > - skb->rxhash = hash; > -} > #endif /* NETIF_F_RXHASH */ > #endif /* < 3.14.0 */ > > Will add this in README and send out version 6. > > > +# To Clone DPDK > > +$ git clone http://92.243.14.124/git/dpdk ./<dpdk-dir> > > +# Ensure that dpdk is present at the same directory level as odp, that > is, > > +# ./odp and ./dpdk > > +# we support only 1.6.0r2 of dpdk for now > > +$ git tag -l -- will list all the tags available > > +$ git checkout tags/v1.6.0r2 > > + > > +$ cd <dpdk-dir> > > + > > +# Only for the first time > > +$ make config T=x86_64-default-linuxapp-gcc > > +# above command will generate build directory as ./build by default in > > +# <dpdk-dir> which can be overridden by specifying O=my_build_dir > option as > > +$ make config T=x86_64-default-linuxapp-gcc O=my_sdk_build_dir > > +# set CONFIG_RTE_BUILD_COMBINE_LIBS=y in <dpdk-build-dir>/.config > > + > > +Note: If non-intel SFP's are used in NIC, then go to > <dpdk-build-dir>/.config > > +and set CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=y > > + > > +$ cd <dpdk-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 > > + > > +$ cd <dpdk-dir> > > +$ sudo 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-dir> > > +$ ./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 LDFLAGS=-L<dpdk-build-dir>/lib > CFLAGS="-include <dpdk-build-dir>/include/rte_config.h > -I<dpdk-build-dir>/include -I<dpdk-build-dir>/include/arch > -I<dpdk-build-dir>/include/exec-env" > > Why do we need to add "-include <dpdk-build-dir>/include/rte_config.h > here? > right after we have -I<dpdk-build-dir>/include > All the configuration related defines are present in rte_config.h and this file is not included as an #include in any of the files intentionally, as this must come ahead of all other include files. > > > +# For example > > +$ ./configure --with-platform=linux-dpdk LDFLAGS=-L/root/dpdk/build/lib > CFLAGS="-include /root/dpdk/build/include/rte_config.h > -I/root/dpdk/build/include -I/root/dpdk/build/include/arch > -I/root/dpdk/build/include/exec-env" > > +$ make clean > > +$ make > > + > > +# Commands to test > > +l2fwding app - ./test/l2fwd/odp_l2fwd -i 0,1 -m 0 -c 2 > > +loopback app - ./test/packet/odp_pktio -i 0,1 -m 0 -c 2 > > + > > + -i 0,1 - interface number > > + -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 > > new file mode 100644 > > index 0000000..9ea1ed8 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/api/odp_buffer.h > > @@ -0,0 +1,94 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > + > > +/** > > + * @file > > + * > > + * ODP buffer descriptor > > + */ > > + > > +#ifndef ODP_BUFFER_H_ > > +#define ODP_BUFFER_H_ > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > + > > + > > +#include <odp_std_types.h> > > + > > + > > + > > + > > + > > +/** > > + * ODP buffer > > + */ > > +typedef unsigned long odp_buffer_t; > > + > > + > > +#define ODP_BUFFER_INVALID (0xffffffff) /**< Invalid buffer */ > > + > > + > > +/** > > + * Buffer start address > > + * > > + * @param buf Buffer handle > > + * > > + * @return Buffer start address > > + */ > > +void *odp_buffer_addr(odp_buffer_t buf); > > + > > +/** > > + * Buffer maximum data size > > + * > > + * @param buf Buffer handle > > + * > > + * @return Buffer maximum data size > > + */ > > +size_t odp_buffer_size(odp_buffer_t buf); > > + > > +/** > > + * Buffer type > > + * > > + * @param buf Buffer handle > > + * > > + * @return Buffer type > > + */ > > +int odp_buffer_type(odp_buffer_t buf); > > + > > +#define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */ > > +#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 > > + * > > + * @param buf Buffer handle > > + * > > + * @return 1 if valid, otherwise 0 > > + */ > > +int odp_buffer_is_valid(odp_buffer_t buf); > > + > > +/** > > + * Print buffer metadata to STDOUT > > + * > > + * @param buf Buffer handle > > + * > > + */ > > +void odp_buffer_print(odp_buffer_t buf); > > + > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > diff --git a/platform/linux-dpdk/include/api/odp_buffer_pool.h > b/platform/linux-dpdk/include/api/odp_buffer_pool.h > > new file mode 100644 > > index 0000000..4b75cf5 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/api/odp_buffer_pool.h > > @@ -0,0 +1,99 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > + > > +/** > > + * @file > > + * > > + * ODP buffer pool > > + */ > > + > > +#ifndef ODP_BUFFER_POOL_H_ > > +#define ODP_BUFFER_POOL_H_ > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > + > > + > > +#include <odp_std_types.h> > > +#include <odp_buffer.h> > > + > > +/** Maximum queue name lenght in chars */ > > +#define ODP_BUFFER_POOL_NAME_LEN 32 > > + > > +/** Invalid buffer pool */ > > +#define ODP_BUFFER_POOL_INVALID (0xffffffff) > > + > > +/** ODP buffer pool */ > > +typedef unsigned long odp_buffer_pool_t; > > + > > + > > +/** > > + * Create a buffer pool > > + * > > + * @param name Name of the pool (max ODP_BUFFER_POOL_NAME_LEN - 1 > chars) > > + * @param base_addr Pool base address > > + * @param size Pool size in bytes > > + * @param buf_size Buffer size in bytes > > + * @param buf_align Minimum buffer alignment > > + * @param buf_type Buffer type > > + * > > + * @return Buffer pool handle > > + */ > > +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); > > + > > + > > +/** > > + * Find a buffer pool by name > > + * > > + * @param name Name of the pool > > + * > > + * @return Buffer pool handle, or ODP_BUFFER_POOL_INVALID if not found. > > + */ > > +odp_buffer_pool_t odp_buffer_pool_lookup(const char *name); > > + > > + > > +/** > > + * Print buffer pool info > > + * > > + * @param pool Pool handle > > + * > > + */ > > +void odp_buffer_pool_print(odp_buffer_pool_t pool); > > + > > + > > + > > +/** > > + * Buffer alloc > > + * > > + * @param pool Pool handle > > + * > > + * @return Buffer handle or ODP_BUFFER_INVALID > > + */ > > +odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool); > > + > > + > > +/** > > + * Buffer free > > + * > > + * @param buf Buffer handle > > + * > > + */ > > +void odp_buffer_free(odp_buffer_t buf); > > + > > + > > + > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > diff --git a/platform/linux-dpdk/include/api/odp_packet.h > b/platform/linux-dpdk/include/api/odp_packet.h > > new file mode 100644 > > index 0000000..bdb3417 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/api/odp_packet.h > > @@ -0,0 +1,228 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > + > > +/** > > + * @file > > + * > > + * ODP packet descriptor > > + */ > > + > > +#ifndef ODP_PACKET_H_ > > +#define ODP_PACKET_H_ > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#include <odp_buffer.h> > > + > > + > > +/** > > + * ODP packet descriptor > > + */ > > +typedef unsigned long odp_packet_t; > > + > > + > > +/** Invalid packet */ > > +#define ODP_PACKET_INVALID ODP_BUFFER_INVALID > > + > > +/** Invalid offset */ > > +#define ODP_PACKET_OFFSET_INVALID ((size_t)-1) > > + > > + > > +/** > > + * Initialize the packet > > + * > > + * Needs to be called if the user allocates a packet buffer, i.e. the > packet > > + * has not been received from I/O through ODP. > > + * > > + * @param pkt Packet handle > > + */ > > +void odp_packet_init(odp_packet_t pkt); > > + > > +/** > > + * Convert from packet handle to buffer handle > > + * > > + * @param buf Buffer handle > > + * > > + * @return Packet handle > > + */ > > +odp_packet_t odp_packet_from_buffer(odp_buffer_t buf); > > + > > +/** > > + * Convert from buffer handle to packet handle > > + * > > + * @param pkt Packet handle > > + * > > + * @return Buffer handle > > + */ > > +odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt); > > + > > +/** > > + * Set the packet length > > + * > > + * @param pkt Packet handle > > + * @param len Length of packet in bytes > > + */ > > +void odp_packet_set_len(odp_packet_t pkt, size_t len); > > + > > +/** > > + * Get the packet length > > + * > > + * @param pkt Packet handle > > + * > > + * @return Packet length in bytes > > + */ > > +size_t odp_packet_get_len(odp_packet_t pkt); > > + > > +/** > > + * Get address to the start of the packet buffer > > + * > > + * The address of the packet buffer is not necessarily the same as the > start > > + * address of the received frame, e.g. an eth frame may be offset by 2 > or 6 > > + * bytes to ensure 32 or 64-bit alignment of the IP header. > > + * Use odp_packet_l2(pkt) to get the start address of a received valid > frame > > + * or odp_packet_start(pkt) to get the start address even if no valid > L2 header > > + * could be found. > > + * > > + * @param pkt Packet handle > > + * > > + * @return Pointer to the start of the packet buffer > > + * > > + * @see odp_packet_l2(), odp_packet_start() > > + */ > > +uint8_t *odp_packet_buf_addr(odp_packet_t pkt); > > + > > +/** > > + * Get pointer to the start of the received frame > > + * > > + * The address of the packet buffer is not necessarily the same as the > start > > + * address of the received frame, e.g. an eth frame may be offset by 2 > or 6 > > + * bytes to ensure 32 or 64-bit alignment of the IP header. > > + * Use odp_packet_l2(pkt) to get the start address of a received valid > eth frame > > + * > > + * odp_packet_start() will always return a pointer to the start of the > frame, > > + * even if the frame is unrecognized and no valid L2 header could be > found. > > + * > > + * @param pkt Packet handle > > + * > > + * @return Pointer to the start of the received frame > > + * > > + * @see odp_packet_l2(), odp_packet_buf_addr() > > + */ > > +uint8_t *odp_packet_start(odp_packet_t pkt); > > + > > +/** > > + * Get pointer to the start of the L2 frame > > + * > > + * The L2 frame header address is not necessarily the same as the > address of the > > + * packet buffer, see odp_packet_buf_addr() > > + * > > + * @param pkt Packet handle > > + * > > + * @return Pointer to L2 header or NULL if not found > > + * > > + * @see odp_packet_buf_addr(), odp_packet_start() > > + */ > > +uint8_t *odp_packet_l2(odp_packet_t pkt); > > + > > +/** > > + * Return the byte offset from the packet buffer to the L2 frame > > + * > > + * @param pkt Packet handle > > + * > > + * @return L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found > > + */ > > +size_t odp_packet_l2_offset(odp_packet_t pkt); > > + > > +/** > > + * Set the byte offset to the L2 frame > > + * > > + * @param pkt Packet handle > > + * @param offset L2 byte offset > > + */ > > +void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset); > > + > > + > > +/** > > + * Get pointer to the start of the L3 packet > > + * > > + * @param pkt Packet handle > > + * > > + * @return Pointer to L3 packet or NULL if not found > > + * > > + */ > > +uint8_t *odp_packet_l3(odp_packet_t pkt); > > + > > +/** > > + * Return the byte offset from the packet buffer to the L3 packet > > + * > > + * @param pkt Packet handle > > + * > > + * @return L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found > > + */ > > +size_t odp_packet_l3_offset(odp_packet_t pkt); > > + > > +/** > > + * Set the byte offset to the L3 packet > > + * > > + * @param pkt Packet handle > > + * @param offset L3 byte offset > > + */ > > +void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset); > > + > > + > > +/** > > + * Get pointer to the start of the L4 packet > > + * > > + * @param pkt Packet handle > > + * > > + * @return Pointer to L4 packet or NULL if not found > > + * > > + */ > > +uint8_t *odp_packet_l4(odp_packet_t pkt); > > + > > +/** > > + * Return the byte offset from the packet buffer to the L4 packet > > + * > > + * @param pkt Packet handle > > + * > > + * @return L4 byte offset or ODP_PACKET_OFFSET_INVALID if not found > > + */ > > +size_t odp_packet_l4_offset(odp_packet_t pkt); > > + > > +/** > > + * Set the byte offset to the L4 packet > > + * > > + * @param pkt Packet handle > > + * @param offset L4 byte offset > > + */ > > +void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset); > > + > > +/** > > + * Print (debug) information about the packet > > + * > > + * @param pkt Packet handle > > + */ > > +void odp_packet_print(odp_packet_t pkt); > > + > > +/** > > + * Copy contents and metadata from pkt_src to pkt_dst > > + * Useful when creating copies of packets > > + * > > + * @param pkt_dst Destination packet > > + * @param pkt_src Source packet > > + * > > + * @return 0 if successful > > + */ > > +int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src); > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > diff --git a/platform/linux-dpdk/include/api/odp_pktio_types.h > b/platform/linux-dpdk/include/api/odp_pktio_types.h > > new file mode 100644 > > index 0000000..b23e6da > > --- /dev/null > > +++ b/platform/linux-dpdk/include/api/odp_pktio_types.h > > @@ -0,0 +1,45 @@ > > + > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#ifndef ODP_PKTIO_TYPES_H > > +#define ODP_PKTIO_TYPES_H > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +/* We should ensure that future enum values will never overlap, > otherwise > > + * applications that want netmap suport might get in trouble if the odp > lib > > + * was not built with netmap support and there are more types define > below > > + */ > > + > > +typedef enum { > > + ODP_PKTIO_TYPE_SOCKET_BASIC = 0x1, > > + ODP_PKTIO_TYPE_SOCKET_MMSG, > > + ODP_PKTIO_TYPE_SOCKET_MMAP, > > + ODP_PKTIO_TYPE_NETMAP, > > + ODP_PKTIO_TYPE_DPDK, > > +} odp_pktio_type_t; > > + > > +#include <odp_pktio_socket.h> > > +#ifdef ODP_HAVE_NETMAP > > +#include <odp_pktio_netmap.h> > > +#endif > > + > > +typedef union odp_pktio_params_t { > > + odp_pktio_type_t type; > > + socket_params_t sock_params; > > +#ifdef ODP_HAVE_NETMAP > > + netmap_params_t nm_params; > > +#endif > > +} odp_pktio_params_t; > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > diff --git a/platform/linux-dpdk/include/odp_buffer_internal.h > b/platform/linux-dpdk/include/odp_buffer_internal.h > > new file mode 100644 > > index 0000000..f87ec80 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/odp_buffer_internal.h > > @@ -0,0 +1,72 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > + > > +/** > > + * @file > > + * > > + * ODP buffer descriptor - implementation internal > > + */ > > + > > +#ifndef ODP_BUFFER_INTERNAL_H_ > > +#define ODP_BUFFER_INTERNAL_H_ > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#include <odp_std_types.h> > > +#include <odp_atomic.h> > > +#include <odp_buffer_pool.h> > > +#include <odp_buffer.h> > > +#include <odp_debug.h> > > +#include <odp_align.h> > > +#include <rte_mbuf.h> > > + > > +/* TODO: move these to correct files */ > > + > > +typedef uint64_t odp_phys_addr_t; > > + > > +#define ODP_BUFFER_MAX_INDEX (ODP_BUFFER_MAX_BUFFERS - 2) > > +#define ODP_BUFFER_INVALID_INDEX (ODP_BUFFER_MAX_BUFFERS - 1) > > + > > +#define ODP_BUFS_PER_CHUNK 16 > > +#define ODP_BUFS_PER_SCATTER 4 > > + > > +#define ODP_BUFFER_TYPE_CHUNK 0xffff > > + > > + > > +#define ODP_BUFFER_POOL_BITS 4 > > +#define ODP_BUFFER_INDEX_BITS (32 - ODP_BUFFER_POOL_BITS) > > +#define ODP_BUFFER_MAX_POOLS (1 << ODP_BUFFER_POOL_BITS) > > +#define ODP_BUFFER_MAX_BUFFERS (1 << ODP_BUFFER_INDEX_BITS) > > + > > +typedef union odp_buffer_bits_t { > > + uint32_t u32; > > + odp_buffer_t handle; > > + > > + struct { > > + uint32_t pool:ODP_BUFFER_POOL_BITS; > > + uint32_t index:ODP_BUFFER_INDEX_BITS; > > + }; > > +} odp_buffer_bits_t; > > + > > + > > +/* forward declaration */ > > +struct odp_buffer_hdr_t; > > + > > + > > +typedef struct rte_mbuf odp_buffer_hdr_t; > > + > > + > > +int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf); > > + > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > diff --git a/platform/linux-dpdk/include/odp_buffer_pool_internal.h > b/platform/linux-dpdk/include/odp_buffer_pool_internal.h > > new file mode 100644 > > index 0000000..1a36655 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/odp_buffer_pool_internal.h > > @@ -0,0 +1,90 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > + > > +/** > > + * @file > > + * > > + * ODP buffer pool - internal header > > + */ > > + > > +#ifndef ODP_BUFFER_POOL_INTERNAL_H_ > > +#define ODP_BUFFER_POOL_INTERNAL_H_ > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#include <odp_std_types.h> > > +#include <odp_buffer_pool.h> > > +#include <odp_buffer_internal.h> > > +#include <odp_align.h> > > +#include <odp_hints.h> > > +#include <odp_config.h> > > +#include <odp_debug.h> > > + > > +/* for DPDK */ > > +#include <rte_mempool.h> > > + > > +/* Use ticketlock instead of spinlock */ > > +#define POOL_USE_TICKETLOCK > > + > > +/* Extra error checks */ > > +/* #define POOL_ERROR_CHECK */ > > + > > + > > +#ifdef POOL_USE_TICKETLOCK > > +#include <odp_ticketlock.h> > > +#else > > +#include <odp_spinlock.h> > > +#endif > > + > > + > > +struct pool_entry_s { > > +#ifdef POOL_USE_TICKETLOCK > > + odp_ticketlock_t lock ODP_ALIGNED_CACHE; > > +#else > > + odp_spinlock_t lock ODP_ALIGNED_CACHE; > > +#endif > > + > > + uint64_t free_bufs; > > + char name[ODP_BUFFER_POOL_NAME_LEN]; > > + > > + > > + odp_buffer_pool_t pool ODP_ALIGNED_CACHE; > > + uintptr_t buf_base; > > + size_t buf_size; > > + size_t buf_offset; > > + uint64_t num_bufs; > > + void *pool_base_addr; > > + uint64_t pool_size; > > + size_t payload_size; > > + size_t payload_align; > > + int buf_type; > > + size_t hdr_size; > > +}; > > + > > + > > +extern void *pool_entry_ptr[]; > > + > > + > > +static inline void *get_pool_entry(odp_buffer_pool_t pool_id) > > +{ > > + return pool_entry_ptr[pool_id]; > > +} > > + > > + > > +static inline odp_buffer_hdr_t *odp_buf_to_hdr(odp_buffer_t buf) > > +{ > > + return (odp_buffer_hdr_t *)buf; > > +} > > + > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > diff --git a/platform/linux-dpdk/include/odp_packet_dpdk.h > b/platform/linux-dpdk/include/odp_packet_dpdk.h > > new file mode 100644 > > index 0000000..bcbe9e8 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/odp_packet_dpdk.h > > @@ -0,0 +1,87 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > +#ifndef ODP_PACKET_DPDK_H > > +#define ODP_PACKET_DPDK_H > > + > > +#include <stdint.h> > > +#include <net/if.h> > > + > > +#include <helper/odp_eth.h> > > +#include <helper/odp_packet_helper.h> > > +#include <odp_align.h> > > +#include <odp_debug.h> > > +#include <odp_packet.h> > > +#include <odp_packet_internal.h> > > +#include <odp_buffer_pool.h> > > +#include <odp_buffer_pool_internal.h> > > +#include <odp_buffer_internal.h> > > +#include <odp_std_types.h> > > + > > +#include <rte_config.h> > > +#include <rte_memory.h> > > +#include <rte_memzone.h> > > +#include <rte_launch.h> > > +#include <rte_tailq.h> > > +#include <rte_eal.h> > > +#include <rte_per_lcore.h> > > +#include <rte_lcore.h> > > +#include <rte_branch_prediction.h> > > +#include <rte_prefetch.h> > > +#include <rte_cycles.h> > > +#include <rte_errno.h> > > +#include <rte_debug.h> > > +#include <rte_log.h> > > +#include <rte_byteorder.h> > > +#include <rte_pci.h> > > +#include <rte_random.h> > > +#include <rte_ether.h> > > +#include <rte_ethdev.h> > > +#include <rte_hash.h> > > +#include <rte_jhash.h> > > +#include <rte_hash_crc.h> > > + > > + > > +#define ODP_DPDK_MODE_HW 0 > > +#define ODP_DPDK_MODE_SW 1 > > + > > +#define DPDK_BLOCKING_IO > > + > > +/** Packet socket using dpdk mmaped rings for both Rx and Tx */ > > +typedef struct { > > + odp_buffer_pool_t pool; > > + > > + /********************************/ > > + char ifname[32]; > > + uint8_t portid; > > + uint16_t queueid; > > +} pkt_dpdk_t; > > + > > +/** > > + * Configure an interface to work in dpdk mode > > + */ > > +int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, > > + odp_buffer_pool_t pool); > > + > > +/** > > + * Switch interface from dpdk mode to normal mode > > + */ > > +int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk); > > + > > +/** > > + * Receive packets using dpdk > > + */ > > +int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > > + unsigned len); > > + > > +/** > > + * Send packets using dpdk > > + */ > > +int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[], > > + unsigned len); > > + > > +int odp_init_dpdk(void); > > +#endif > > diff --git a/platform/linux-dpdk/include/odp_packet_internal.h > b/platform/linux-dpdk/include/odp_packet_internal.h > > new file mode 100644 > > index 0000000..0f798c1 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/odp_packet_internal.h > > @@ -0,0 +1,139 @@ > > +/* Copyright (c) 2014, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > + > > +/** > > + * @file > > + * > > + * ODP packet descriptor - implementation internal > > + */ > > + > > +#ifndef ODP_PACKET_INTERNAL_H_ > > +#define ODP_PACKET_INTERNAL_H_ > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#include <odp_align.h> > > +#include <odp_debug.h> > > +#include <odp_buffer_internal.h> > > +#include <odp_buffer_pool_internal.h> > > +#include <odp_packet.h> > > +#include <odp_packet_io.h> > > + > > +/** > > + * Packet input & protocol flags > > + */ > > +typedef union { > > + /* All input flags */ > > + uint32_t all; > > + > > + struct { > > + /* Bitfield flags for each protocol */ > > + uint32_t l2:1; /**< known L2 protocol present */ > > + uint32_t l3:1; /**< known L3 protocol present */ > > + uint32_t l4:1; /**< known L4 protocol present */ > > + > > + uint32_t eth:1; /**< Ethernet */ > > + uint32_t jumbo:1; /**< Jumbo frame */ > > + uint32_t vlan:1; /**< VLAN hdr found */ > > + uint32_t vlan_qinq:1; /**< Stacked VLAN found, QinQ */ > > + > > + uint32_t arp:1; /**< ARP */ > > + > > + uint32_t ipv4:1; /**< IPv4 */ > > + uint32_t ipv6:1; /**< IPv6 */ > > + uint32_t ipfrag:1; /**< IP fragment */ > > + uint32_t ipopt:1; /**< IP optional headers */ > > + uint32_t ipsec:1; /**< IPSec decryption may be needed > */ > > + > > + uint32_t udp:1; /**< UDP */ > > + uint32_t tcp:1; /**< TCP */ > > + uint32_t sctp:1; /**< SCTP */ > > + uint32_t icmp:1; /**< ICMP */ > > + }; > > +} input_flags_t; > > + > > +ODP_ASSERT(sizeof(input_flags_t) == sizeof(uint32_t), > INPUT_FLAGS_SIZE_ERROR); > > + > > +/** > > + * Packet error flags > > + */ > > +typedef union { > > + /* All error flags */ > > + uint32_t all; > > + > > + struct { > > + /* Bitfield flags for each detected error */ > > + uint32_t frame_len:1; /**< Frame length error */ > > + uint32_t l2_chksum:1; /**< L2 checksum error, checks TBD */ > > + uint32_t ip_err:1; /**< IP error, checks TBD */ > > + uint32_t tcp_err:1; /**< TCP error, checks TBD */ > > + uint32_t udp_err:1; /**< UDP error, checks TBD */ > > + }; > > +} error_flags_t; > > + > > +ODP_ASSERT(sizeof(error_flags_t) == sizeof(uint32_t), > ERROR_FLAGS_SIZE_ERROR); > > + > > +/** > > + * Packet output flags > > + */ > > +typedef union { > > + /* All output flags */ > > + uint32_t all; > > + > > + struct { > > + /* Bitfield flags for each output option */ > > + uint32_t l4_chksum:1; /**< Request L4 checksum calculation > */ > > + }; > > +} output_flags_t; > > + > > +ODP_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), > OUTPUT_FLAGS_SIZE_ERROR); > > + > > +/** > > + * Internal Packet header > > + */ > > +typedef struct { > > + /* common buffer header */ > > + odp_buffer_hdr_t buf_hdr; > > + > > + input_flags_t input_flags; > > + error_flags_t error_flags; > > + output_flags_t output_flags; > > + > > + uint32_t frame_offset; /**< offset to start of frame, even on > error */ > > + uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */ > > + uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */ > > + uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also > ICMP) */ > > + > > + uint32_t frame_len; > > + > > + odp_pktio_t input; > > + > > + uint32_t pad; > > + uint8_t payload[]; > > + > > +} odp_packet_hdr_t; > > + > > +/** > > + * Return the packet header > > + */ > > +static inline odp_packet_hdr_t *odp_packet_hdr(odp_packet_t pkt) > > +{ > > + return (odp_packet_hdr_t *)pkt; > > +} > > + > > +/** > > + * Parse packet and set internal metadata > > + */ > > +void odp_packet_parse(odp_packet_t pkt, size_t len, size_t l2_offset); > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > diff --git a/platform/linux-dpdk/include/odp_packet_io_internal.h > b/platform/linux-dpdk/include/odp_packet_io_internal.h > > new file mode 100644 > > index 0000000..08abea7 > > --- /dev/null > > +++ b/platform/linux-dpdk/include/odp_packet_io_internal.h > > @@ -0,0 +1,51 @@ > > +/* Copyright (c) 2013, Linaro Limited > > + * All rights reserved. > > + * > > + * SPDX-License-Identifier: BSD-3-Clause > > + */ > > + > > + > > +/** > > + * @file > > + * > > + * ODP packet IO - implementation internal > > + */ > > + > > +#ifndef ODP_PACKET_IO_INTERNAL_H_ > > +#define ODP_PACKET_IO_INTERNAL_H_ > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#include <odp_spinlock.h> > > +#include <odp_packet_socket.h> > > +#ifdef ODP_HAVE_NETMAP > > +#include <odp_packet_netmap.h> > > +#endif > > +#include <odp_packet_dpdk.h> > > + > > +struct pktio_entry { > > + odp_spinlock_t lock; /**< entry spinlock */ > > + int taken; /**< is entry taken(1) or free(0) > */ > > + odp_queue_t inq_default; /**< default input queue, if set */ > > + odp_queue_t outq_default; /**< default out queue */ > > + odp_pktio_params_t params; /**< pktio parameters */ > > + pkt_sock_t pkt_sock; /**< using socket API for IO */ > > + pkt_sock_mmap_t pkt_sock_mmap; /**< using socket mmap API for IO > */ > > +#ifdef ODP_HAVE_NETMAP > > + pkt_netmap_t pkt_nm; /**< using netmap API for IO */ > > +#endif > > + pkt_dpdk_t pkt_dpdk; /**< using DPDK API for IO */ > > +}; > > + > > +typedef union { > > + struct pktio_entry s; > > + uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct > pktio_entry))]; > > +} pktio_entry_t; > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif > > 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..d8d127f > > --- /dev/null > > +++ b/platform/linux-dpdk/odp_packet_io.c > > @@ -0,0 +1,419 @@ > > +/* 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; > > + memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk)); > > + /* 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; > > + } > > + > > + ODP_DBG("Allocating dpdk pktio\n"); > > + > > + 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); > > + > > + 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; > > + } > > + > > + 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)) { > > + res = close_pkt_dpdk(&entry->s.pkt_dpdk); > > + 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); > > + pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, len); > > + 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); > > + pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk, > > + pkt_table, len); > > + 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); > > +} > > -- > > 1.8.1.2 > > > > > > _______________________________________________ > > lng-odp mailing list > > lng-odp@lists.linaro.org > > http://lists.linaro.org/mailman/listinfo/lng-odp > > -- > Anders Roxell > anders.roxell@linaro.org > M: +46 709 71 42 85 | IRC: roxell >
diff --git a/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h b/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h index 19df483..78a794a 100644 --- a/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h +++ b/lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h @@ -3845,11 +3845,6 @@ static inline struct sk_buff *__kc__vlan_hwaccel_put_tag(struct sk_buff *skb, #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) ) #ifdef NETIF_F_RXHASH #define PKT_HASH_TYPE_L3 0 -static inline void -skb_set_hash(struct sk_buff *skb, __u32 hash, __always_unused int type) -{ - skb->rxhash = hash; -} #endif /* NETIF_F_RXHASH */ #endif /* < 3.14.0 */