Discussion:
[dpdk-dev] [PATCH 0/2] Elastic Flow Distributor
(too old to reply)
Pablo de Lara
2016-12-02 14:52:18 UTC
Permalink
EFD is a distributor library that uses perfect hashing to determine a
target/value for a given incoming flow key. It has the following advantages:
first, because it uses perfect hashing it does not store the key itself and
hence lookup performance is not dependent on the key size. Second, the
target/value can be any arbitrary value hence the system designer and/or
operator can better optimize service rates and inter-cluster network traffic
locating. Third, since the storage requirement is much smaller than a
hash-based flow table (i.e. better fit for CPU cache), EFD can scale to millions
of flow keys. Finally, with current optimized library implementation performance
is fully scalable with number of CPU cores.

The basic idea of EFD is when a given key is to be inserted, a family of hash
functions is searched until the correct hash function that maps the input key to
the correct value is found. However, rather than explicitly storing all keys and
their associated values, EFD stores only indices of hash functions that map keys
to values, and thereby consumes much less space than conventional flow-based
tables. The lookup operation is very simple, similar to computational-based
scheme, given an input key the lookup operation is reduced to hashing that key
with the correct hash function.

Intuitively, finding a hash function that maps each of a large number (millions)
of input keys to the correct output value is effectively impossible, as a result
EFD, breaks the problem into smaller pieces (divide and conquer). EFD divides
the entire input key set into many small groups. Each group consists of
approximately 20-28 keys (a configurable parameter for the library), then, for
each small group, a brute force search to find a hash function that produces the
correct outputs for each key in the group.
It should be mentioned that since in the online lookup table for EFD doesn’t
store the key itself, the size of the EFD table is independent of the key size
and hence EFD lookup performance which is almost constant irrespective of the
length of the key which is a highly desirable feature especially for longer
keys.

Library code is included in the patch, plus an sample application that shows
how the library can be used.

RFC for this library was already sent:
http://dpdk.org/ml/archives/dev/2016-October/049238.html

For more information on the library, check out the following document:
https://github.com/pablodelara/perfect_hash_flow_distributor/blob/master/EFD_description.pdf


Pablo de Lara (2):
efd: new Elastic Flow Distributor library
examples/flow_distributor: sample app to demonstrate EFD usage

config/common_base | 5 +
examples/Makefile | 1 +
examples/flow_distributor/Makefile | 44 +
examples/flow_distributor/distributor/Makefile | 57 ++
examples/flow_distributor/distributor/args.c | 200 ++++
examples/flow_distributor/distributor/args.h | 39 +
examples/flow_distributor/distributor/init.c | 371 ++++++++
examples/flow_distributor/distributor/init.h | 76 ++
examples/flow_distributor/distributor/main.c | 362 +++++++
examples/flow_distributor/node/Makefile | 48 +
examples/flow_distributor/node/node.c | 417 ++++++++
examples/flow_distributor/shared/common.h | 99 ++
lib/Makefile | 1 +
lib/librte_eal/common/include/rte_log.h | 1 +
lib/librte_efd/Makefile | 56 ++
lib/librte_efd/rte_efd.c | 1203 ++++++++++++++++++++++++
lib/librte_efd/rte_efd.h | 312 ++++++
lib/librte_efd/rte_efd_version.map | 12 +
mk/rte.app.mk | 1 +
19 files changed, 3305 insertions(+)
create mode 100644 examples/flow_distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/args.c
create mode 100644 examples/flow_distributor/distributor/args.h
create mode 100644 examples/flow_distributor/distributor/init.c
create mode 100644 examples/flow_distributor/distributor/init.h
create mode 100644 examples/flow_distributor/distributor/main.c
create mode 100644 examples/flow_distributor/node/Makefile
create mode 100644 examples/flow_distributor/node/node.c
create mode 100644 examples/flow_distributor/shared/common.h
create mode 100644 lib/librte_efd/Makefile
create mode 100644 lib/librte_efd/rte_efd.c
create mode 100644 lib/librte_efd/rte_efd.h
create mode 100644 lib/librte_efd/rte_efd_version.map
--
2.7.4
Pablo de Lara
2016-12-02 14:52:19 UTC
Permalink
Elastic Flow Distributor (EFD) is a distributor library that uses
perfect hashing to determine a target/value for a given incoming flow key.
It has the following advantages:

- First, because it uses perfect hashing, it does not store the key itself and
hence lookup performance is not dependent on the key size.

- Second, the target/value can be any arbitrary value hence the system designer
and/or operator can better optimize service rates and inter-cluster
network traffic locating.

- Third, since the storage requirement is much smaller than a hash-based flow table
(i.e. better fit for CPU cache), EFD can scale to millions of flow keys.
Finally, with current optimized library implementation performance
is fully scalable with number of CPU cores.

Signed-off-by: Pablo de Lara <***@intel.com>
---
config/common_base | 5 +
lib/Makefile | 1 +
lib/librte_eal/common/include/rte_log.h | 1 +
lib/librte_efd/Makefile | 56 ++
lib/librte_efd/rte_efd.c | 1203 +++++++++++++++++++++++++++++++
lib/librte_efd/rte_efd.h | 312 ++++++++
lib/librte_efd/rte_efd_version.map | 12 +
mk/rte.app.mk | 1 +
8 files changed, 1591 insertions(+)
create mode 100644 lib/librte_efd/Makefile
create mode 100644 lib/librte_efd/rte_efd.c
create mode 100644 lib/librte_efd/rte_efd.h
create mode 100644 lib/librte_efd/rte_efd_version.map

diff --git a/config/common_base b/config/common_base
index 4bff83a..376742a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -458,6 +458,11 @@ CONFIG_RTE_LIBRTE_HASH=y
CONFIG_RTE_LIBRTE_HASH_DEBUG=n

#
+# Compile librte_efd
+#
+CONFIG_RTE_LIBRTE_EFD=y
+
+#
# Compile librte_jobstats
#
CONFIG_RTE_LIBRTE_JOBSTATS=y
diff --git a/lib/Makefile b/lib/Makefile
index 990f23a..9a41188 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -43,6 +43,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
+DIRS-$(CONFIG_RTE_LIBRTE_EFD) += librte_efd
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl
DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 29f7d19..70e150d 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -79,6 +79,7 @@ extern struct rte_logs rte_logs;
#define RTE_LOGTYPE_PIPELINE 0x00008000 /**< Log related to pipeline. */
#define RTE_LOGTYPE_MBUF 0x00010000 /**< Log related to mbuf. */
#define RTE_LOGTYPE_CRYPTODEV 0x00020000 /**< Log related to cryptodev. */
+#define RTE_LOGTYPE_EFD 0x00040000 /**< Log related to cryptodev. */

/* these log types can be used in an application */
#define RTE_LOGTYPE_USER1 0x01000000 /**< User-defined log type 1. */
diff --git a/lib/librte_efd/Makefile b/lib/librte_efd/Makefile
new file mode 100644
index 0000000..ae21bc7
--- /dev/null
+++ b/lib/librte_efd/Makefile
@@ -0,0 +1,56 @@
+# BSD LICENSE
+#
+# Copyright(c) 2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_efd.a
+
+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -D_GNU_SOURCE
+
+EXPORT_MAP := rte_efd_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_EFD) := rte_efd.c
+
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_EFD)-include := rte_efd.h
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_ether
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_efd/rte_efd.c b/lib/librte_efd/rte_efd.c
new file mode 100644
index 0000000..0b8b51e
--- /dev/null
+++ b/lib/librte_efd/rte_efd.c
@@ -0,0 +1,1203 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <immintrin.h>
+#include <math.h>
+#include <sys/queue.h>
+
+#include <rte_log.h>
+#include <rte_eal_memconfig.h>
+#include <rte_errno.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_prefetch.h>
+#include <rte_branch_prediction.h>
+
+#include "rte_efd.h"
+
+/** Hash function used to determine chunk_id and bin_id for a group */
+#define EFD_HASH(key) (efd_hash_internal((key), 0xbc9f1d34))
+/** Hash function used as constant component of perfect hash search */
+#define EFD_HASHFUNCA(key) (efd_hash_internal((key), 0xbc9f1d35))
+/** Hash function used as multiplicative component of perfect hash search */
+#define EFD_HASHFUNCB(key) (efd_hash_internal((key), 0xbc9f1d36))
+
+/*************************************************************************
+ * Fixed constants
+ *************************************************************************/
+
+/* These parameters are fixed by the efd_bin_to_group balancing table */
+#define EFD_CHUNK_NUM_GROUPS (64)
+#define EFD_CHUNK_NUM_BINS (256)
+#define EFD_CHUNK_NUM_BIN_TO_GROUP_SETS (EFD_CHUNK_NUM_BINS / EFD_CHUNK_NUM_GROUPS)
+
+/*
+ * Target number of rules that each chunk is created to handle.
+ * Used when initially allocating the table
+ */
+#define EFD_TARGET_CHUNK_NUM_RULES (EFD_CHUNK_NUM_GROUPS * EFD_TARGET_GROUP_NUM_RULES)
+
+/** This is fixed based on the bin_to_group permutation array */
+#define EFD_MAX_GROUP_NUM_BINS (16)
+
+/**
+ * The end of the chunks array needs some extra padding to ensure
+ * that vectorization over-reads on the last online chunk stay within
+allocated memory
+ */
+#define EFD_NUM_CHUNK_PADDING_BYTES (256)
+
+#define EFD_LOOKUPTBL_SHIFT (32 - 4)
+typedef uint16_t efd_lookuptbl_t;
+typedef uint16_t efd_hashfunc_t;
+
+TAILQ_HEAD(rte_efd_list, rte_tailq_entry);
+
+static struct rte_tailq_elem rte_efd_tailq = {
+ .name = "RTE_EFD",
+};
+EAL_REGISTER_TAILQ(rte_efd_tailq);
+
+/** Internal permutation array used to shuffle bins into pseudorandom groups */
+const uint32_t efd_bin_to_group[EFD_CHUNK_NUM_BIN_TO_GROUP_SETS][EFD_CHUNK_NUM_BINS] = {
+ {
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
+ 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
+ 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
+ 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
+ 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,
+ 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
+ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,
+ 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
+ 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
+ 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47,
+ 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,
+ 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55,
+ 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59,
+ 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63
+ },
+ {
+ 34, 33, 48, 59, 0, 21, 36, 18, 9, 49, 54, 38, 51, 23, 31, 5,
+ 44, 23, 37, 52, 11, 4, 58, 20, 38, 40, 38, 22, 26, 28, 42, 6,
+ 46, 16, 31, 28, 46, 14, 60, 0, 35, 53, 16, 58, 16, 29, 39, 7,
+ 1, 54, 15, 11, 48, 3, 62, 9, 58, 5, 30, 43, 17, 7, 36, 34,
+ 6, 36, 2, 14, 10, 1, 47, 47, 20, 45, 62, 56, 34, 25, 39, 18,
+ 51, 41, 61, 25, 56, 40, 41, 37, 52, 35, 30, 57, 11, 42, 37, 27,
+ 54, 19, 26, 13, 48, 31, 46, 15, 12, 10, 16, 20, 43, 17, 12, 55,
+ 45, 18, 8, 41, 7, 31, 42, 63, 12, 14, 21, 57, 24, 40, 5, 41,
+ 13, 44, 23, 59, 25, 57, 52, 50, 62, 1, 2, 49, 32, 57, 26, 43,
+ 56, 60, 55, 5, 49, 6, 3, 50, 46, 39, 27, 33, 17, 4, 53, 13,
+ 2, 19, 36, 51, 63, 0, 22, 33, 59, 28, 29, 23, 45, 33, 53, 27,
+ 22, 21, 40, 56, 4, 18, 44, 47, 28, 17, 4, 50, 21, 62, 8, 39,
+ 0, 8, 15, 24, 29, 24, 9, 11, 48, 61, 35, 55, 43, 1, 54, 42,
+ 53, 60, 22, 3, 32, 52, 25, 8, 15, 60, 7, 55, 27, 63, 19, 10,
+ 63, 24, 61, 19, 12, 38, 6, 29, 13, 37, 10, 3, 45, 32, 32, 30,
+ 49, 61, 44, 14, 20, 58, 35, 30, 2, 26, 34, 51, 9, 59, 47, 50
+ },
+ {
+ 32, 35, 32, 34, 55, 5, 6, 23, 49, 11, 6, 23, 52, 37, 29, 54,
+ 55, 40, 63, 50, 29, 52, 61, 25, 12, 56, 39, 38, 29, 11, 46, 1,
+ 40, 11, 19, 56, 7, 28, 51, 16, 15, 48, 21, 51, 60, 31, 14, 22,
+ 41, 47, 59, 56, 53, 28, 58, 26, 43, 27, 41, 33, 24, 52, 44, 38,
+ 13, 59, 48, 51, 60, 15, 3, 30, 15, 0, 10, 62, 44, 14, 28, 51,
+ 38, 2, 41, 26, 25, 49, 10, 12, 55, 57, 27, 35, 19, 33, 0, 30,
+ 5, 36, 47, 53, 5, 53, 20, 43, 34, 37, 52, 41, 21, 63, 59, 9,
+ 24, 1, 45, 24, 39, 44, 45, 16, 9, 17, 7, 50, 57, 22, 18, 28,
+ 25, 45, 2, 40, 58, 15, 17, 3, 1, 27, 61, 39, 19, 0, 19, 21,
+ 57, 62, 54, 60, 54, 40, 48, 33, 36, 37, 4, 42, 1, 43, 58, 8,
+ 13, 42, 10, 56, 35, 22, 48, 61, 63, 10, 49, 9, 24, 9, 25, 57,
+ 33, 18, 13, 31, 42, 36, 36, 55, 30, 37, 53, 34, 59, 4, 4, 23,
+ 8, 16, 58, 14, 30, 11, 12, 63, 49, 62, 2, 39, 47, 22, 2, 60,
+ 18, 8, 46, 31, 6, 20, 32, 29, 46, 42, 20, 31, 32, 61, 34, 4,
+ 47, 26, 20, 43, 26, 21, 7, 3, 16, 35, 18, 44, 27, 62, 13, 23,
+ 6, 50, 12, 8, 45, 17, 3, 46, 50, 7, 14, 5, 17, 54, 38, 0
+ },
+ {
+ 29, 56, 5, 7, 54, 48, 23, 37, 35, 44, 52, 40, 33, 49, 60, 0,
+ 59, 51, 28, 12, 41, 26, 2, 23, 34, 5, 59, 40, 3, 19, 6, 26,
+ 35, 53, 45, 49, 29, 57, 28, 62, 58, 59, 19, 53, 59, 62, 6, 54,
+ 13, 15, 48, 50, 45, 21, 41, 12, 34, 40, 24, 56, 19, 21, 35, 18,
+ 55, 45, 9, 61, 47, 61, 19, 15, 16, 39, 17, 31, 3, 51, 21, 50,
+ 17, 25, 25, 11, 44, 16, 18, 28, 14, 2, 37, 61, 58, 27, 62, 4,
+ 14, 17, 1, 9, 46, 28, 37, 0, 53, 43, 57, 7, 57, 46, 21, 41,
+ 39, 14, 52, 60, 44, 53, 49, 60, 49, 63, 13, 11, 29, 1, 55, 47,
+ 55, 12, 60, 43, 54, 37, 13, 6, 42, 10, 36, 13, 9, 8, 34, 51,
+ 31, 32, 12, 7, 57, 2, 26, 14, 3, 30, 63, 3, 32, 1, 5, 11,
+ 27, 24, 26, 44, 31, 23, 56, 38, 62, 0, 40, 30, 6, 23, 38, 2,
+ 47, 5, 15, 27, 16, 10, 31, 25, 22, 63, 30, 25, 20, 33, 32, 50,
+ 29, 43, 55, 10, 50, 45, 56, 20, 4, 7, 27, 46, 11, 16, 22, 52,
+ 35, 20, 41, 54, 46, 33, 42, 18, 63, 8, 22, 58, 36, 4, 51, 42,
+ 38, 32, 38, 22, 17, 0, 47, 8, 48, 8, 48, 1, 61, 36, 33, 20,
+ 24, 39, 39, 18, 30, 36, 9, 43, 42, 24, 10, 58, 4, 15, 34, 52
+ },
+};
+
+/*************************************************************************
+ * Offline region structures
+ *************************************************************************/
+
+/** Online group containing number of rules, values, keys and their bins
+ * for EFD_MAX_GROUP_NUM_RULES rules.
+ */
+struct efd_offline_group_rules {
+ uint32_t num_rules;
+ /**< Sum of the number of rules in all bins assigned to this group. */
+
+ efd_key_t key[EFD_MAX_GROUP_NUM_RULES];
+ /**< Array with all keys of the group. */
+ efd_value_t value[EFD_MAX_GROUP_NUM_RULES];
+ /**< Array with all values of the keys of the group. */
+
+ uint8_t bin_id[EFD_MAX_GROUP_NUM_RULES];
+ /**< Stores the bin for each correspending key to
+ * avoid having to recompute it
+ */
+};
+
+/** Offline chunk record, containing EFD_TARGET_CHUNK_NUM_RULES rules.
+ * Those rules are split into EFD_CHUNK_NUM_GROUPS groups per chunk.
+ */
+struct efd_offline_chunk_rules {
+ uint16_t num_rules;
+ /**< Number of rules in the entire chunk; used to detect unbalanced groups */
+
+ struct efd_offline_group_rules group_rules[EFD_CHUNK_NUM_GROUPS];
+ /**< Array of all groups in the chunk. */
+};
+
+/*************************************************************************
+ * Online region structures
+ *************************************************************************/
+
+/** Online group containing values for EFD_MAX_GROUP_NUM_RULES rules. */
+struct efd_online_group_entry {
+ efd_hashfunc_t hash_idx[EFD_VALUE_NUM_BITS];
+ efd_lookuptbl_t lookup_table[EFD_VALUE_NUM_BITS];
+} __attribute__((__packed__));
+
+/**
+ * A single chunk record, containing EFD_TARGET_CHUNK_NUM_RULES rules.
+ * Those rules are split into EFD_CHUNK_NUM_GROUPS groups per chunk.
+ */
+struct efd_online_chunk {
+ uint8_t bin_choice_list[(EFD_CHUNK_NUM_BINS * 2 + 7) / 8];
+ /**< This is a packed indirection index into the 'groups' array.
+ * Each byte contains four two-bit values which index into
+ * the efd_bin_to_group array.
+ * The efd_bin_to_group array returns the index into the groups array
+ */
+
+ struct efd_online_group_entry groups[EFD_CHUNK_NUM_GROUPS];
+ /**< Array of all the groups in the chunk. */
+} __attribute__((__packed__));
+
+/**
+ * EFD table structure
+ */
+struct rte_efd_table {
+ char name[RTE_EFD_NAMESIZE]; /**< Name of the efd table. */
+
+ uint32_t max_num_rules;
+ /**< Static maximum number of entries the table was constructed to hold. */
+
+ uint32_t num_rules;
+ /**< Number of entries currently in the table . */
+
+ uint32_t num_chunks;
+ /**< Number of chunks in the table needed to support num_rules. */
+
+ uint32_t num_chunks_shift;
+ /**< Bits to shift to get chunk id, instead of dividing by num_chunk. */
+
+ struct efd_online_chunk *chunks[RTE_MAX_NUMA_NODES];
+ /**< Dynamic array of size num_chunks of chunk records. */
+
+ struct efd_offline_chunk_rules *offline_chunks;
+ /**< Dynamic array of size num_chunks of key-value pairs. */
+};
+
+
+/**
+ * Compute the hash of a key given a particular seed
+ *
+ * @param key
+ * key to hash
+ * @param seed
+ * seed for the hash function
+ *
+ * @return
+ * 32-bit hash
+ */
+static inline uint32_t
+efd_hash_internal(const efd_key_t *const key, const uint32_t seed)
+{
+ return (uint32_t)(rte_hash_crc(key->bytes, EFD_KEY_LEN, seed));
+}
+
+
+/**
+ * Computes the chunk ID for a given key hash
+ *
+ * @param table
+ * EFD table to reference
+ * @param hashed_key
+ * 32-bit key hash returned by EFD_HASH
+ *
+ * @return
+ * chunk ID containing this key hash
+ */
+static inline uint32_t
+efd_get_chunk_id(const struct rte_efd_table *const table,
+ const uint32_t hashed_key)
+{
+ return hashed_key & (table->num_chunks - 1);
+}
+
+/**
+ * Computes the bin ID for a given key hash
+ *
+ * @param table
+ * EFD table to reference
+ * @param hashed_key
+ * 32-bit key hash returned by EFD_HASH
+ *
+ * @return bin ID containing this key hash
+ */
+static inline uint32_t
+efd_get_bin_id(const struct rte_efd_table *const table,
+ const uint32_t hashed_key)
+{
+ return (hashed_key >> table->num_chunks_shift) & (EFD_CHUNK_NUM_BINS - 1);
+}
+
+/**
+ * Looks up the current permutation choice for a particular bin in the online table
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to look up existing values (ideally caller's socket id)
+ * @param chunk_id
+ * Chunk ID of bin to look up
+ * @param bin_id
+ * Bin ID to look up
+ *
+ * @return
+ * Currently active permutation choice in the online table
+ */
+static inline uint8_t
+efd_get_choice(const struct rte_efd_table *const table,
+ const unsigned int socket_id,
+ const uint32_t chunk_id,
+ const uint32_t bin_id)
+{
+ struct efd_online_chunk *chunk = &table->chunks[socket_id][chunk_id];
+
+ /*
+ * Grab the chunk (byte) that contains the choices
+ * for four neighboring bins.
+ */
+ uint8_t choice_chunk =
+ chunk->bin_choice_list[bin_id / EFD_CHUNK_NUM_BIN_TO_GROUP_SETS];
+
+ /*
+ * Compute the offset into the chunk that contains
+ * the group_id lookup position
+ */
+ int offset = (bin_id & 0x3) * 2;
+
+ /* Extract from the byte just the desired lookup position */
+ return (uint8_t)((choice_chunk >> offset) & 0x3);
+}
+
+/**
+ * Compute the chunk_id and bin_id for a given key
+ *
+ * @param table
+ * EFD table to reference
+ * @param key
+ * Key to hash and find location of
+ * @param chunk_id
+ * Computed chunk ID
+ * @param bin_id
+ * Computed bin ID
+ *
+ */
+static inline void
+efd_compute_ids(const struct rte_efd_table *const table,
+ const efd_key_t *const key, uint32_t *const chunk_id,
+ uint32_t *const bin_id)
+{
+ /* Compute the position of the entry in the hash table */
+ uint32_t h = EFD_HASH(key);
+
+ /* Compute the chunk_id where that entry can be found */
+ *chunk_id = efd_get_chunk_id(table, h);
+
+ /*
+ * Compute the bin within that chunk where the entry
+ * can be found (0 - 255)
+ */
+ *bin_id = efd_get_bin_id(table, h);
+}
+
+/**
+ * Search for a hash function for a group that satisfies all group results
+ */
+static inline int
+efd_search_hash(const struct efd_offline_group_rules *const off_group,
+ struct efd_online_group_entry *const on_group)
+{
+ efd_hashfunc_t hash_idx;
+ efd_hashfunc_t start_hash_idx[EFD_VALUE_NUM_BITS];
+ efd_lookuptbl_t start_lookup_table[EFD_VALUE_NUM_BITS];
+
+ uint32_t i, j, rule_id;
+ uint32_t hash_val_a[EFD_MAX_GROUP_NUM_RULES];
+ uint32_t hash_val_b[EFD_MAX_GROUP_NUM_RULES];
+ uint32_t hash_val[EFD_MAX_GROUP_NUM_RULES];
+
+
+ rte_prefetch0(off_group->value);
+
+ /*
+ * Prepopulate the hash_val tables by running the two hash functions
+ * for each provided rule
+ */
+ for (i = 0; i < off_group->num_rules; i++) {
+ hash_val_b[i] = EFD_HASHFUNCB(&off_group->key[i]);
+ hash_val_a[i] = EFD_HASHFUNCA(&off_group->key[i]);
+ }
+
+ for (i = 0; i < EFD_VALUE_NUM_BITS; i++) {
+ hash_idx = on_group->hash_idx[i];
+ start_hash_idx[i] = hash_idx;
+
+ do {
+ efd_lookuptbl_t lookup_table = 0;
+ efd_lookuptbl_t lookup_table_complement = 0;
+
+ for (rule_id = 0; rule_id < off_group->num_rules; rule_id++)
+ hash_val[rule_id] = hash_val_a[rule_id] + (hash_idx *
+ hash_val_b[rule_id]);
+
+ /*
+ * The goal here is to find a hash function for this
+ * particular bit entry that meets the following criteria:
+ * The most significant bits of the hash result define a
+ * shift into the lookup table where the bit will be stored
+ */
+
+ /* Iterate over each provided rule */
+ for (rule_id = 0; rule_id < off_group->num_rules;
+ rule_id++) {
+ /*
+ * Use the few most significant bits (number based on
+ * EFD_LOOKUPTBL_SIZE) to see what position the
+ * expected bit should be set in the lookup_table
+ */
+ uint32_t bucket_idx = hash_val[rule_id] >>
+ EFD_LOOKUPTBL_SHIFT;
+
+ /*
+ * Get the current bit of interest.
+ * This only find an appropriate hash function
+ * for one bit at a time of the rule
+ */
+ efd_lookuptbl_t expected =
+ (off_group->value[rule_id] >> i) & 0x1;
+
+ /*
+ * Add the expected bit (if set) to a map
+ * (lookup_table). Also set its complement
+ * in lookup_table_complement
+ */
+ lookup_table |= expected << bucket_idx;
+ lookup_table_complement |= (1 - expected)
+ << bucket_idx;
+
+ /*
+ * If ever the hash function of two different
+ * elements result in different values at the
+ * same location in the lookup_table,
+ * the current hash_idx is not valid.
+ */
+ if (lookup_table & lookup_table_complement)
+ break;
+ }
+
+ /*
+ * Check if the previous loop completed without
+ * breaking early
+ */
+ if (rule_id == off_group->num_rules) {
+ /*
+ * Current hash function worked, store it
+ * for the current group
+ */
+ on_group->hash_idx[i] = hash_idx;
+ on_group->lookup_table[i] = lookup_table;
+
+ /*
+ * Make sure that the hash function has changed
+ * from the starting value
+ */
+ hash_idx = start_hash_idx[i] + 1;
+ break;
+ }
+ hash_idx++;
+
+ } while (hash_idx != start_hash_idx[i]);
+
+ /* Failed to find perfect hash for this group */
+ if (hash_idx == start_hash_idx[i]) {
+ /*
+ * Restore previous hash_idx and lookup_table
+ * for all value bits
+ */
+ for (j = 0; j < i; j++) {
+ on_group->hash_idx[j] = start_hash_idx[j];
+ on_group->lookup_table[j] = start_lookup_table[j];
+ }
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+struct rte_efd_table *
+rte_efd_create(const char *name, uint32_t max_num_rules,
+ uint8_t online_cpu_socket_bitmask,
+ uint8_t offline_cpu_socket)
+{
+ struct rte_efd_table *table = NULL;
+ uint32_t num_chunks, num_chunks_shift;
+ uint8_t socket_id;
+ struct rte_efd_list *efd_list = NULL;
+ struct rte_tailq_entry *te;
+ uint64_t offline_table_size;
+
+ efd_list = RTE_TAILQ_CAST(rte_efd_tailq.head, rte_efd_list);
+
+ if (online_cpu_socket_bitmask == 0) {
+ RTE_LOG(ERR, EFD, "At least one CPU socket must be enabled "
+ "in the bitmask\n");
+ return NULL;
+ }
+
+ if (max_num_rules == 0) {
+ RTE_LOG(ERR, EFD, "Max num rules must be higher than 0\n");
+ return NULL;
+ }
+
+ /*
+ * Compute the minimum number of chunks (smallest power of 2)
+ * that can hold all of the rules
+ */
+ if (max_num_rules % EFD_TARGET_CHUNK_NUM_RULES == 0)
+ num_chunks = rte_align32pow2(max_num_rules /
+ EFD_TARGET_CHUNK_NUM_RULES);
+ else
+ num_chunks = rte_align32pow2((max_num_rules /
+ EFD_TARGET_CHUNK_NUM_RULES) + 1);
+
+ num_chunks_shift = log2(num_chunks);
+
+ rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+ /*
+ * Guarantee there's no existing: this is normally already checked
+ * by ring creation above
+ */
+ TAILQ_FOREACH(te, efd_list, next) {
+ table = (struct rte_efd_table *) te->data;
+ if (strncmp(name, table->name, RTE_EFD_NAMESIZE) == 0)
+ break;
+ }
+
+ table = NULL;
+ if (te != NULL) {
+ rte_errno = EEXIST;
+ te = NULL;
+ goto error_unlock_exit;
+ }
+
+ te = rte_zmalloc("EFD_TAILQ_ENTRY", sizeof(*te), 0);
+ if (te == NULL) {
+ RTE_LOG(ERR, EFD, "tailq entry allocation failed\n");
+ goto error_unlock_exit;
+ }
+
+ /* Create a new EFD table management structure */
+ table = (struct rte_efd_table *) rte_zmalloc_socket(NULL,
+ sizeof(struct rte_efd_table),
+ RTE_CACHE_LINE_SIZE,
+ offline_cpu_socket);
+ if (table == NULL) {
+ RTE_LOG(ERR, EFD, "Allocating EFD table management structure"
+ " on socket %u failed\n",
+ offline_cpu_socket);
+ goto error_unlock_exit;
+ }
+
+
+ RTE_LOG(DEBUG, EFD, "Allocated EFD table management structure "
+ "on socket %u\n", offline_cpu_socket);
+
+ table->max_num_rules = num_chunks * EFD_TARGET_CHUNK_NUM_RULES;
+ table->num_rules = 0;
+ table->num_chunks = num_chunks;
+ table->num_chunks_shift = num_chunks_shift;
+ snprintf(table->name, sizeof(table->name), "%s", name);
+
+ RTE_LOG(DEBUG, EFD, "Creating an EFD table with %u chunks,"
+ " which potentially supports %u entries\n",
+ num_chunks, table->max_num_rules);
+
+ /* Make sure all the allocatable table pointers are NULL initially */
+ for (socket_id = 0; socket_id < RTE_MAX_NUMA_NODES; socket_id++)
+ table->chunks[socket_id] = NULL;
+ table->offline_chunks = NULL;
+
+ /*
+ * Allocate one online table per socket specified
+ * in the user-supplied bitmask
+ */
+ uint64_t online_table_size = num_chunks * sizeof(struct efd_online_chunk) +
+ EFD_NUM_CHUNK_PADDING_BYTES;
+
+ for (socket_id = 0; socket_id < RTE_MAX_NUMA_NODES; socket_id++) {
+ if ((online_cpu_socket_bitmask >> socket_id) & 0x01) {
+ /*
+ * Allocate all of the EFD table chunks (the online portion)
+ * as a continuous block
+ */
+ table->chunks[socket_id] =
+ (struct efd_online_chunk *) rte_zmalloc_socket(NULL,
+ online_table_size,
+ RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (table->chunks[socket_id] == NULL) {
+ RTE_LOG(ERR, EFD,
+ "Allocating EFD online table on "
+ "socket %u failed\n",
+ socket_id);
+ goto error_unlock_exit;
+ }
+ RTE_LOG(DEBUG, EFD,
+ "Allocated EFD online table of size %lu bytes "
+ "(%.2f MB) on socket %u\n", online_table_size,
+ (float)online_table_size / (1024.0F * 1024.0F),
+ socket_id);
+ }
+ }
+
+ /*
+ * Allocate the EFD table offline portion (with the actual rules
+ * mapping keys to values) as a continuous block.
+ * This could be several gigabytes of memory.
+ */
+ offline_table_size = num_chunks * sizeof(struct efd_offline_chunk_rules);
+ table->offline_chunks =
+ (struct efd_offline_chunk_rules *) rte_zmalloc_socket(NULL,
+ offline_table_size,
+ RTE_CACHE_LINE_SIZE,
+ offline_cpu_socket);
+ if (table->offline_chunks == NULL) {
+ RTE_LOG(ERR, EFD, "Allocating EFD offline table on socket %u "
+ "failed\n", offline_cpu_socket);
+ goto error_unlock_exit;
+ }
+
+ RTE_LOG(DEBUG, EFD,
+ "Allocated EFD offline table of size %lu bytes "
+ " (%.2f MB) on socket %u\n", offline_table_size,
+ (float)offline_table_size / (1024.0F * 1024.0F),
+ offline_cpu_socket);
+
+ te->data = (void *) table;
+ TAILQ_INSERT_TAIL(efd_list, te, next);
+ rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+ return table;
+
+error_unlock_exit:
+ rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+ rte_efd_free(table);
+
+ return NULL;
+}
+
+struct rte_efd_table *
+rte_efd_find_existing(const char *name)
+{
+ struct rte_efd_table *table = NULL;
+ struct rte_tailq_entry *te;
+ struct rte_efd_list *efd_list;
+
+ efd_list = RTE_TAILQ_CAST(rte_efd_tailq.head, rte_efd_list);
+
+ rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+ TAILQ_FOREACH(te, efd_list, next) {
+ table = (struct rte_efd_table *) te->data;
+ if (strncmp(name, table->name, RTE_EFD_NAMESIZE) == 0)
+ break;
+ }
+ rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+ if (te == NULL) {
+ rte_errno = ENOENT;
+ return NULL;
+ }
+ return table;
+}
+
+void
+rte_efd_free(struct rte_efd_table *table)
+{
+ uint8_t socket_id;
+
+ if (table != NULL) {
+ for (socket_id = 0; socket_id < RTE_MAX_NUMA_NODES; socket_id++) {
+ if (table->chunks[socket_id] != NULL)
+ rte_free(table->chunks[socket_id]);
+ }
+
+ if (table->offline_chunks != NULL)
+ rte_free(table->offline_chunks);
+
+ rte_free(table);
+ }
+}
+
+/**
+ * Applies a previously computed table entry to the specified table for all
+ * socket-local copies of the online table.
+ * Intended to apply an update for only a single change
+ * to a key/value pair at a time
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing values (ideally caller's socket id)
+ * @param chunk_id
+ * Chunk index to update
+ * @param group_id
+ * Group index to update
+ * @param bin_id
+ * Bin within the group that this update affects
+ * @param new_bin_choice
+ * Newly chosen permutation which this bin should use - only lower 2 bits
+ * @param new_group_entry
+ * Previously computed updated chunk/group entry
+ */
+static inline void
+efd_apply_update(struct rte_efd_table *const table, const unsigned int socket_id,
+ const uint32_t chunk_id, const uint32_t group_id,
+ const uint32_t bin_id, const uint8_t new_bin_choice,
+ const struct efd_online_group_entry *const new_group_entry)
+{
+ int i;
+ struct efd_online_chunk *chunk = &table->chunks[socket_id][chunk_id];
+ uint8_t bin_index = bin_id / EFD_CHUNK_NUM_BIN_TO_GROUP_SETS;
+
+ /*
+ * Grab the current byte that contains the choices
+ * for four neighboring bins
+ */
+ uint8_t choice_chunk =
+ chunk->bin_choice_list[bin_index];
+
+
+ /* Compute the offset into the chunk that needs to be updated */
+ int offset = (bin_id & 0x3) * 2;
+
+ /* Zero the two bits of interest and set them to new_bin_choice */
+ choice_chunk = (choice_chunk & (~(0x03 << offset)))
+ | ((new_bin_choice & 0x03) << offset);
+
+ /* Update the online table with the new data across all sockets */
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ if (table->chunks[i] != NULL) {
+ memcpy(&(table->chunks[i][chunk_id].groups[group_id]),
+ new_group_entry,
+ sizeof(struct efd_online_group_entry));
+ table->chunks[i][chunk_id].bin_choice_list[bin_index] =
+ choice_chunk;
+ }
+ }
+}
+
+
+/**
+ * Computes an updated table entry where the supplied key points to a new host.
+ * If no entry exists, one is inserted.
+ *
+ * This function does NOT modify the online table(s)
+ * This function DOES modify the offline table
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing values (ideally caller's socket id)
+ * @param key
+ * Key to insert
+ * @param value
+ * Value to associate with key
+ * @param chunk_id
+ * Chunk ID of the chunk that was modified
+ * @param group_id
+ * Group ID of the group that was modified
+ * @param bin_id
+ * Bin ID that was modified
+ * @param new_bin_choice
+ * Newly chosen permutation which this bin will use
+ * @param entry
+ * Newly computed online entry to apply later with efd_apply_update
+ *
+ * @return
+ * EFD_UPDATE_WARN_GROUP_FULL
+ * Operation is insert, and the last available space in the
+ * key's group was just used. Future inserts may fail as groups fill up.
+ * This operation was still successful, and entry contains a valid update
+ * EFD_UPDATE_FAILED
+ * Either the EFD failed to find a suitable perfect hash or the group was full
+ * This is a fatal error, and the table is now in an indeterminite state
+ * EFD_UPDATE_NO_CHANGE
+ * Operation resulted in no change to the table (same value already exists)
+ * 0
+ * Insert or update was successful, and the new efd_online_group_entry
+ * is stored in *entry
+ *
+ * @warning
+ * Note that entry will be UNCHANGED if the update has no effect, and thus any
+ * subsequent use of the entry content will likely be invalid
+ */
+static inline int
+efd_compute_update(struct rte_efd_table *const table, const unsigned int socket_id,
+ const efd_key_t *const key, const efd_value_t value,
+ uint32_t *const chunk_id, uint32_t *const group_id,
+ uint32_t *const bin_id, uint8_t *const new_bin_choice,
+ struct efd_online_group_entry *const entry)
+{
+ unsigned int i;
+ int ret;
+ int status = EXIT_SUCCESS;
+ int found = 0;
+
+ efd_compute_ids(table, key, chunk_id, bin_id);
+
+ struct efd_offline_chunk_rules *const chunk =
+ &table->offline_chunks[*chunk_id];
+ struct efd_offline_group_rules *new_group;
+ struct efd_offline_group_rules current_group_copy;
+ struct efd_offline_group_rules new_group_copy;
+
+ uint8_t current_choice = efd_get_choice(table, socket_id,
+ *chunk_id, *bin_id);
+ uint32_t current_group_id = efd_bin_to_group[current_choice][*bin_id];
+ struct efd_offline_group_rules *const current_group =
+ &chunk->group_rules[current_group_id];
+ uint8_t bin_size = 0;
+
+ /* Scan the current group and see if the key is already present */
+ for (i = 0; i < current_group->num_rules; i++) {
+ if (current_group->bin_id[i] == *bin_id)
+ bin_size++;
+
+ if (found == 0 && unlikely(memcmp(&current_group->key[i],
+ key, EFD_KEY_LEN) == 0)) {
+ /* Key is already present */
+
+ /*
+ * If previous value is same as new value,
+ * no additional work is required
+ */
+ if (current_group->value[i] == value)
+ return EFD_UPDATE_NO_CHANGE;
+
+ /* Save the original group state, if update fails */
+ memcpy(&current_group_copy, current_group,
+ sizeof(struct efd_offline_group_rules));
+ current_group->value[i] = value;
+ found = 1;
+ }
+ }
+
+ if (found == 0) {
+ /* Key does not exist. Insert the rule into the bin/group */
+ if (unlikely(current_group->num_rules >= EFD_MAX_GROUP_NUM_RULES)) {
+ RTE_LOG(ERR, EFD,
+ "Fatal: No room remaining for insert into "
+ "chunk %u group %u bin %u\n",
+ *chunk_id,
+ current_group_id, *bin_id);
+ return EFD_UPDATE_FAILED;
+ }
+ /* Save the original group state, if update fails */
+ memcpy(&current_group_copy, current_group,
+ sizeof(struct efd_offline_group_rules));
+
+ if (unlikely(current_group->num_rules ==
+ (EFD_MAX_GROUP_NUM_RULES - 1))) {
+ RTE_LOG(INFO, EFD, "Warn: Insert into last "
+ "available slot in chunk %u "
+ "group %u bin %u\n", *chunk_id,
+ current_group_id, *bin_id);
+ status = EFD_UPDATE_WARN_GROUP_FULL;
+ }
+ memcpy(&current_group->key[current_group->num_rules],
+ key, EFD_KEY_LEN);
+ current_group->value[current_group->num_rules] = value;
+ current_group->bin_id[current_group->num_rules] = *bin_id;
+ table->num_rules++;
+ current_group->num_rules++;
+ bin_size++;
+ }
+
+ /* Group need to be rebalanced when it starts to get loaded */
+ if (current_group->num_rules > EFD_MIN_BALANCED_NUM_RULES) {
+
+ /*
+ * Subtract the number of entries in the bin from
+ * the original group
+ */
+ current_group->num_rules -= bin_size;
+
+ /*
+ * Figure out which of the available groups that this bin
+ * can map to is the smallest (using the current group
+ * as baseline)
+ */
+ uint8_t smallest_choice = current_choice;
+ uint8_t smallest_size = current_group->num_rules;
+ uint32_t smallest_group_id = current_group_id;
+ unsigned char choice;
+
+ for (choice = 0; choice < EFD_CHUNK_NUM_BIN_TO_GROUP_SETS;
+ choice++) {
+ uint32_t test_group_id =
+ efd_bin_to_group[choice][*bin_id];
+ uint32_t num_rules =
+ chunk->group_rules[test_group_id].num_rules;
+ if (num_rules < smallest_size) {
+ smallest_choice = choice;
+ smallest_size = num_rules;
+ smallest_group_id = test_group_id;
+ }
+ }
+
+ *new_bin_choice = smallest_choice;
+ *group_id = smallest_group_id;
+ new_group = &chunk->group_rules[smallest_group_id];
+
+ if (smallest_group_id == current_group_id) {
+ new_group->num_rules += bin_size;
+ RTE_LOG(DEBUG, EFD, "chunk %u: Left bin %u (%u entries) "
+ "in group %u (%u entries)\n", *chunk_id,
+ *bin_id, bin_size, *group_id,
+ new_group->num_rules);
+ } else {
+ /*
+ * Remove the bin from the group it was previously
+ * assigned to and add it to the new group
+ */
+
+ RTE_LOG(DEBUG, EFD, "chunk %u: Moving bin %u (%u entries) "
+ "from group %u (%u entries) to %u "
+ "(%u entries)\n", *chunk_id, *bin_id,
+ bin_size, current_group_id,
+ current_group->num_rules + bin_size,
+ smallest_group_id,
+ new_group->num_rules + bin_size);
+
+ /* Save the original group state, if update fails */
+ memcpy(&new_group_copy, new_group,
+ sizeof(struct efd_offline_group_rules));
+
+ uint8_t empty_idx = 0;
+
+ for (i = 0; i < current_group->num_rules + bin_size; i++) {
+ /*
+ * Move keys that belong to the same bin
+ * to the new group
+ */
+ if (current_group->bin_id[i] == *bin_id) {
+ new_group->key[new_group->num_rules] =
+ current_group->key[i];
+ new_group->value[new_group->num_rules] =
+ current_group->value[i];
+ new_group->bin_id[new_group->num_rules] =
+ current_group->bin_id[i];
+ new_group->num_rules++;
+ } else {
+ if (i != empty_idx) {
+ /*
+ * Need to move this key towards
+ * the top of the array
+ */
+ current_group->key[empty_idx] =
+ current_group->key[i];
+ current_group->value[empty_idx] =
+ current_group->value[i];
+ current_group->bin_id[empty_idx] =
+ current_group->bin_id[i];
+ }
+ empty_idx++;
+ }
+
+ }
+ }
+ } else {
+ *new_bin_choice = current_choice;
+ *group_id = current_group_id;
+ new_group = current_group;
+ }
+
+ /*
+ * Recompute the hash function for the modified group,
+ * and return it to the caller
+ */
+ ret = efd_search_hash(new_group, entry);
+
+ if (ret != 0) {
+ RTE_LOG(ERR, EFD,
+ "Failed to find perfect hash for group "
+ "containing %u entries\n",
+ new_group->num_rules);
+ /* Restore table to the previous state */
+ if (new_group != current_group)
+ memcpy(new_group, &new_group_copy,
+ sizeof(struct efd_offline_group_rules));
+ memcpy(current_group, &current_group_copy,
+ sizeof(struct efd_offline_group_rules));
+
+ return EFD_UPDATE_FAILED;
+ }
+
+ return status;
+}
+
+int
+rte_efd_update(struct rte_efd_table *const table, const unsigned int socket_id,
+ const efd_key_t *const key,
+ const efd_value_t value)
+{
+ uint32_t chunk_id, group_id, bin_id;
+ uint8_t new_bin_choice;
+ struct efd_online_group_entry entry;
+
+ int status = efd_compute_update(table, socket_id, key, value,
+ &chunk_id, &group_id, &bin_id,
+ &new_bin_choice, &entry);
+
+ if (status == EFD_UPDATE_NO_CHANGE)
+ return EXIT_SUCCESS;
+
+ if (status != EXIT_SUCCESS)
+ return status;
+
+ efd_apply_update(table, socket_id, chunk_id, group_id, bin_id,
+ new_bin_choice, &entry);
+ return status;
+}
+
+int
+rte_efd_delete(struct rte_efd_table *const table, const unsigned int socket_id,
+ const efd_key_t *const key, efd_value_t *const prev_value)
+{
+ unsigned int i;
+ uint32_t chunk_id, bin_id;
+ uint8_t not_found = 1;
+
+ efd_compute_ids(table, key, &chunk_id, &bin_id);
+
+ struct efd_offline_chunk_rules *const chunk =
+ &table->offline_chunks[chunk_id];
+
+ uint8_t current_choice = efd_get_choice(table, socket_id,
+ chunk_id, bin_id);
+ uint32_t current_group_id = efd_bin_to_group[current_choice][bin_id];
+ struct efd_offline_group_rules *const current_group =
+ &chunk->group_rules[current_group_id];
+
+ /*
+ * Search the current group for the specified key.
+ * If it exists, remove it and re-pack the other values
+ */
+ for (i = 0; i < current_group->num_rules; i++) {
+ if (not_found) {
+ /* Found key that needs to be removed */
+ if (memcmp(&current_group->key[i], key, EFD_KEY_LEN) == 0) {
+ /* Store previous value if requested by caller */
+ if (prev_value != NULL)
+ *prev_value = current_group->value[i];
+
+ not_found = 0;
+ }
+ } else {
+ /*
+ * If the desired key has been found,
+ * need to shift other values up one
+ */
+
+ /* Need to shift this entry back up one index */
+ current_group->key[i - 1] = current_group->key[i];
+ current_group->value[i - 1] = current_group->value[i];
+ current_group->bin_id[i - 1] = current_group->bin_id[i];
+ }
+ }
+
+ if (not_found == 0) {
+ table->num_rules--;
+ current_group->num_rules--;
+ }
+
+ return not_found;
+}
+
+
+#if (EFD_VALUE_NUM_BITS == 8 || EFD_VALUE_NUM_BITS == 16 || \
+ EFD_VALUE_NUM_BITS == 24 || EFD_VALUE_NUM_BITS == 32)
+#define EFD_LOAD_SI128(val) _mm_load_si128(val)
+#else
+#define EFD_LOAD_SI128(val) _mm_lddqu_si128(val)
+#endif
+
+static inline efd_value_t
+efd_lookup_internal(const struct efd_online_group_entry *const group,
+ const uint32_t hash_val_a, const uint32_t hash_val_b)
+{
+ efd_value_t value = 0;
+
+#if EFD_VALUE_NUM_BITS > 3 && defined(RTE_MACHINE_CPUFLAG_AVX2)
+ uint32_t byte_idx;
+
+ __m256i vhash_val_a = _mm256_set1_epi32(hash_val_a);
+ __m256i vhash_val_b = _mm256_set1_epi32(hash_val_b);
+
+ for (byte_idx = 0; byte_idx < EFD_VALUE_NUM_BITS; byte_idx += 8) {
+ __m256i vhash_idx =
+ _mm256_cvtepu16_epi32(EFD_LOAD_SI128((__m128i const *)
+ &group->hash_idx[byte_idx]));
+ __m256i vlookup_table = _mm256_cvtepu16_epi32(
+ EFD_LOAD_SI128((__m128i const *)
+ &group->lookup_table[byte_idx]));
+ __m256i vhash = _mm256_add_epi32(vhash_val_a,
+ _mm256_mullo_epi32(vhash_idx, vhash_val_b));
+ __m256i vbucket_idx = _mm256_srli_epi32(vhash, EFD_LOOKUPTBL_SHIFT);
+ __m256i vresult = _mm256_srlv_epi32(vlookup_table, vbucket_idx);
+
+ value |= (_mm256_movemask_ps((__m256)_mm256_slli_epi32(vresult, 31))
+ & ((1 << (EFD_VALUE_NUM_BITS - byte_idx)) - 1)) << byte_idx;
+ }
+#else
+ uint32_t bit;
+
+ for (bit = 0; bit < EFD_VALUE_NUM_BITS; bit++) {
+ value <<= 1;
+
+ uint32_t h = hash_val_a + (hash_val_b *
+ group->hash_idx[EFD_VALUE_NUM_BITS - bit - 1]);
+ uint16_t bucket_idx = h >> EFD_LOOKUPTBL_SHIFT;
+
+ value |= (group->lookup_table[EFD_VALUE_NUM_BITS - bit - 1] >>
+ bucket_idx) & 0x1;
+ }
+#endif
+
+ return value;
+}
+
+efd_value_t
+rte_efd_lookup(const struct rte_efd_table *const table, const unsigned int socket_id,
+ const efd_key_t *const key)
+{
+ uint32_t chunk_id, group_id, bin_id;
+ uint8_t bin_choice;
+ const struct efd_online_group_entry *group;
+ const struct efd_online_chunk *const chunks = table->chunks[socket_id];
+
+ /* Determine the chunk and group location for the given key */
+ efd_compute_ids(table, key, &chunk_id, &bin_id);
+ bin_choice = efd_get_choice(table, socket_id, chunk_id, bin_id);
+ group_id = efd_bin_to_group[bin_choice][bin_id];
+ group = &chunks[chunk_id].groups[group_id];
+
+ return efd_lookup_internal(group, EFD_HASHFUNCA(key), EFD_HASHFUNCB(key));
+}
+
+void rte_efd_lookup_bulk(const struct rte_efd_table *const table,
+ const unsigned int socket_id, const int num_keys,
+ const efd_key_t *const *const key_list,
+ efd_value_t *const value_list)
+{
+ int i;
+ uint32_t chunk_id_list[EFD_BURST_MAX];
+ uint32_t bin_id_list[EFD_BURST_MAX];
+ uint8_t bin_choice_list[EFD_BURST_MAX];
+ uint32_t group_id_list[EFD_BURST_MAX];
+ struct efd_online_group_entry *group;
+
+ struct efd_online_chunk *chunks = table->chunks[socket_id];
+
+ for (i = 0; i < num_keys; i++) {
+ efd_compute_ids(table, key_list[i], &chunk_id_list[i],
+ &bin_id_list[i]);
+ rte_prefetch0(&chunks[chunk_id_list[i]].bin_choice_list);
+ }
+
+ for (i = 0; i < num_keys; i++) {
+ bin_choice_list[i] = efd_get_choice(table, socket_id,
+ chunk_id_list[i], bin_id_list[i]);
+ group_id_list[i] =
+ efd_bin_to_group[bin_choice_list[i]][bin_id_list[i]];
+ group = &chunks[chunk_id_list[i]].groups[group_id_list[i]];
+ rte_prefetch0(group);
+ }
+
+ for (i = 0; i < num_keys; i++) {
+ group = &chunks[chunk_id_list[i]].groups[group_id_list[i]];
+ value_list[i] = efd_lookup_internal(group,
+ EFD_HASHFUNCA(key_list[i]),
+ EFD_HASHFUNCB(key_list[i]));
+ }
+}
+
diff --git a/lib/librte_efd/rte_efd.h b/lib/librte_efd/rte_efd.h
new file mode 100644
index 0000000..ede5acf
--- /dev/null
+++ b/lib/librte_efd/rte_efd.h
@@ -0,0 +1,312 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef __LIBEFD_H__
+#define __LIBEFD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_hash_crc.h>
+#include "rte_lcore.h"
+
+/*************************************************************************
+ * User selectable constants
+ *************************************************************************/
+
+/*
+ * If possible, best lookup performance will be achieved by ensuring that
+ * the entire table fits in the L3 cache.
+ *
+ * Some formulas for calculating various sizes are listed below:
+ *
+ * # of chunks =
+ * 2 ^ (ceiling(log2((requested # of rules) /
+ * (EFD_CHUNK_NUM_GROUPS * EFD_TARGET_GROUP_NUM_RULES))))
+ *
+ * Target # of rules = (# of chunks) * EFD_CHUNK_NUM_GROUPS *
+ * EFD_TARGET_GROUP_NUM_RULES
+ *
+ * Group Size (in bytes) = 4 (per value bit)
+ *
+ * Table size (in bytes) = EFD_VALUE_NUM_BITS * (# of chunks) *
+ * EFD_CHUNK_NUM_GROUPS * (group size)
+ */
+
+/**
+ * !!! This parameter should be adjusted for your application !!!
+ *
+ * This parameter adjusts the number of bits of value that can be
+ * stored in the table.
+ * For example, setting the number of bits to 3 will allow storing 8 values
+ * in the table (between 0 and 7).
+ *
+ * This number directly affects the performance of both lookups and insertion.
+ * In general, performance decreases as more bits are stored in the table.
+ *
+ * This number is directly proportional to the size of the online region
+ * used for lookups.
+ *
+ * Note that due to the way the CPU operates on memory, best lookup performance
+ * will be achieved when EFD_VALUE_NUM_BITS is a multiple of 8.
+ * These values align the hash indexes on 16-byte boundaries.
+ * The greatest performance drop is moving from 8->9 bits, 16->17 bits, etc.
+ *
+ * This value must be between 1 and 32
+ */
+#ifndef EFD_VALUE_NUM_BITS
+#define EFD_VALUE_NUM_BITS (8)
+#endif
+
+/**
+ * !!! This parameter should be adjusted for your application !!!
+ *
+ * This parameter adjusts the size of the keys stored in the table (in bytes).
+ * There are no restrictions around valid key sizes, and larger keys
+ * do not change the size of the online table used for lookups.
+ */
+#ifndef EFD_KEY_LEN
+#define EFD_KEY_LEN (4)
+#endif
+
+/*
+ * EFD_TARGET_GROUP_NUM_RULES:
+ * Adjusts how many groups/chunks are allocated at table creation time
+ * to support the requested number of rules. Higher values pack entries
+ * more tightly in memory, resulting in a smaller memory footprint
+ * for the online table.
+ * This comes at the cost of lower insert/update performance.
+ *
+ * EFD_MAX_GROUP_NUM_RULES:
+ * This adjusts the amount of offline memory allocated to store key/value
+ * pairs for the table. The recommended numbers are upper-bounds for
+ * this parameter
+ * - any higher and it becomes very unlikely that a perfect hash function
+ * can be found for that group size. This value should be at
+ * least 40% larger than EFD_TARGET_GROUP_NUM_RULES
+ *
+ * Recommended values for various lookuptable and hashfunc sizes are:
+ *
+ * HASH_FUNC_SIZE = 16, LOOKUPTBL_SIZE = 16:
+ * EFD_TARGET_GROUP_NUM_RULES = 22
+ * EFD_MAX_GROUP_NUM_RULES = 28
+ */
+#define EFD_TARGET_GROUP_NUM_RULES (22)
+#define EFD_MAX_GROUP_NUM_RULES (28)
+
+#define EFD_MIN_BALANCED_NUM_RULES 5
+
+/**
+ * Maximum number of keys that can be looked up in one call to efd_lookup_bulk
+ */
+#ifndef EFD_BURST_MAX
+#define EFD_BURST_MAX (32)
+#endif
+
+/** Maximum number of characters in efd name.*/
+#define RTE_EFD_NAMESIZE 32
+
+#if (EFD_VALUE_NUM_BITS > 0 && EFD_VALUE_NUM_BITS <= 8)
+typedef uint8_t efd_value_t;
+#elif (EFD_VALUE_NUM_BITS > 8 && EFD_VALUE_NUM_BITS <= 16)
+typedef uint16_t efd_value_t;
+#elif (EFD_VALUE_NUM_BITS > 16 && EFD_VALUE_NUM_BITS <= 32)
+typedef uint32_t efd_value_t;
+#else
+#error("EFD_VALUE_NUM_BITS must be in the range [1:32]")
+#endif
+
+#if (EFD_KEY_LEN <= 0)
+#error("EFD_KEY_LEN must be an integer greater than 0")
+#endif
+
+/* Variable size keys */
+typedef struct {
+ uint8_t bytes[EFD_KEY_LEN];
+} efd_key_t;
+
+/**
+ * Creates an EFD table with a single offline region and multiple per-socket
+ * internally-managed copies of the online table used for lookups
+ *
+ * @param name
+ * EFD table name
+ * @param max_num_rules
+ * Minimum number of rules the table should be sized to hold.
+ * Will be rounded up to the next smallest valid table size
+ * @param online_cpu_socket_bitmask
+ * Bitmask specifying which sockets should get a copy of the online table.
+ * LSB = socket 0, etc.
+ * @param offline_cpu_socket
+ * Identifies the socket where the offline table will be allocated
+ * (and most efficiently accessed in the case of updates/insertions)
+ *
+ * @return
+ * EFD table, or NULL if table allocation failed or the bitmask is invalid
+ */
+struct rte_efd_table *
+rte_efd_create(const char *name, uint32_t max_num_rules,
+ uint8_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket);
+
+/**
+ * Releases the resources from an EFD table
+ *
+ * @param table
+ * Table to free
+ */
+void
+rte_efd_free(struct rte_efd_table *table);
+
+/**
+ * Find an existing EFD table object and return a pointer to it.
+ *
+ * @param name
+ * Name of the EFD table as passed to rte_hash_create()
+ * @return
+ * Pointer to EFD table or NULL if object not found
+ * with rte_errno set appropriately. Possible rte_errno values include:
+ * - ENOENT - value not available for return
+ */
+struct rte_efd_table*
+rte_efd_find_existing(const char *name);
+
+#define EFD_UPDATE_WARN_GROUP_FULL (1)
+#define EFD_UPDATE_NO_CHANGE (2)
+#define EFD_UPDATE_FAILED (3)
+
+/**
+ * Computes an updated table entry for the supplied key/value pair.
+ * The update is then immediately applied to the provided table and
+ * all socket-local copies of the chunks are updated.
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param key
+ * EFD table key to modify
+ * @param value
+ * Value to associate with the key
+ *
+ * @return
+ * EFD_UPDATE_WARN_GROUP_FULL
+ * Operation is insert, and the last available space in the
+ * key's group was just used
+ * Future inserts may fail as groups fill up
+ * This operation was still successful, and entry contains a valid update
+ * EFD_UPDATE_FAILED
+ * Either the EFD failed to find a suitable perfect hash or the group was full
+ * This is a fatal error, and the table is now in an indeterminite state
+ * EFD_UPDATE_NO_CHANGE
+ * Operation resulted in no change to the table (same value already exists)
+ * 0 - success
+ */
+int
+rte_efd_update(struct rte_efd_table *table, unsigned int socket_id,
+ const efd_key_t *key, efd_value_t value);
+
+/**
+ * Removes any value currently associated with the specified key from the table
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param key
+ * EFD table key to delete
+ * @param prev_value
+ * If not NULL, will store the previous value here before deleting it
+ *
+ * @return
+ * 0 - successfully found and deleted the key
+ * nonzero otherwise
+ */
+int
+rte_efd_delete(struct rte_efd_table *table, unsigned int socket_id,
+ const efd_key_t *key, efd_value_t *prev_value);
+
+/**
+ * Looks up the value associated with a key
+ *
+ * NOTE: Lookups will *always* succeed - this is a property of
+ * using a perfect hash table.
+ * If the specified key was never inserted, a pseudorandom answer will be returned.
+ * There is no way to know based on the lookup if the key was ever inserted
+ * originally, so this must be tracked elsewhere.
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param key
+ * EFD table key to look up
+ *
+ * @return
+ * Value associated with the key, or random junk if they key was never inserted
+ */
+efd_value_t
+rte_efd_lookup(const struct rte_efd_table *table, unsigned int socket_id,
+ const efd_key_t *key);
+
+/**
+ * Looks up the value associated with several keys.
+ *
+ * NOTE: Lookups will *always* succeed - this is a property of
+ * using a perfect hash table.
+ * If the specified key was never inserted, a pseudorandom answer will be returned.
+ * There is no way to know based on the lookup if the key was ever inserted
+ * originally, so this must be tracked elsewhere.
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param num_keys
+ * Number of keys in the key_list array, must be less than EFD_BURST_MAX
+ * @param key_list
+ * Array of num_keys pointers which point to keys to look up
+ * @param value_list
+ * Array of size num_keys where lookup values will be stored
+ */
+void
+rte_efd_lookup_bulk(const struct rte_efd_table *table, unsigned int socket_id,
+ int num_keys, const efd_key_t *const *key_list,
+ efd_value_t *value_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LIBEFD_H__ */
+
diff --git a/lib/librte_efd/rte_efd_version.map b/lib/librte_efd/rte_efd_version.map
new file mode 100644
index 0000000..91810b3
--- /dev/null
+++ b/lib/librte_efd/rte_efd_version.map
@@ -0,0 +1,12 @@
+DPDK_17.02 {
+ global:
+
+ rte_efd_create;
+ rte_efd_delete;
+ rte_efd_free;
+ rte_efd_lookup;
+ rte_efd_lookup_bulk;
+ rte_efd_update;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f75f0e2..3956849 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -86,6 +86,7 @@ _LDLIBS-y += --whole-archive

_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
_LDLIBS-$(CONFIG_RTE_LIBRTE_HASH) += -lrte_hash
+_LDLIBS-$(CONFIG_RTE_LIBRTE_EFD) += -lrte_efd
_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lrte_vhost

_LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS) += -lrte_kvargs
--
2.7.4
Pablo de Lara
2016-12-02 14:52:20 UTC
Permalink
This new sample app, based on the client/server sample app,
shows the user an scenario using the EFD library.
It consists of:

- A front-end server which has an EFD table that stores the
node id for each flow key, which will distribute the incoming
packets to the different nodes

- A back-end node, which has a hash table where node checks,
after reading packets coming from the server, whether the packet
is meant to be used in such node, in which case it will be TXed,
or not, in which case, packet will be dropped.

Signed-off-by: Pablo de Lara <***@intel.com>
---
examples/Makefile | 1 +
examples/flow_distributor/Makefile | 44 +++
examples/flow_distributor/distributor/Makefile | 57 ++++
examples/flow_distributor/distributor/args.c | 200 ++++++++++++
examples/flow_distributor/distributor/args.h | 39 +++
examples/flow_distributor/distributor/init.c | 371 ++++++++++++++++++++++
examples/flow_distributor/distributor/init.h | 76 +++++
examples/flow_distributor/distributor/main.c | 362 +++++++++++++++++++++
examples/flow_distributor/node/Makefile | 48 +++
examples/flow_distributor/node/node.c | 417 +++++++++++++++++++++++++
examples/flow_distributor/shared/common.h | 99 ++++++
11 files changed, 1714 insertions(+)
create mode 100644 examples/flow_distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/args.c
create mode 100644 examples/flow_distributor/distributor/args.h
create mode 100644 examples/flow_distributor/distributor/init.c
create mode 100644 examples/flow_distributor/distributor/init.h
create mode 100644 examples/flow_distributor/distributor/main.c
create mode 100644 examples/flow_distributor/node/Makefile
create mode 100644 examples/flow_distributor/node/node.c
create mode 100644 examples/flow_distributor/shared/common.h

diff --git a/examples/Makefile b/examples/Makefile
index d49c7f2..b404982 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -45,6 +45,7 @@ DIRS-y += dpdk_qat
endif
DIRS-y += ethtool
DIRS-y += exception_path
+DIRS-$(CONFIG_RTE_LIBRTE_EFD) += flow_distributor
DIRS-y += helloworld
DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += ip_pipeline
ifeq ($(CONFIG_RTE_LIBRTE_LPM),y)
diff --git a/examples/flow_distributor/Makefile b/examples/flow_distributor/Makefile
new file mode 100644
index 0000000..d085e49
--- /dev/null
+++ b/examples/flow_distributor/Makefile
@@ -0,0 +1,44 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += distributor
+DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += node
+
+include $(RTE_SDK)/mk/rte.extsubdir.mk
diff --git a/examples/flow_distributor/distributor/Makefile b/examples/flow_distributor/distributor/Makefile
new file mode 100644
index 0000000..5a709ab
--- /dev/null
+++ b/examples/flow_distributor/distributor/Makefile
@@ -0,0 +1,57 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV), "linuxapp")
+$(error This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+endif
+
+# binary name
+APP = distributor
+
+# all source are stored in SRCS-y
+SRCS-y := main.c init.c args.c
+
+INC := $(wildcard *.h)
+
+CFLAGS += $(WERROR_FLAGS) -O3
+CFLAGS += -I$(SRCDIR)/../shared
+
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/flow_distributor/distributor/args.c b/examples/flow_distributor/distributor/args.c
new file mode 100644
index 0000000..3bd1ad6
--- /dev/null
+++ b/examples/flow_distributor/distributor/args.c
@@ -0,0 +1,200 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <rte_memory.h>
+#include <rte_string_fns.h>
+
+#include "common.h"
+#include "args.h"
+#include "init.h"
+
+/* 1M flows by default */
+#define DEFAULT_NUM_FLOWS 0x100000
+
+/* global var for number of nodes - extern in header */
+uint8_t num_nodes;
+/* global var for number of flows - extern in header */
+uint32_t num_flows = DEFAULT_NUM_FLOWS;
+
+static const char *progname;
+
+/**
+ * Prints out usage information to stdout
+ */
+static void
+usage(void)
+{
+ printf("%s [EAL options] -- -p PORTMASK -n NUM_NODES -f NUM_FLOWS\n"
+ " -p PORTMASK: hexadecimal bitmask of ports to use\n"
+ " -n NUM_NODES: number of node processes to use\n"
+ " -f NUM_FLOWS: number of flows to be added in the EFD table\n",
+ progname);
+}
+
+/**
+ * The ports to be used by the application are passed in
+ * the form of a bitmask. This function parses the bitmask
+ * and places the port numbers to be used into the port[]
+ * array variable
+ */
+static int
+parse_portmask(uint8_t max_ports, const char *portmask)
+{
+ char *end = NULL;
+ unsigned long pm;
+ uint8_t count = 0;
+
+ if (portmask == NULL || *portmask == '\0')
+ return -1;
+
+ /* convert parameter to a number and verify */
+ pm = strtoul(portmask, &end, 16);
+ if (end == NULL || *end != '\0' || pm == 0)
+ return -1;
+
+ /* loop through bits of the mask and mark ports */
+ while (pm != 0) {
+ if (pm & 0x01) { /* bit is set in mask, use port */
+ if (count >= max_ports)
+ printf("WARNING: requested port %u not present"
+ " - ignoring\n", (unsigned int)count);
+ else
+ info->id[info->num_ports++] = count;
+ }
+ pm = (pm >> 1);
+ count++;
+ }
+
+ return 0;
+}
+
+/**
+ * Take the number of nodes parameter passed to the app
+ * and convert to a number to store in the num_nodes variable
+ */
+static int
+parse_num_nodes(const char *nodes)
+{
+ char *end = NULL;
+ unsigned long temp;
+
+ if (nodes == NULL || *nodes == '\0')
+ return -1;
+
+ temp = strtoul(nodes, &end, 10);
+ if (end == NULL || *end != '\0' || temp == 0)
+ return -1;
+
+ num_nodes = (uint8_t)temp;
+ return 0;
+}
+
+static int
+parse_num_flows(const char *flows)
+{
+ char *end = NULL;
+
+ /* parse hexadecimal string */
+ num_flows = strtoul(flows, &end, 16);
+ if ((flows[0] == '\0') || (end == NULL) || (*end != '\0'))
+ return -1;
+
+ if (num_flows == 0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * The application specific arguments follow the DPDK-specific
+ * arguments which are stripped by the DPDK init. This function
+ * processes these application arguments, printing usage info
+ * on error.
+ */
+int
+parse_app_args(uint8_t max_ports, int argc, char *argv[])
+{
+ int option_index, opt;
+ char **argvopt = argv;
+ static struct option lgopts[] = { /* no long options */
+ {NULL, 0, 0, 0 }
+ };
+ progname = argv[0];
+
+ while ((opt = getopt_long(argc, argvopt, "n:f:p:", lgopts,
+ &option_index)) != EOF) {
+ switch (opt) {
+ case 'p':
+ if (parse_portmask(max_ports, optarg) != 0) {
+ usage();
+ return -1;
+ }
+ break;
+ case 'n':
+ if (parse_num_nodes(optarg) != 0) {
+ usage();
+ return -1;
+ }
+ break;
+ case 'f':
+ if (parse_num_flows(optarg) != 0) {
+ usage();
+ return -1;
+ }
+ break;
+ default:
+ printf("ERROR: Unknown option '%c'\n", opt);
+ usage();
+ return -1;
+ }
+ }
+
+ if (info->num_ports == 0 || num_nodes == 0) {
+ usage();
+ return -1;
+ }
+
+ if (info->num_ports % 2 != 0) {
+ printf("ERROR: application requires an even "
+ "number of ports to use\n");
+ return -1;
+ }
+ return 0;
+}
diff --git a/examples/flow_distributor/distributor/args.h b/examples/flow_distributor/distributor/args.h
new file mode 100644
index 0000000..8b36148
--- /dev/null
+++ b/examples/flow_distributor/distributor/args.h
@@ -0,0 +1,39 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef _ARGS_H_
+#define _ARGS_H_
+
+int parse_app_args(uint8_t max_ports, int argc, char *argv[]);
+
+#endif /* ifndef _ARGS_H_ */
diff --git a/examples/flow_distributor/distributor/init.c b/examples/flow_distributor/distributor/init.c
new file mode 100644
index 0000000..dff466c
--- /dev/null
+++ b/examples/flow_distributor/distributor/init.c
@@ -0,0 +1,371 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_byteorder.h>
+#include <rte_atomic.h>
+#include <rte_launch.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_branch_prediction.h>
+#include <rte_debug.h>
+#include <rte_ring.h>
+#include <rte_log.h>
+#include <rte_mempool.h>
+#include <rte_memcpy.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_cycles.h>
+#include <rte_efd.h>
+#include <rte_hash.h>
+
+#include "common.h"
+#include "args.h"
+#include "init.h"
+
+#define MBUFS_PER_NODE 1536
+#define MBUFS_PER_PORT 1536
+#define MBUF_CACHE_SIZE 512
+
+#define RTE_MP_RX_DESC_DEFAULT 512
+#define RTE_MP_TX_DESC_DEFAULT 512
+#define NODE_QUEUE_RINGSIZE 128
+
+#define NO_FLAGS 0
+
+/* The mbuf pool for packet rx */
+struct rte_mempool *pktmbuf_pool;
+
+/* array of info/queues for nodes */
+struct node *nodes;
+
+/* Flow distributor table */
+struct rte_efd_table *efd_table;
+
+/* Shared info between distributor and nodes */
+struct shared_info *info;
+
+/**
+ * Initialise the mbuf pool for packet reception for the NIC, and any other
+ * buffer pools needed by the app - currently none.
+ */
+static int
+init_mbuf_pools(void)
+{
+ const unsigned int num_mbufs = (num_nodes * MBUFS_PER_NODE) +
+ (info->num_ports * MBUFS_PER_PORT);
+
+ /*
+ * Don't pass single-producer/single-consumer flags to mbuf create as it
+ * seems faster to use a cache instead
+ */
+ printf("Creating mbuf pool '%s' [%u mbufs] ...\n",
+ PKTMBUF_POOL_NAME, num_mbufs);
+ pktmbuf_pool = rte_pktmbuf_pool_create(PKTMBUF_POOL_NAME, num_mbufs,
+ MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+
+ return pktmbuf_pool == NULL; /* 0 on success */
+}
+
+/**
+ * Initialise an individual port:
+ * - configure number of rx and tx rings
+ * - set up each rx ring, to pull from the main mbuf pool
+ * - set up each tx ring
+ * - start the port and report its status to stdout
+ */
+static int
+init_port(uint8_t port_num)
+{
+ /* for port configuration all features are off by default */
+ const struct rte_eth_conf port_conf = {
+ .rxmode = {
+ .mq_mode = ETH_MQ_RX_RSS
+ }
+ };
+ const uint16_t rx_rings = 1, tx_rings = num_nodes;
+ const uint16_t rx_ring_size = RTE_MP_RX_DESC_DEFAULT;
+ const uint16_t tx_ring_size = RTE_MP_TX_DESC_DEFAULT;
+
+ uint16_t q;
+ int retval;
+
+ printf("Port %u init ... ", (unsigned int)port_num);
+ fflush(stdout);
+
+ /*
+ * Standard DPDK port initialisation - config port, then set up
+ * rx and tx rings.
+ */
+ retval = rte_eth_dev_configure(port_num, rx_rings, tx_rings, &port_conf);
+ if (retval != 0)
+ return retval;
+
+ for (q = 0; q < rx_rings; q++) {
+ retval = rte_eth_rx_queue_setup(port_num, q, rx_ring_size,
+ rte_eth_dev_socket_id(port_num),
+ NULL, pktmbuf_pool);
+ if (retval < 0)
+ return retval;
+ }
+
+ for (q = 0; q < tx_rings; q++) {
+ retval = rte_eth_tx_queue_setup(port_num, q, tx_ring_size,
+ rte_eth_dev_socket_id(port_num),
+ NULL);
+ if (retval < 0)
+ return retval;
+ }
+
+ rte_eth_promiscuous_enable(port_num);
+
+ retval = rte_eth_dev_start(port_num);
+ if (retval < 0)
+ return retval;
+
+ printf("done:\n");
+
+ return 0;
+}
+
+/**
+ * Set up the DPDK rings which will be used to pass packets, via
+ * pointers, between the multi-process distributor and node processes.
+ * Each node needs one RX queue.
+ */
+static int
+init_shm_rings(void)
+{
+ unsigned int i;
+ unsigned int socket_id;
+ const char *q_name;
+ const unsigned int ringsize = NODE_QUEUE_RINGSIZE;
+
+ nodes = rte_malloc("node details",
+ sizeof(*nodes) * num_nodes, 0);
+ if (nodes == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot allocate memory for "
+ "node program details\n");
+
+ for (i = 0; i < num_nodes; i++) {
+ /* Create an RX queue for each node */
+ socket_id = rte_socket_id();
+ q_name = get_rx_queue_name(i);
+ nodes[i].rx_q = rte_ring_create(q_name,
+ ringsize, socket_id,
+ RING_F_SP_ENQ | RING_F_SC_DEQ);
+ if (nodes[i].rx_q == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot create rx ring queue "
+ "for node %u\n", i);
+ }
+ return 0;
+}
+
+/*
+ * Create flow distributor table which will contain all the flows
+ * that will be distributed among the nodes
+ */
+static void
+create_flow_distributor_table(void)
+{
+ uint8_t socket_id = rte_socket_id();
+
+ /* create table */
+ efd_table = rte_efd_create("flow table", num_flows * 2, 1 << socket_id,
+ socket_id);
+
+ if (efd_table == NULL)
+ rte_exit(EXIT_FAILURE, "Problem creating the flow table\n");
+}
+
+static void
+populate_flow_distributor_table(void)
+{
+ unsigned int i;
+ int32_t ret;
+ uint32_t ip_dst;
+ uint8_t socket_id = rte_socket_id();
+ uint64_t node_id;
+
+ /* Add flows in tables */
+ for (i = 0; i < num_flows; i++) {
+ node_id = i % num_nodes;
+
+ ip_dst = rte_cpu_to_be_32(i);
+ ret = rte_efd_update(efd_table, socket_id,
+ (efd_key_t *)&ip_dst, (efd_value_t)node_id);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Unable to add entry %u in "
+ "flow distributor table\n", i);
+ }
+
+ printf("EFD table: Adding 0x%x keys\n", num_flows);
+}
+
+/* Check the link status of all ports in up to 9s, and print them finally */
+static void
+check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
+ uint8_t portid, count, all_ports_up, print_flag = 0;
+ struct rte_eth_link link;
+
+ printf("\nChecking link status");
+ fflush(stdout);
+ for (count = 0; count <= MAX_CHECK_TIME; count++) {
+ all_ports_up = 1;
+ for (portid = 0; portid < port_num; portid++) {
+ if ((port_mask & (1 << info->id[portid])) == 0)
+ continue;
+ memset(&link, 0, sizeof(link));
+ rte_eth_link_get_nowait(info->id[portid], &link);
+ /* print link status if flag set */
+ if (print_flag == 1) {
+ if (link.link_status)
+ printf("Port %d Link Up - speed %u "
+ "Mbps - %s\n", info->id[portid],
+ (unsigned int)link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ else
+ printf("Port %d Link Down\n",
+ (uint8_t)info->id[portid]);
+ continue;
+ }
+ /* clear all_ports_up flag if any link down */
+ if (link.link_status == ETH_LINK_DOWN) {
+ all_ports_up = 0;
+ break;
+ }
+ }
+ /* after finally printing all link status, get out */
+ if (print_flag == 1)
+ break;
+
+ if (all_ports_up == 0) {
+ printf(".");
+ fflush(stdout);
+ rte_delay_ms(CHECK_INTERVAL);
+ }
+
+ /* set the print_flag if all ports up or timeout */
+ if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
+ print_flag = 1;
+ printf("done\n");
+ }
+ }
+}
+
+/**
+ * Main init function for the multi-process distributor app,
+ * calls subfunctions to do each stage of the initialisation.
+ */
+int
+init(int argc, char *argv[])
+{
+ int retval;
+ const struct rte_memzone *mz;
+ uint8_t i, total_ports;
+
+ /* init EAL, parsing EAL args */
+ retval = rte_eal_init(argc, argv);
+ if (retval < 0)
+ return -1;
+ argc -= retval;
+ argv += retval;
+
+ /* get total number of ports */
+ total_ports = rte_eth_dev_count();
+
+ /* set up array for port data */
+ mz = rte_memzone_reserve(MZ_SHARED_INFO, sizeof(*info),
+ rte_socket_id(), NO_FLAGS);
+ if (mz == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot reserve memory zone "
+ "for port information\n");
+ memset(mz->addr, 0, sizeof(*info));
+ info = mz->addr;
+
+ /* parse additional, application arguments */
+ retval = parse_app_args(total_ports, argc, argv);
+ if (retval != 0)
+ return -1;
+
+ /* initialise mbuf pools */
+ retval = init_mbuf_pools();
+ if (retval != 0)
+ rte_exit(EXIT_FAILURE, "Cannot create needed mbuf pools\n");
+
+ /* now initialise the ports we will use */
+ for (i = 0; i < info->num_ports; i++) {
+ retval = init_port(info->id[i]);
+ if (retval != 0)
+ rte_exit(EXIT_FAILURE, "Cannot initialise port %u\n",
+ (unsigned int) i);
+ }
+
+ check_all_ports_link_status(info->num_ports, (~0x0));
+
+ /* initialise the node queues/rings for inter-eu comms */
+ init_shm_rings();
+
+ /* Create the flow distributor table */
+ create_flow_distributor_table();
+
+ /* Populate the flow distributor table */
+ populate_flow_distributor_table();
+
+ /* Share the total number of nodes */
+ info->num_nodes = num_nodes;
+
+ /* Share the total number of flows */
+ info->num_flows = num_flows;
+ return 0;
+}
diff --git a/examples/flow_distributor/distributor/init.h b/examples/flow_distributor/distributor/init.h
new file mode 100644
index 0000000..ea0c0d4
--- /dev/null
+++ b/examples/flow_distributor/distributor/init.h
@@ -0,0 +1,76 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef _INIT_H_
+#define _INIT_H_
+
+/*
+ * #include <rte_ring.h>
+ * #include "args.h"
+ */
+
+/*
+ * Define a node structure with all needed info, including
+ * stats from the nodes.
+ */
+struct node {
+ struct rte_ring *rx_q;
+ unsigned int node_id;
+ /* these stats hold how many packets the node will actually receive,
+ * and how many packets were dropped because the node's queue was full.
+ * The port-info stats, in contrast, record how many packets were received
+ * or transmitted on an actual NIC port.
+ */
+ struct {
+ uint64_t rx;
+ uint64_t rx_drop;
+ } stats;
+};
+
+extern struct rte_efd_table *efd_table;
+extern struct node *nodes;
+
+/*
+ * shared information between distributor and nodes: number of clients,
+ * port numbers, rx and tx stats etc.
+ */
+extern struct shared_info *info;
+
+extern struct rte_mempool *pktmbuf_pool;
+extern uint8_t num_nodes;
+extern unsigned int num_sockets;
+extern uint32_t num_flows;
+
+int init(int argc, char *argv[]);
+
+#endif /* ifndef _INIT_H_ */
diff --git a/examples/flow_distributor/distributor/main.c b/examples/flow_distributor/distributor/main.c
new file mode 100644
index 0000000..efe6960
--- /dev/null
+++ b/examples/flow_distributor/distributor/main.c
@@ -0,0 +1,362 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <inttypes.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <netinet/ip.h>
+
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_byteorder.h>
+#include <rte_launch.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_branch_prediction.h>
+#include <rte_atomic.h>
+#include <rte_ring.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_mempool.h>
+#include <rte_memcpy.h>
+#include <rte_mbuf.h>
+#include <rte_ether.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ethdev.h>
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_efd.h>
+#include <rte_ip.h>
+
+#include "common.h"
+#include "args.h"
+#include "init.h"
+
+/*
+ * When doing reads from the NIC or the node queues,
+ * use this batch size
+ */
+#define PACKET_READ_SIZE 32
+
+/*
+ * Local buffers to put packets in, used to send packets in bursts to the
+ * nodes
+ */
+struct node_rx_buf {
+ struct rte_mbuf *buffer[PACKET_READ_SIZE];
+ uint16_t count;
+};
+
+struct flow_distributor_stats {
+ uint64_t distributed;
+ uint64_t drop;
+} flow_dist_stats;
+
+/* One buffer per node rx queue - dynamically allocate array */
+static struct node_rx_buf *cl_rx_buf;
+
+static const char *
+get_printable_mac_addr(uint8_t port)
+{
+ static const char err_address[] = "00:00:00:00:00:00";
+ static char addresses[RTE_MAX_ETHPORTS][sizeof(err_address)];
+ struct ether_addr mac;
+
+ if (unlikely(port >= RTE_MAX_ETHPORTS))
+ return err_address;
+ if (unlikely(addresses[port][0] == '\0')) {
+ rte_eth_macaddr_get(port, &mac);
+ snprintf(addresses[port], sizeof(addresses[port]),
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac.addr_bytes[0], mac.addr_bytes[1],
+ mac.addr_bytes[2], mac.addr_bytes[3],
+ mac.addr_bytes[4], mac.addr_bytes[5]);
+ }
+ return addresses[port];
+}
+
+/*
+ * This function displays the recorded statistics for each port
+ * and for each node. It uses ANSI terminal codes to clear
+ * screen when called. It is called from a single non-master
+ * thread in the distributor process, when the process is run with more
+ * than one lcore enabled.
+ */
+static void
+do_stats_display(void)
+{
+ unsigned int i, j;
+ const char clr[] = {27, '[', '2', 'J', '\0'};
+ const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'};
+ uint64_t port_tx[RTE_MAX_ETHPORTS], port_tx_drop[RTE_MAX_ETHPORTS];
+ uint64_t node_tx[MAX_NODES], node_tx_drop[MAX_NODES];
+
+ /* to get TX stats, we need to do some summing calculations */
+ memset(port_tx, 0, sizeof(port_tx));
+ memset(port_tx_drop, 0, sizeof(port_tx_drop));
+ memset(node_tx, 0, sizeof(node_tx));
+ memset(node_tx_drop, 0, sizeof(node_tx_drop));
+
+ for (i = 0; i < num_nodes; i++) {
+ const struct tx_stats *tx = &info->tx_stats[i];
+
+ for (j = 0; j < info->num_ports; j++) {
+ const uint64_t tx_val = tx->tx[info->id[j]];
+ const uint64_t drop_val = tx->tx_drop[info->id[j]];
+
+ port_tx[j] += tx_val;
+ port_tx_drop[j] += drop_val;
+ node_tx[i] += tx_val;
+ node_tx_drop[i] += drop_val;
+ }
+ }
+
+ /* Clear screen and move to top left */
+ printf("%s%s", clr, topLeft);
+
+ printf("PORTS\n");
+ printf("-----\n");
+ for (i = 0; i < info->num_ports; i++)
+ printf("Port %u: '%s'\t", (unsigned int)info->id[i],
+ get_printable_mac_addr(info->id[i]));
+ printf("\n\n");
+ for (i = 0; i < info->num_ports; i++) {
+ printf("Port %u - rx: %9"PRIu64"\t"
+ "tx: %9"PRIu64"\n",
+ (unsigned int)info->id[i], info->rx_stats.rx[i],
+ port_tx[i]);
+ }
+
+ printf("\nFLOW DISTRIBUTOR\n");
+ printf("-----\n");
+ printf("distributed: %9"PRIu64", drop: %9"PRIu64"\n",
+ flow_dist_stats.distributed, flow_dist_stats.drop);
+
+ printf("\nNODES\n");
+ printf("-------\n");
+ for (i = 0; i < num_nodes; i++) {
+ const unsigned long long rx = nodes[i].stats.rx;
+ const unsigned long long rx_drop = nodes[i].stats.rx_drop;
+ const struct filter_stats *filter = &info->filter_stats[i];
+
+ printf("Node %2u - rx: %9llu, rx_drop: %9llu\n"
+ " tx: %9"PRIu64", tx_drop: %9"PRIu64"\n"
+ " filter_passed: %9"PRIu64", "
+ "filter_drop: %9"PRIu64"\n",
+ i, rx, rx_drop, node_tx[i], node_tx_drop[i],
+ filter->passed, filter->drop);
+ }
+
+ printf("\n");
+}
+
+/*
+ * The function called from each non-master lcore used by the process.
+ * The test_and_set function is used to randomly pick a single lcore on which
+ * the code to display the statistics will run. Otherwise, the code just
+ * repeatedly sleeps.
+ */
+static int
+sleep_lcore(__attribute__((unused)) void *dummy)
+{
+ /* Used to pick a display thread - static, so zero-initialised */
+ static rte_atomic32_t display_stats;
+
+ /* Only one core should display stats */
+ if (rte_atomic32_test_and_set(&display_stats)) {
+ const unsigned int sleeptime = 1;
+
+ printf("Core %u displaying statistics\n", rte_lcore_id());
+
+ /* Longer initial pause so above printf is seen */
+ sleep(sleeptime * 3);
+
+ /* Loop forever: sleep always returns 0 or <= param */
+ while (sleep(sleeptime) <= sleeptime)
+ do_stats_display();
+ }
+ return 0;
+}
+
+/*
+ * Function to set all the node statistic values to zero.
+ * Called at program startup.
+ */
+static void
+clear_stats(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_nodes; i++)
+ nodes[i].stats.rx = nodes[i].stats.rx_drop = 0;
+}
+
+/*
+ * send a burst of traffic to a node, assuming there are packets
+ * available to be sent to this node
+ */
+static void
+flush_rx_queue(uint16_t node)
+{
+ uint16_t j;
+ struct node *cl;
+
+ if (cl_rx_buf[node].count == 0)
+ return;
+
+ cl = &nodes[node];
+ if (rte_ring_enqueue_bulk(cl->rx_q, (void **)cl_rx_buf[node].buffer,
+ cl_rx_buf[node].count) != 0){
+ for (j = 0; j < cl_rx_buf[node].count; j++)
+ rte_pktmbuf_free(cl_rx_buf[node].buffer[j]);
+ cl->stats.rx_drop += cl_rx_buf[node].count;
+ } else
+ cl->stats.rx += cl_rx_buf[node].count;
+
+ cl_rx_buf[node].count = 0;
+}
+
+/*
+ * marks a packet down to be sent to a particular node process
+ */
+static inline void
+enqueue_rx_packet(uint8_t node, struct rte_mbuf *buf)
+{
+ cl_rx_buf[node].buffer[cl_rx_buf[node].count++] = buf;
+}
+
+/*
+ * This function takes a group of packets and routes them
+ * individually to the node process. Very simply round-robins the packets
+ * without checking any of the packet contents.
+ */
+static void
+process_packets(uint32_t port_num __rte_unused, struct rte_mbuf *pkts[],
+ uint16_t rx_count, unsigned int socket_id)
+{
+ uint16_t i;
+ uint8_t node;
+ efd_value_t data[EFD_BURST_MAX];
+ const efd_key_t *key_ptrs[EFD_BURST_MAX];
+
+ struct ipv4_hdr *ipv4_hdr;
+ uint32_t ipv4_dst_ip[EFD_BURST_MAX];
+
+ for (i = 0; i < rx_count; i++) {
+ /* Handle IPv4 header.*/
+ ipv4_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct ipv4_hdr *,
+ sizeof(struct ether_hdr));
+ ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
+ key_ptrs[i] = (efd_key_t *)&ipv4_dst_ip[i];
+ }
+
+ rte_efd_lookup_bulk(efd_table, socket_id, rx_count,
+ (const efd_key_t **) key_ptrs, data);
+ for (i = 0; i < rx_count; i++) {
+ node = (uint8_t) ((uintptr_t)data[i]);
+
+ if (node >= num_nodes) {
+ /*
+ * Node is out of range, which means that
+ * flow has not been inserted
+ */
+ flow_dist_stats.drop++;
+ rte_pktmbuf_free(pkts[i]);
+ } else {
+ flow_dist_stats.distributed++;
+ enqueue_rx_packet(node, pkts[i]);
+ }
+ }
+
+ for (i = 0; i < num_nodes; i++)
+ flush_rx_queue(i);
+}
+
+/*
+ * Function called by the master lcore of the DPDK process.
+ */
+static void
+do_packet_forwarding(void)
+{
+ unsigned int port_num = 0; /* indexes the port[] array */
+ unsigned int socket_id = rte_socket_id();
+
+ for (;;) {
+ struct rte_mbuf *buf[PACKET_READ_SIZE];
+ uint16_t rx_count;
+
+ /* read a port */
+ rx_count = rte_eth_rx_burst(info->id[port_num], 0,
+ buf, PACKET_READ_SIZE);
+ info->rx_stats.rx[port_num] += rx_count;
+
+ /* Now process the NIC packets read */
+ if (likely(rx_count > 0))
+ process_packets(port_num, buf, rx_count, socket_id);
+
+ /* move to next port */
+ if (++port_num == info->num_ports)
+ port_num = 0;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ /* initialise the system */
+ if (init(argc, argv) < 0)
+ return -1;
+ RTE_LOG(INFO, APP, "Finished Process Init.\n");
+
+ cl_rx_buf = calloc(num_nodes, sizeof(cl_rx_buf[0]));
+
+ /* clear statistics */
+ clear_stats();
+
+ /* put all other cores to sleep bar master */
+ rte_eal_mp_remote_launch(sleep_lcore, NULL, SKIP_MASTER);
+
+ do_packet_forwarding();
+ return 0;
+}
diff --git a/examples/flow_distributor/node/Makefile b/examples/flow_distributor/node/Makefile
new file mode 100644
index 0000000..59aac28
--- /dev/null
+++ b/examples/flow_distributor/node/Makefile
@@ -0,0 +1,48 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# binary name
+APP = node
+
+# all source are stored in SRCS-y
+SRCS-y := node.c
+
+CFLAGS += $(WERROR_FLAGS) -O3
+CFLAGS += -I$(SRCDIR)/../shared
+
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/flow_distributor/node/node.c b/examples/flow_distributor/node/node.c
new file mode 100644
index 0000000..e68f252
--- /dev/null
+++ b/examples/flow_distributor/node/node.c
@@ -0,0 +1,417 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_log.h>
+#include <rte_per_lcore.h>
+#include <rte_launch.h>
+#include <rte_lcore.h>
+#include <rte_ring.h>
+#include <rte_launch.h>
+#include <rte_lcore.h>
+#include <rte_debug.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+#include <rte_ip.h>
+
+#include "common.h"
+
+/* Number of packets to attempt to read from queue */
+#define PKT_READ_SIZE ((uint16_t)32)
+
+/*
+ * Our node id number - tells us which rx queue to read, and NIC TX
+ * queue to write to.
+ */
+static uint8_t node_id;
+
+#define MBQ_CAPACITY 32
+
+/* maps input ports to output ports for packets */
+static uint8_t output_ports[RTE_MAX_ETHPORTS];
+
+/* buffers up a set of packet that are ready to send */
+struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
+
+/* shared data from distributor. We update statistics here */
+static struct tx_stats *tx_stats;
+
+static struct filter_stats *filter_stats;
+
+/*
+ * print a usage message
+ */
+static void
+usage(const char *progname)
+{
+ printf("Usage: %s [EAL args] -- -n <node_id>\n\n", progname);
+}
+
+/*
+ * Convert the node id number from a string to an int.
+ */
+static int
+parse_node_num(const char *node)
+{
+ char *end = NULL;
+ unsigned long temp;
+
+ if (node == NULL || *node == '\0')
+ return -1;
+
+ temp = strtoul(node, &end, 10);
+ if (end == NULL || *end != '\0')
+ return -1;
+
+ node_id = (uint8_t)temp;
+ return 0;
+}
+
+/*
+ * Parse the application arguments to the node app.
+ */
+static int
+parse_app_args(int argc, char *argv[])
+{
+ int option_index, opt;
+ char **argvopt = argv;
+ const char *progname = NULL;
+ static struct option lgopts[] = { /* no long options */
+ {NULL, 0, 0, 0 }
+ };
+ progname = argv[0];
+
+ while ((opt = getopt_long(argc, argvopt, "n:", lgopts,
+ &option_index)) != EOF) {
+ switch (opt) {
+ case 'n':
+ if (parse_node_num(optarg) != 0) {
+ usage(progname);
+ return -1;
+ }
+ break;
+ default:
+ usage(progname);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Tx buffer error callback
+ */
+static void
+flush_tx_error_callback(struct rte_mbuf **unsent, uint16_t count,
+ void *userdata) {
+ int i;
+ uint8_t port_id = (uintptr_t)userdata;
+
+ tx_stats->tx_drop[port_id] += count;
+
+ /* free the mbufs which failed from transmit */
+ for (i = 0; i < count; i++)
+ rte_pktmbuf_free(unsent[i]);
+
+}
+
+static void
+configure_tx_buffer(uint8_t port_id, uint16_t size)
+{
+ int ret;
+
+ /* Initialize TX buffers */
+ tx_buffer[port_id] = rte_zmalloc_socket("tx_buffer",
+ RTE_ETH_TX_BUFFER_SIZE(size), 0,
+ rte_eth_dev_socket_id(port_id));
+ if (tx_buffer[port_id] == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx "
+ "on port %u\n", (unsigned int) port_id);
+
+ rte_eth_tx_buffer_init(tx_buffer[port_id], size);
+
+ ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[port_id],
+ flush_tx_error_callback, (void *)(intptr_t)port_id);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Cannot set error callback for "
+ "tx buffer on port %u\n", (unsigned int) port_id);
+}
+
+/*
+ * set up output ports so that all traffic on port gets sent out
+ * its paired port. Index using actual port numbers since that is
+ * what comes in the mbuf structure.
+ */
+static void
+configure_output_ports(const struct shared_info *info)
+{
+ int i;
+
+ if (info->num_ports > RTE_MAX_ETHPORTS)
+ rte_exit(EXIT_FAILURE, "Too many ethernet ports. "
+ "RTE_MAX_ETHPORTS = %u\n",
+ (unsigned int)RTE_MAX_ETHPORTS);
+ for (i = 0; i < info->num_ports - 1; i += 2) {
+ uint8_t p1 = info->id[i];
+ uint8_t p2 = info->id[i+1];
+
+ output_ports[p1] = p2;
+ output_ports[p2] = p1;
+
+ configure_tx_buffer(p1, MBQ_CAPACITY);
+ configure_tx_buffer(p2, MBQ_CAPACITY);
+
+ }
+}
+
+/*
+ * Create the hash table that will contain the flows that
+ * the node will handle, which will be used to decide if packet
+ * is transmitted or dropped.
+ */
+static struct rte_hash *
+create_hash_table(const struct shared_info *info)
+{
+ uint32_t num_flows_node = info->num_flows / info->num_nodes;
+ char name[RTE_HASH_NAMESIZE];
+ struct rte_hash *h;
+
+ /* create table */
+ struct rte_hash_parameters hash_params = {
+ .entries = num_flows_node * 2, /* table load = 50% */
+ .key_len = sizeof(uint32_t), /* Store IPv4 dest IP address */
+ .socket_id = rte_socket_id(),
+ .hash_func_init_val = 0,
+ };
+
+ snprintf(name, sizeof(name), "hash_table_%d", node_id);
+ hash_params.name = name;
+ h = rte_hash_create(&hash_params);
+
+ if (h == NULL)
+ rte_exit(EXIT_FAILURE,
+ "Problem creating the hash table for node %d\n",
+ node_id);
+ return h;
+}
+
+static void
+populate_hash_table(const struct rte_hash *h, const struct shared_info *info)
+{
+ unsigned int i;
+ int32_t ret;
+ uint32_t ip_dst;
+ uint32_t num_flows_node = 0;
+ uint64_t target_node;
+
+ /* Add flows in table */
+ for (i = 0; i < info->num_flows; i++) {
+ target_node = i % info->num_nodes;
+ if (target_node != node_id)
+ continue;
+
+ ip_dst = rte_cpu_to_be_32(i);
+
+ ret = rte_hash_add_key(h, (void *) &ip_dst);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Unable to add entry %u "
+ "in hash table\n", i);
+ else
+ num_flows_node++;
+
+ }
+
+ printf("Hash table: Adding 0x%x keys\n", num_flows_node);
+}
+
+/*
+ * This function performs routing of packets
+ * Just sends each input packet out an output port based solely on the input
+ * port it arrived on.
+ */
+static inline void
+transmit_packet(struct rte_mbuf *buf)
+{
+ int sent;
+ const uint8_t in_port = buf->port;
+ const uint8_t out_port = output_ports[in_port];
+ struct rte_eth_dev_tx_buffer *buffer = tx_buffer[out_port];
+
+ sent = rte_eth_tx_buffer(out_port, node_id, buffer, buf);
+ if (sent)
+ tx_stats->tx[out_port] += sent;
+
+}
+
+static inline int
+handle_packets(struct rte_hash *h, struct rte_mbuf **bufs, uint16_t num_packets)
+{
+ struct ipv4_hdr *ipv4_hdr;
+ uint32_t ipv4_dst_ip[PKT_READ_SIZE];
+ const void *key_ptrs[PKT_READ_SIZE];
+ unsigned int i;
+ int32_t positions[PKT_READ_SIZE] = {0};
+
+ for (i = 0; i < num_packets; i++) {
+ /* Handle IPv4 header.*/
+ ipv4_hdr = rte_pktmbuf_mtod_offset(bufs[i], struct ipv4_hdr *,
+ sizeof(struct ether_hdr));
+ ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
+ key_ptrs[i] = &ipv4_dst_ip[i];
+ }
+ /* Check if packets belongs to any flows handled by this node */
+ rte_hash_lookup_bulk(h, key_ptrs, num_packets, positions);
+
+ for (i = 0; i < num_packets; i++) {
+ if (likely(positions[i] >= 0)) {
+ filter_stats->passed++;
+ transmit_packet(bufs[i]);
+ } else {
+ filter_stats->drop++;
+ /* Drop packet, as flow is not handled by this node */
+ rte_pktmbuf_free(bufs[i]);
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Application main function - loops through
+ * receiving and processing packets. Never returns
+ */
+int
+main(int argc, char *argv[])
+{
+ const struct rte_memzone *mz;
+ struct rte_ring *rx_ring;
+ struct rte_hash *h;
+ struct rte_mempool *mp;
+ struct shared_info *info;
+ int need_flush = 0; /* indicates whether we have unsent packets */
+ int retval;
+ void *pkts[PKT_READ_SIZE];
+ uint16_t sent;
+
+ retval = rte_eal_init(argc, argv);
+ if (retval < 0)
+ return -1;
+ argc -= retval;
+ argv += retval;
+
+ if (parse_app_args(argc, argv) < 0)
+ rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n");
+
+ if (rte_eth_dev_count() == 0)
+ rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
+
+ rx_ring = rte_ring_lookup(get_rx_queue_name(node_id));
+ if (rx_ring == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get RX ring - "
+ "is distributor process running?\n");
+
+ mp = rte_mempool_lookup(PKTMBUF_POOL_NAME);
+ if (mp == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n");
+
+ mz = rte_memzone_lookup(MZ_SHARED_INFO);
+ if (mz == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get port info structure\n");
+ info = mz->addr;
+ tx_stats = &(info->tx_stats[node_id]);
+ filter_stats = &(info->filter_stats[node_id]);
+
+ configure_output_ports(info);
+
+ h = create_hash_table(info);
+
+ populate_hash_table(h, info);
+
+ RTE_LOG(INFO, APP, "Finished Process Init.\n");
+
+ printf("\nNode process %d handling packets\n", node_id);
+ printf("[Press Ctrl-C to quit ...]\n");
+
+ for (;;) {
+ uint16_t rx_pkts = PKT_READ_SIZE;
+ uint8_t port;
+
+ /*
+ * Try dequeuing max possible packets first, if that fails,
+ * get the most we can. Loop body should only execute once,
+ * maximum
+ */
+ while (rx_pkts > 0 &&
+ unlikely(rte_ring_dequeue_bulk(rx_ring, pkts,
+ rx_pkts) != 0))
+ rx_pkts = (uint16_t)RTE_MIN(rte_ring_count(rx_ring),
+ PKT_READ_SIZE);
+
+ if (unlikely(rx_pkts == 0)) {
+ if (need_flush)
+ for (port = 0; port < info->num_ports; port++) {
+ sent = rte_eth_tx_buffer_flush(info->id[port],
+ node_id, tx_buffer[port]);
+ if (unlikely(sent))
+ tx_stats->tx[port] += sent;
+ }
+ need_flush = 0;
+ continue;
+ }
+
+ handle_packets(h, (struct rte_mbuf **)pkts, rx_pkts);
+
+ need_flush = 1;
+ }
+}
diff --git a/examples/flow_distributor/shared/common.h b/examples/flow_distributor/shared/common.h
new file mode 100644
index 0000000..66c5574
--- /dev/null
+++ b/examples/flow_distributor/shared/common.h
@@ -0,0 +1,99 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <rte_hash_crc.h>
+#include <rte_hash.h>
+
+#define MAX_NODES 16
+/*
+ * Shared port info, including statistics information for display by distributor.
+ * Structure will be put in a memzone.
+ * - All port id values share one cache line as this data will be read-only
+ * during operation.
+ * - All rx statistic values share cache lines, as this data is written only
+ * by the distributor process. (rare reads by stats display)
+ * - The tx statistics have values for all ports per cache line, but the stats
+ * themselves are written by the nodes, so we have a distinct set, on different
+ * cache lines for each node to use.
+ */
+struct rx_stats {
+ uint64_t rx[RTE_MAX_ETHPORTS];
+} __rte_cache_aligned;
+
+struct tx_stats {
+ uint64_t tx[RTE_MAX_ETHPORTS];
+ uint64_t tx_drop[RTE_MAX_ETHPORTS];
+} __rte_cache_aligned;
+
+struct filter_stats {
+ uint64_t drop;
+ uint64_t passed;
+} __rte_cache_aligned;
+
+struct shared_info {
+ uint8_t num_nodes;
+ uint8_t num_ports;
+ uint32_t num_flows;
+ uint8_t id[RTE_MAX_ETHPORTS];
+ struct rx_stats rx_stats;
+ struct tx_stats tx_stats[MAX_NODES];
+ struct filter_stats filter_stats[MAX_NODES];
+};
+
+/* define common names for structures shared between distributor and node */
+#define MP_NODE_RXQ_NAME "MProc_Node_%u_RX"
+#define PKTMBUF_POOL_NAME "MProc_pktmbuf_pool"
+#define MZ_SHARED_INFO "MProc_shared_info"
+
+/*
+ * Given the rx queue name template above, get the queue name
+ */
+static inline const char *
+get_rx_queue_name(unsigned int id)
+{
+ /*
+ * Buffer for return value. Size calculated by %u being replaced
+ * by maximum 3 digits (plus an extra byte for safety)
+ */
+ static char buffer[sizeof(MP_NODE_RXQ_NAME) + 2];
+
+ snprintf(buffer, sizeof(buffer) - 1, MP_NODE_RXQ_NAME, id);
+ return buffer;
+}
+
+#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
+
+#endif
--
2.7.4
Pablo de Lara
2017-01-07 01:06:01 UTC
Permalink
EFD is a distributor library that uses perfect hashing to determine a
target/value for a given incoming flow key. It has the following advantages:
first, because it uses perfect hashing it does not store the key itself and
hence lookup performance is not dependent on the key size. Second, the
target/value can be any arbitrary value hence the system designer and/or
operator can better optimize service rates and inter-cluster network traffic
locating. Third, since the storage requirement is much smaller than a
hash-based flow table (i.e. better fit for CPU cache), EFD can scale to millions
of flow keys. Finally, with current optimized library implementation performance
is fully scalable with number of CPU cores.

The basic idea of EFD is when a given key is to be inserted, a family of hash
functions is searched until the correct hash function that maps the input key to
the correct value is found. However, rather than explicitly storing all keys and
their associated values, EFD stores only indices of hash functions that map keys
to values, and thereby consumes much less space than conventional flow-based
tables. The lookup operation is very simple, similar to computational-based
scheme, given an input key the lookup operation is reduced to hashing that key
with the correct hash function.

Intuitively, finding a hash function that maps each of a large number (millions)
of input keys to the correct output value is effectively impossible, as a result
EFD, breaks the problem into smaller pieces (divide and conquer). EFD divides
the entire input key set into many small groups. Each group consists of
approximately 20-28 keys (a configurable parameter for the library), then, for
each small group, a brute force search to find a hash function that produces the
correct outputs for each key in the group.
It should be mentioned that since in the online lookup table for EFD doesn’t
store the key itself, the size of the EFD table is independent of the key size
and hence EFD lookup performance which is almost constant irrespective of the
length of the key which is a highly desirable feature especially for longer
keys.

Library code is included in the patch, plus an sample application that shows
how the library can be used.

RFC for this library was already sent:
http://dpdk.org/ml/archives/dev/2016-October/049238.html

For more information on the library, check out the following document:
https://github.com/pablodelara/perfect_hash_flow_distributor/blob/master/EFD_description.pdf

Changes in v2:

- Added documentation for library and sample app
- Fixed checkpatch errors/warnings
- Added functional and performance tests
- Made key size variable at runtime
- Made code multi-architecture compatible at runtime


Pablo de Lara (5):
efd: new Elastic Flow Distributor library
app/test: add EFD functional and perf tests
examples/flow_distributor: sample app to demonstrate EFD usage
doc: add EFD library section in Programmers guide
doc: add flow distributor guide

MAINTAINERS | 9 +
app/test/Makefile | 3 +
app/test/test_efd.c | 494 ++++++++
app/test/test_efd_perf.c | 407 ++++++
config/common_base | 5 +
doc/api/doxy-api-index.md | 3 +-
doc/api/doxy-api.conf | 1 +
doc/api/examples.dox | 4 +
doc/guides/prog_guide/efd_lib.rst | 413 ++++++
doc/guides/prog_guide/img/efd_i1.svg | 78 ++
doc/guides/prog_guide/img/efd_i10.svg | 1272 +++++++++++++++++++
doc/guides/prog_guide/img/efd_i11.svg | 413 ++++++
doc/guides/prog_guide/img/efd_i12.svg | 590 +++++++++
doc/guides/prog_guide/img/efd_i13.svg | 1407 +++++++++++++++++++++
doc/guides/prog_guide/img/efd_i2.svg | 209 +++
doc/guides/prog_guide/img/efd_i3.svg | 420 ++++++
doc/guides/prog_guide/img/efd_i4.svg | 364 ++++++
doc/guides/prog_guide/img/efd_i5.svg | 578 +++++++++
doc/guides/prog_guide/img/efd_i6.svg | 413 ++++++
doc/guides/prog_guide/img/efd_i8.svg | 776 ++++++++++++
doc/guides/prog_guide/img/efd_i9.svg | 271 ++++
doc/guides/prog_guide/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 15 +
doc/guides/sample_app_ug/flow_distributor.rst | 492 +++++++
doc/guides/sample_app_ug/img/flow_distributor.svg | 417 ++++++
doc/guides/sample_app_ug/index.rst | 1 +
examples/Makefile | 1 +
examples/flow_distributor/Makefile | 44 +
examples/flow_distributor/distributor/Makefile | 57 +
examples/flow_distributor/distributor/args.c | 200 +++
examples/flow_distributor/distributor/args.h | 39 +
examples/flow_distributor/distributor/init.c | 371 ++++++
examples/flow_distributor/distributor/init.h | 76 ++
examples/flow_distributor/distributor/main.c | 362 ++++++
examples/flow_distributor/node/Makefile | 48 +
examples/flow_distributor/node/node.c | 417 ++++++
examples/flow_distributor/shared/common.h | 99 ++
lib/Makefile | 1 +
lib/librte_eal/common/include/rte_log.h | 1 +
lib/librte_efd/Makefile | 56 +
lib/librte_efd/rte_efd.c | 1354 ++++++++++++++++++++
lib/librte_efd/rte_efd.h | 294 +++++
lib/librte_efd/rte_efd_version.map | 12 +
mk/rte.app.mk | 1 +
44 files changed, 12488 insertions(+), 1 deletion(-)
create mode 100644 app/test/test_efd.c
create mode 100644 app/test/test_efd_perf.c
create mode 100644 doc/guides/prog_guide/efd_lib.rst
create mode 100644 doc/guides/prog_guide/img/efd_i1.svg
create mode 100644 doc/guides/prog_guide/img/efd_i10.svg
create mode 100644 doc/guides/prog_guide/img/efd_i11.svg
create mode 100644 doc/guides/prog_guide/img/efd_i12.svg
create mode 100644 doc/guides/prog_guide/img/efd_i13.svg
create mode 100644 doc/guides/prog_guide/img/efd_i2.svg
create mode 100644 doc/guides/prog_guide/img/efd_i3.svg
create mode 100644 doc/guides/prog_guide/img/efd_i4.svg
create mode 100644 doc/guides/prog_guide/img/efd_i5.svg
create mode 100644 doc/guides/prog_guide/img/efd_i6.svg
create mode 100644 doc/guides/prog_guide/img/efd_i8.svg
create mode 100644 doc/guides/prog_guide/img/efd_i9.svg
create mode 100644 doc/guides/sample_app_ug/flow_distributor.rst
create mode 100644 doc/guides/sample_app_ug/img/flow_distributor.svg
create mode 100644 examples/flow_distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/args.c
create mode 100644 examples/flow_distributor/distributor/args.h
create mode 100644 examples/flow_distributor/distributor/init.c
create mode 100644 examples/flow_distributor/distributor/init.h
create mode 100644 examples/flow_distributor/distributor/main.c
create mode 100644 examples/flow_distributor/node/Makefile
create mode 100644 examples/flow_distributor/node/node.c
create mode 100644 examples/flow_distributor/shared/common.h
create mode 100644 lib/librte_efd/Makefile
create mode 100644 lib/librte_efd/rte_efd.c
create mode 100644 lib/librte_efd/rte_efd.h
create mode 100644 lib/librte_efd/rte_efd_version.map
--
2.7.4
Pablo de Lara
2017-01-07 01:06:02 UTC
Permalink
Elastic Flow Distributor (EFD) is a distributor library that uses
perfect hashing to determine a target/value for a given incoming flow key.
It has the following advantages:

- First, because it uses perfect hashing, it does not store
the key itself and hence lookup performance is not dependent
on the key size.

- Second, the target/value can be any arbitrary value hence
the system designer and/or operator can better optimize service rates
and inter-cluster network traffic locating.

- Third, since the storage requirement is much smaller than a hash-based
flow table (i.e. better fit for CPU cache), EFD can scale to
millions of flow keys.
Finally, with current optimized library implementation performance
is fully scalable with number of CPU cores.

Signed-off-by: Byron Marohn <***@intel.com>
Signed-off-by: Pablo de Lara <***@intel.com>
Signed-off-by: Saikrishna Edupuganti <***@intel.com>
---
MAINTAINERS | 5 +
config/common_base | 5 +
doc/api/doxy-api-index.md | 3 +-
doc/api/doxy-api.conf | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +
lib/Makefile | 1 +
lib/librte_eal/common/include/rte_log.h | 1 +
lib/librte_efd/Makefile | 56 ++
lib/librte_efd/rte_efd.c | 1354 +++++++++++++++++++++++++++++++
lib/librte_efd/rte_efd.h | 294 +++++++
lib/librte_efd/rte_efd_version.map | 12 +
mk/rte.app.mk | 1 +
12 files changed, 1744 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_efd/Makefile
create mode 100644 lib/librte_efd/rte_efd.c
create mode 100644 lib/librte_efd/rte_efd.h
create mode 100644 lib/librte_efd/rte_efd_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 9645c9b..9c60d67 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -528,6 +528,11 @@ F: app/test/test_acl.*
F: examples/l3fwd-acl/
F: doc/guides/sample_app_ug/l3_forward_access_ctrl.rst

+EFD
+M: Byron Marohn <***@intel.com>
+M: Pablo de Lara Guarch <***@intel.com>
+F: lib/librte_efd/
+
Hashes
M: Bruce Richardson <***@intel.com>
M: Pablo de Lara <***@intel.com>
diff --git a/config/common_base b/config/common_base
index 8e9dcfa..869d8fb 100644
--- a/config/common_base
+++ b/config/common_base
@@ -467,6 +467,11 @@ CONFIG_RTE_LIBRTE_HASH=y
CONFIG_RTE_LIBRTE_HASH_DEBUG=n

#
+# Compile librte_efd
+#
+CONFIG_RTE_LIBRTE_EFD=y
+
+#
# Compile librte_jobstats
#
CONFIG_RTE_LIBRTE_JOBSTATS=y
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 72d59b2..0d34e2f 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -90,7 +90,8 @@ There are many libraries, so their headers may be grouped by topics:
[frag/reass] (@ref rte_ip_frag.h),
[LPM IPv4 route] (@ref rte_lpm.h),
[LPM IPv6 route] (@ref rte_lpm6.h),
- [ACL] (@ref rte_acl.h)
+ [ACL] (@ref rte_acl.h),
+ [EFD] (@ref rte_efd.h)

- **QoS**:
[metering] (@ref rte_meter.h),
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index b340fcf..6892315 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -40,6 +40,7 @@ INPUT = doc/api/doxy-api-index.md \
lib/librte_compat \
lib/librte_cryptodev \
lib/librte_distributor \
+ lib/librte_efd \
lib/librte_ether \
lib/librte_hash \
lib/librte_ip_frag \
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 180af82..5023038 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -53,6 +53,18 @@ New Features
information.


+* **Added Elastic Flow Distributor library (rte_efd).**
+
+ This new library uses perfect hashing to determine a target/value for a
+ given incoming flow key.
+
+ It does not store the key itself for lookup operations, and therefore,
+ lookup performance is not dependent on the key size. Also, the target/value
+ can be any arbitrary value (8 bits by default). Finally, the storage requirement
+ is much smaller than a hash-based flow table and therefore, it can better fit for
+ CPU cache, being able to scale to millions of flow keys.
+
+
Resolved Issues
---------------

diff --git a/lib/Makefile b/lib/Makefile
index 990f23a..9a41188 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -43,6 +43,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
+DIRS-$(CONFIG_RTE_LIBRTE_EFD) += librte_efd
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl
DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 671e274..f8342ae 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -79,6 +79,7 @@ extern struct rte_logs rte_logs;
#define RTE_LOGTYPE_PIPELINE 0x00008000 /**< Log related to pipeline. */
#define RTE_LOGTYPE_MBUF 0x00010000 /**< Log related to mbuf. */
#define RTE_LOGTYPE_CRYPTODEV 0x00020000 /**< Log related to cryptodev. */
+#define RTE_LOGTYPE_EFD 0x00040000 /**< Log related to EFD. */

/* these log types can be used in an application */
#define RTE_LOGTYPE_USER1 0x01000000 /**< User-defined log type 1. */
diff --git a/lib/librte_efd/Makefile b/lib/librte_efd/Makefile
new file mode 100644
index 0000000..577469e
--- /dev/null
+++ b/lib/librte_efd/Makefile
@@ -0,0 +1,56 @@
+# BSD LICENSE
+#
+# Copyright(c) 2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_efd.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
+
+EXPORT_MAP := rte_efd_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_EFD) := rte_efd.c
+
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_EFD)-include := rte_efd.h
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EFD) += lib/librte_ether
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_efd/rte_efd.c b/lib/librte_efd/rte_efd.c
new file mode 100644
index 0000000..53f2b92
--- /dev/null
+++ b/lib/librte_efd/rte_efd.c
@@ -0,0 +1,1354 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <immintrin.h>
+#include <math.h>
+#include <sys/queue.h>
+
+#include <rte_log.h>
+#include <rte_eal_memconfig.h>
+#include <rte_errno.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_prefetch.h>
+#include <rte_branch_prediction.h>
+#include <rte_memcpy.h>
+#include <rte_ring.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+#include "rte_efd.h"
+
+#define EFD_KEY(key_idx, table) (table->keys + ((key_idx) * table->key_len))
+/** Hash function used to determine chunk_id and bin_id for a group */
+#define EFD_HASH(key, table) \
+ (uint32_t)(rte_jhash(key, table->key_len, 0xbc9f1d34))
+/** Hash function used as constant component of perfect hash search */
+#define EFD_HASHFUNCA(key, table) \
+ (uint32_t)(rte_hash_crc(key, table->key_len, 0xbc9f1d35))
+/** Hash function used as multiplicative component of perfect hash search */
+#define EFD_HASHFUNCB(key, table) \
+ (uint32_t)(rte_hash_crc(key, table->key_len, 0xbc9f1d36))
+
+/*************************************************************************
+ * Fixed constants
+ *************************************************************************/
+
+/* These parameters are fixed by the efd_bin_to_group balancing table */
+#define EFD_CHUNK_NUM_GROUPS (64)
+#define EFD_CHUNK_NUM_BINS (256)
+#define EFD_CHUNK_NUM_BIN_TO_GROUP_SETS \
+ (EFD_CHUNK_NUM_BINS / EFD_CHUNK_NUM_GROUPS)
+
+/*
+ * Target number of rules that each chunk is created to handle.
+ * Used when initially allocating the table
+ */
+#define EFD_TARGET_CHUNK_NUM_RULES \
+ (EFD_CHUNK_NUM_GROUPS * EFD_TARGET_GROUP_NUM_RULES)
+/*
+ * Max number of rules that each chunk is created to handle.
+ * Used when initially allocating the table
+ */
+#define EFD_TARGET_CHUNK_MAX_NUM_RULES \
+ (EFD_CHUNK_NUM_GROUPS * EFD_MAX_GROUP_NUM_RULES)
+
+/** This is fixed based on the bin_to_group permutation array */
+#define EFD_MAX_GROUP_NUM_BINS (16)
+
+/**
+ * The end of the chunks array needs some extra padding to ensure
+ * that vectorization over-reads on the last online chunk stay within
+allocated memory
+ */
+#define EFD_NUM_CHUNK_PADDING_BYTES (256)
+
+#define EFD_LOOKUPTBL_SHIFT (32 - 4)
+typedef uint16_t efd_lookuptbl_t;
+typedef uint16_t efd_hashfunc_t;
+
+/* All different signature compare functions */
+enum rte_efd_compare_function {
+ RTE_HASH_COMPARE_SCALAR = 0,
+ RTE_HASH_COMPARE_AVX2,
+ RTE_HASH_COMPARE_NUM
+};
+
+TAILQ_HEAD(rte_efd_list, rte_tailq_entry);
+
+static struct rte_tailq_elem rte_efd_tailq = {
+ .name = "RTE_EFD",
+};
+EAL_REGISTER_TAILQ(rte_efd_tailq);
+
+/** Internal permutation array used to shuffle bins into pseudorandom groups */
+const uint32_t efd_bin_to_group[EFD_CHUNK_NUM_BIN_TO_GROUP_SETS][EFD_CHUNK_NUM_BINS] = {
+ {
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
+ 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
+ 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
+ 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
+ 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,
+ 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
+ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,
+ 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
+ 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
+ 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47,
+ 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,
+ 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55,
+ 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59,
+ 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63
+ },
+ {
+ 34, 33, 48, 59, 0, 21, 36, 18, 9, 49, 54, 38, 51, 23, 31, 5,
+ 44, 23, 37, 52, 11, 4, 58, 20, 38, 40, 38, 22, 26, 28, 42, 6,
+ 46, 16, 31, 28, 46, 14, 60, 0, 35, 53, 16, 58, 16, 29, 39, 7,
+ 1, 54, 15, 11, 48, 3, 62, 9, 58, 5, 30, 43, 17, 7, 36, 34,
+ 6, 36, 2, 14, 10, 1, 47, 47, 20, 45, 62, 56, 34, 25, 39, 18,
+ 51, 41, 61, 25, 56, 40, 41, 37, 52, 35, 30, 57, 11, 42, 37, 27,
+ 54, 19, 26, 13, 48, 31, 46, 15, 12, 10, 16, 20, 43, 17, 12, 55,
+ 45, 18, 8, 41, 7, 31, 42, 63, 12, 14, 21, 57, 24, 40, 5, 41,
+ 13, 44, 23, 59, 25, 57, 52, 50, 62, 1, 2, 49, 32, 57, 26, 43,
+ 56, 60, 55, 5, 49, 6, 3, 50, 46, 39, 27, 33, 17, 4, 53, 13,
+ 2, 19, 36, 51, 63, 0, 22, 33, 59, 28, 29, 23, 45, 33, 53, 27,
+ 22, 21, 40, 56, 4, 18, 44, 47, 28, 17, 4, 50, 21, 62, 8, 39,
+ 0, 8, 15, 24, 29, 24, 9, 11, 48, 61, 35, 55, 43, 1, 54, 42,
+ 53, 60, 22, 3, 32, 52, 25, 8, 15, 60, 7, 55, 27, 63, 19, 10,
+ 63, 24, 61, 19, 12, 38, 6, 29, 13, 37, 10, 3, 45, 32, 32, 30,
+ 49, 61, 44, 14, 20, 58, 35, 30, 2, 26, 34, 51, 9, 59, 47, 50
+ },
+ {
+ 32, 35, 32, 34, 55, 5, 6, 23, 49, 11, 6, 23, 52, 37, 29, 54,
+ 55, 40, 63, 50, 29, 52, 61, 25, 12, 56, 39, 38, 29, 11, 46, 1,
+ 40, 11, 19, 56, 7, 28, 51, 16, 15, 48, 21, 51, 60, 31, 14, 22,
+ 41, 47, 59, 56, 53, 28, 58, 26, 43, 27, 41, 33, 24, 52, 44, 38,
+ 13, 59, 48, 51, 60, 15, 3, 30, 15, 0, 10, 62, 44, 14, 28, 51,
+ 38, 2, 41, 26, 25, 49, 10, 12, 55, 57, 27, 35, 19, 33, 0, 30,
+ 5, 36, 47, 53, 5, 53, 20, 43, 34, 37, 52, 41, 21, 63, 59, 9,
+ 24, 1, 45, 24, 39, 44, 45, 16, 9, 17, 7, 50, 57, 22, 18, 28,
+ 25, 45, 2, 40, 58, 15, 17, 3, 1, 27, 61, 39, 19, 0, 19, 21,
+ 57, 62, 54, 60, 54, 40, 48, 33, 36, 37, 4, 42, 1, 43, 58, 8,
+ 13, 42, 10, 56, 35, 22, 48, 61, 63, 10, 49, 9, 24, 9, 25, 57,
+ 33, 18, 13, 31, 42, 36, 36, 55, 30, 37, 53, 34, 59, 4, 4, 23,
+ 8, 16, 58, 14, 30, 11, 12, 63, 49, 62, 2, 39, 47, 22, 2, 60,
+ 18, 8, 46, 31, 6, 20, 32, 29, 46, 42, 20, 31, 32, 61, 34, 4,
+ 47, 26, 20, 43, 26, 21, 7, 3, 16, 35, 18, 44, 27, 62, 13, 23,
+ 6, 50, 12, 8, 45, 17, 3, 46, 50, 7, 14, 5, 17, 54, 38, 0
+ },
+ {
+ 29, 56, 5, 7, 54, 48, 23, 37, 35, 44, 52, 40, 33, 49, 60, 0,
+ 59, 51, 28, 12, 41, 26, 2, 23, 34, 5, 59, 40, 3, 19, 6, 26,
+ 35, 53, 45, 49, 29, 57, 28, 62, 58, 59, 19, 53, 59, 62, 6, 54,
+ 13, 15, 48, 50, 45, 21, 41, 12, 34, 40, 24, 56, 19, 21, 35, 18,
+ 55, 45, 9, 61, 47, 61, 19, 15, 16, 39, 17, 31, 3, 51, 21, 50,
+ 17, 25, 25, 11, 44, 16, 18, 28, 14, 2, 37, 61, 58, 27, 62, 4,
+ 14, 17, 1, 9, 46, 28, 37, 0, 53, 43, 57, 7, 57, 46, 21, 41,
+ 39, 14, 52, 60, 44, 53, 49, 60, 49, 63, 13, 11, 29, 1, 55, 47,
+ 55, 12, 60, 43, 54, 37, 13, 6, 42, 10, 36, 13, 9, 8, 34, 51,
+ 31, 32, 12, 7, 57, 2, 26, 14, 3, 30, 63, 3, 32, 1, 5, 11,
+ 27, 24, 26, 44, 31, 23, 56, 38, 62, 0, 40, 30, 6, 23, 38, 2,
+ 47, 5, 15, 27, 16, 10, 31, 25, 22, 63, 30, 25, 20, 33, 32, 50,
+ 29, 43, 55, 10, 50, 45, 56, 20, 4, 7, 27, 46, 11, 16, 22, 52,
+ 35, 20, 41, 54, 46, 33, 42, 18, 63, 8, 22, 58, 36, 4, 51, 42,
+ 38, 32, 38, 22, 17, 0, 47, 8, 48, 8, 48, 1, 61, 36, 33, 20,
+ 24, 39, 39, 18, 30, 36, 9, 43, 42, 24, 10, 58, 4, 15, 34, 52
+ },
+};
+
+/*************************************************************************
+ * Offline region structures
+ *************************************************************************/
+
+/** Online group containing number of rules, values, keys and their bins
+ * for EFD_MAX_GROUP_NUM_RULES rules.
+ */
+struct efd_offline_group_rules {
+ uint32_t num_rules;
+ /**< Sum of the number of rules in all bins assigned to this group. */
+
+ uint32_t key_idx[EFD_MAX_GROUP_NUM_RULES];
+ /**< Array with all keys of the group. */
+ efd_value_t value[EFD_MAX_GROUP_NUM_RULES];
+ /**< Array with all values of the keys of the group. */
+
+ uint8_t bin_id[EFD_MAX_GROUP_NUM_RULES];
+ /**< Stores the bin for each correspending key to
+ * avoid having to recompute it
+ */
+};
+
+/** Offline chunk record, containing EFD_TARGET_CHUNK_NUM_RULES rules.
+ * Those rules are split into EFD_CHUNK_NUM_GROUPS groups per chunk.
+ */
+struct efd_offline_chunk_rules {
+ uint16_t num_rules;
+ /**< Number of rules in the entire chunk;
+ * used to detect unbalanced groups
+ */
+
+ struct efd_offline_group_rules group_rules[EFD_CHUNK_NUM_GROUPS];
+ /**< Array of all groups in the chunk. */
+};
+
+/*************************************************************************
+ * Online region structures
+ *************************************************************************/
+
+/** Online group containing values for EFD_MAX_GROUP_NUM_RULES rules. */
+struct efd_online_group_entry {
+ efd_hashfunc_t hash_idx[RTE_EFD_VALUE_NUM_BITS];
+ efd_lookuptbl_t lookup_table[RTE_EFD_VALUE_NUM_BITS];
+} __attribute__((__packed__));
+
+/**
+ * A single chunk record, containing EFD_TARGET_CHUNK_NUM_RULES rules.
+ * Those rules are split into EFD_CHUNK_NUM_GROUPS groups per chunk.
+ */
+struct efd_online_chunk {
+ uint8_t bin_choice_list[(EFD_CHUNK_NUM_BINS * 2 + 7) / 8];
+ /**< This is a packed indirection index into the 'groups' array.
+ * Each byte contains four two-bit values which index into
+ * the efd_bin_to_group array.
+ * The efd_bin_to_group array returns the index into the groups array
+ */
+
+ struct efd_online_group_entry groups[EFD_CHUNK_NUM_GROUPS];
+ /**< Array of all the groups in the chunk. */
+} __attribute__((__packed__));
+
+/**
+ * EFD table structure
+ */
+struct rte_efd_table {
+ char name[RTE_EFD_NAMESIZE]; /**< Name of the efd table. */
+
+ uint32_t key_len; /**< Length of the key stored offline */
+
+ uint32_t max_num_rules;
+ /**< Static maximum number of entries the table was constructed to hold. */
+
+ uint32_t num_rules;
+ /**< Number of entries currently in the table . */
+
+ uint32_t num_chunks;
+ /**< Number of chunks in the table needed to support num_rules. */
+
+ uint32_t num_chunks_shift;
+ /**< Bits to shift to get chunk id, instead of dividing by num_chunk. */
+
+ enum rte_efd_compare_function cmp_fn;
+ /**< Indicates which compare function to use. */
+
+ struct efd_online_chunk *chunks[RTE_MAX_NUMA_NODES];
+ /**< Dynamic array of size num_chunks of chunk records. */
+
+ struct efd_offline_chunk_rules *offline_chunks;
+ /**< Dynamic array of size num_chunks of key-value pairs. */
+
+ struct rte_ring *free_slots;
+ /**< Ring that stores all indexes of the free slots in the key table */
+
+ uint8_t *keys; /**< Dynamic array of size max_num_rules of keys */
+};
+
+/**
+ * Computes the chunk ID for a given key hash
+ *
+ * @param table
+ * EFD table to reference
+ * @param hashed_key
+ * 32-bit key hash returned by EFD_HASH
+ *
+ * @return
+ * chunk ID containing this key hash
+ */
+static inline uint32_t
+efd_get_chunk_id(const struct rte_efd_table * const table,
+ const uint32_t hashed_key)
+{
+ return hashed_key & (table->num_chunks - 1);
+}
+
+/**
+ * Computes the bin ID for a given key hash
+ *
+ * @param table
+ * EFD table to reference
+ * @param hashed_key
+ * 32-bit key hash returned by EFD_HASH
+ *
+ * @return bin ID containing this key hash
+ */
+static inline uint32_t
+efd_get_bin_id(const struct rte_efd_table * const table,
+ const uint32_t hashed_key)
+{
+ return (hashed_key >> table->num_chunks_shift) & (EFD_CHUNK_NUM_BINS - 1);
+}
+
+/**
+ * Looks up the current permutation choice for a particular bin in the online table
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to look up existing values (ideally caller's socket id)
+ * @param chunk_id
+ * Chunk ID of bin to look up
+ * @param bin_id
+ * Bin ID to look up
+ *
+ * @return
+ * Currently active permutation choice in the online table
+ */
+static inline uint8_t
+efd_get_choice(const struct rte_efd_table * const table,
+ const unsigned int socket_id, const uint32_t chunk_id,
+ const uint32_t bin_id)
+{
+ struct efd_online_chunk *chunk = &table->chunks[socket_id][chunk_id];
+
+ /*
+ * Grab the chunk (byte) that contains the choices
+ * for four neighboring bins.
+ */
+ uint8_t choice_chunk =
+ chunk->bin_choice_list[bin_id / EFD_CHUNK_NUM_BIN_TO_GROUP_SETS];
+
+ /*
+ * Compute the offset into the chunk that contains
+ * the group_id lookup position
+ */
+ int offset = (bin_id & 0x3) * 2;
+
+ /* Extract from the byte just the desired lookup position */
+ return (uint8_t) ((choice_chunk >> offset) & 0x3);
+}
+
+/**
+ * Compute the chunk_id and bin_id for a given key
+ *
+ * @param table
+ * EFD table to reference
+ * @param key
+ * Key to hash and find location of
+ * @param chunk_id
+ * Computed chunk ID
+ * @param bin_id
+ * Computed bin ID
+ *
+ */
+static inline void
+efd_compute_ids(const struct rte_efd_table * const table,
+ const void *key, uint32_t * const chunk_id, uint32_t * const bin_id)
+{
+ /* Compute the position of the entry in the hash table */
+ uint32_t h = EFD_HASH(key, table);
+
+ /* Compute the chunk_id where that entry can be found */
+ *chunk_id = efd_get_chunk_id(table, h);
+
+ /*
+ * Compute the bin within that chunk where the entry
+ * can be found (0 - 255)
+ */
+ *bin_id = efd_get_bin_id(table, h);
+}
+
+/**
+ * Search for a hash function for a group that satisfies all group results
+ */
+static inline int
+efd_search_hash(struct rte_efd_table * const table,
+ const struct efd_offline_group_rules * const off_group,
+ struct efd_online_group_entry * const on_group)
+{
+ efd_hashfunc_t hash_idx;
+ efd_hashfunc_t start_hash_idx[RTE_EFD_VALUE_NUM_BITS];
+ efd_lookuptbl_t start_lookup_table[RTE_EFD_VALUE_NUM_BITS];
+
+ uint32_t i, j, rule_id;
+ uint32_t hash_val_a[EFD_MAX_GROUP_NUM_RULES];
+ uint32_t hash_val_b[EFD_MAX_GROUP_NUM_RULES];
+ uint32_t hash_val[EFD_MAX_GROUP_NUM_RULES];
+
+
+ rte_prefetch0(off_group->value);
+
+ /*
+ * Prepopulate the hash_val tables by running the two hash functions
+ * for each provided rule
+ */
+ for (i = 0; i < off_group->num_rules; i++) {
+ void *key_stored = EFD_KEY(off_group->key_idx[i], table);
+ hash_val_b[i] = EFD_HASHFUNCB(key_stored, table);
+ hash_val_a[i] = EFD_HASHFUNCA(key_stored, table);
+ }
+
+ for (i = 0; i < RTE_EFD_VALUE_NUM_BITS; i++) {
+ hash_idx = on_group->hash_idx[i];
+ start_hash_idx[i] = hash_idx;
+ start_lookup_table[i] = on_group->lookup_table[i];
+
+ do {
+ efd_lookuptbl_t lookup_table = 0;
+ efd_lookuptbl_t lookup_table_complement = 0;
+
+ for (rule_id = 0; rule_id < off_group->num_rules; rule_id++)
+ hash_val[rule_id] = hash_val_a[rule_id] + (hash_idx *
+ hash_val_b[rule_id]);
+
+ /*
+ * The goal here is to find a hash function for this
+ * particular bit entry that meets the following criteria:
+ * The most significant bits of the hash result define a
+ * shift into the lookup table where the bit will be stored
+ */
+
+ /* Iterate over each provided rule */
+ for (rule_id = 0; rule_id < off_group->num_rules;
+ rule_id++) {
+ /*
+ * Use the few most significant bits (number based on
+ * EFD_LOOKUPTBL_SIZE) to see what position the
+ * expected bit should be set in the lookup_table
+ */
+ uint32_t bucket_idx = hash_val[rule_id] >>
+ EFD_LOOKUPTBL_SHIFT;
+
+ /*
+ * Get the current bit of interest.
+ * This only find an appropriate hash function
+ * for one bit at a time of the rule
+ */
+ efd_lookuptbl_t expected =
+ (off_group->value[rule_id] >> i) & 0x1;
+
+ /*
+ * Add the expected bit (if set) to a map
+ * (lookup_table). Also set its complement
+ * in lookup_table_complement
+ */
+ lookup_table |= expected << bucket_idx;
+ lookup_table_complement |= (1 - expected)
+ << bucket_idx;
+
+ /*
+ * If ever the hash function of two different
+ * elements result in different values at the
+ * same location in the lookup_table,
+ * the current hash_idx is not valid.
+ */
+ if (lookup_table & lookup_table_complement)
+ break;
+ }
+
+ /*
+ * Check if the previous loop completed without
+ * breaking early
+ */
+ if (rule_id == off_group->num_rules) {
+ /*
+ * Current hash function worked, store it
+ * for the current group
+ */
+ on_group->hash_idx[i] = hash_idx;
+ on_group->lookup_table[i] = lookup_table;
+
+ /*
+ * Make sure that the hash function has changed
+ * from the starting value
+ */
+ hash_idx = start_hash_idx[i] + 1;
+ break;
+ }
+ hash_idx++;
+
+ } while (hash_idx != start_hash_idx[i]);
+
+ /* Failed to find perfect hash for this group */
+ if (hash_idx == start_hash_idx[i]) {
+ /*
+ * Restore previous hash_idx and lookup_table
+ * for all value bits
+ */
+ for (j = 0; j < i; j++) {
+ on_group->hash_idx[j] = start_hash_idx[j];
+ on_group->lookup_table[j] = start_lookup_table[j];
+ }
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+struct rte_efd_table *
+rte_efd_create(const char *name, uint32_t max_num_rules, uint32_t key_len,
+ uint8_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket)
+{
+ struct rte_efd_table *table = NULL;
+ uint8_t *key_array = NULL;
+ uint32_t num_chunks, num_chunks_shift;
+ uint8_t socket_id;
+ struct rte_efd_list *efd_list = NULL;
+ struct rte_tailq_entry *te;
+ uint64_t offline_table_size;
+ char ring_name[RTE_RING_NAMESIZE];
+ struct rte_ring *r = NULL;
+ unsigned int i;
+
+ efd_list = RTE_TAILQ_CAST(rte_efd_tailq.head, rte_efd_list);
+
+ if (online_cpu_socket_bitmask == 0) {
+ RTE_LOG(ERR, EFD, "At least one CPU socket must be enabled "
+ "in the bitmask\n");
+ return NULL;
+ }
+
+ if (max_num_rules == 0) {
+ RTE_LOG(ERR, EFD, "Max num rules must be higher than 0\n");
+ return NULL;
+ }
+
+ /*
+ * Compute the minimum number of chunks (smallest power of 2)
+ * that can hold all of the rules
+ */
+ if (max_num_rules % EFD_TARGET_CHUNK_NUM_RULES == 0)
+ num_chunks = rte_align32pow2(max_num_rules /
+ EFD_TARGET_CHUNK_NUM_RULES);
+ else
+ num_chunks = rte_align32pow2((max_num_rules /
+ EFD_TARGET_CHUNK_NUM_RULES) + 1);
+
+ num_chunks_shift = log2(num_chunks);
+
+ rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+ /*
+ * Guarantee there's no existing: this is normally already checked
+ * by ring creation above
+ */
+ TAILQ_FOREACH(te, efd_list, next)
+ {
+ table = (struct rte_efd_table *) te->data;
+ if (strncmp(name, table->name, RTE_EFD_NAMESIZE) == 0)
+ break;
+ }
+
+ table = NULL;
+ if (te != NULL) {
+ rte_errno = EEXIST;
+ te = NULL;
+ goto error_unlock_exit;
+ }
+
+ te = rte_zmalloc("EFD_TAILQ_ENTRY", sizeof(*te), 0);
+ if (te == NULL) {
+ RTE_LOG(ERR, EFD, "tailq entry allocation failed\n");
+ goto error_unlock_exit;
+ }
+
+ /* Create a new EFD table management structure */
+ table = (struct rte_efd_table *) rte_zmalloc_socket(NULL,
+ sizeof(struct rte_efd_table),
+ RTE_CACHE_LINE_SIZE,
+ offline_cpu_socket);
+ if (table == NULL) {
+ RTE_LOG(ERR, EFD, "Allocating EFD table management structure"
+ " on socket %u failed\n",
+ offline_cpu_socket);
+ goto error_unlock_exit;
+ }
+
+
+ RTE_LOG(DEBUG, EFD, "Allocated EFD table management structure "
+ "on socket %u\n", offline_cpu_socket);
+
+ table->max_num_rules = num_chunks * EFD_TARGET_CHUNK_MAX_NUM_RULES;
+ table->num_rules = 0;
+ table->num_chunks = num_chunks;
+ table->num_chunks_shift = num_chunks_shift;
+ table->key_len = key_len;
+
+ /* key_array */
+ key_array = (uint8_t *) rte_zmalloc_socket(NULL,
+ table->max_num_rules * table->key_len,
+ RTE_CACHE_LINE_SIZE,
+ offline_cpu_socket);
+ if (key_array == NULL) {
+ RTE_LOG(ERR, EFD, "Allocating key array"
+ " on socket %u failed\n",
+ offline_cpu_socket);
+ goto error_unlock_exit;
+ }
+ table->keys = key_array;
+ snprintf(table->name, sizeof(table->name), "%s", name);
+
+ RTE_LOG(DEBUG, EFD, "Creating an EFD table with %u chunks,"
+ " which potentially supports %u entries\n",
+ num_chunks, table->max_num_rules);
+
+ /* Make sure all the allocatable table pointers are NULL initially */
+ for (socket_id = 0; socket_id < RTE_MAX_NUMA_NODES; socket_id++)
+ table->chunks[socket_id] = NULL;
+ table->offline_chunks = NULL;
+
+ /*
+ * Allocate one online table per socket specified
+ * in the user-supplied bitmask
+ */
+ uint64_t online_table_size = num_chunks * sizeof(struct efd_online_chunk) +
+ EFD_NUM_CHUNK_PADDING_BYTES;
+
+ for (socket_id = 0; socket_id < RTE_MAX_NUMA_NODES; socket_id++) {
+ if ((online_cpu_socket_bitmask >> socket_id) & 0x01) {
+ /*
+ * Allocate all of the EFD table chunks (the online portion)
+ * as a continuous block
+ */
+ table->chunks[socket_id] =
+ (struct efd_online_chunk *) rte_zmalloc_socket(
+ NULL,
+ online_table_size,
+ RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (table->chunks[socket_id] == NULL) {
+ RTE_LOG(ERR, EFD,
+ "Allocating EFD online table on "
+ "socket %u failed\n",
+ socket_id);
+ goto error_unlock_exit;
+ }
+ RTE_LOG(DEBUG, EFD,
+ "Allocated EFD online table of size "
+ "%"PRIu64" bytes (%.2f MB) on socket %u\n",
+ online_table_size,
+ (float) online_table_size /
+ (1024.0F * 1024.0F),
+ socket_id);
+ }
+ }
+
+#if defined(RTE_ARCH_X86)
+ if (RTE_EFD_VALUE_NUM_BITS > 3 && rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2))
+ table->cmp_fn = RTE_HASH_COMPARE_AVX2;
+ else
+#endif
+ table->cmp_fn = RTE_HASH_COMPARE_SCALAR;
+
+ /*
+ * Allocate the EFD table offline portion (with the actual rules
+ * mapping keys to values) as a continuous block.
+ * This could be several gigabytes of memory.
+ */
+ offline_table_size = num_chunks * sizeof(struct efd_offline_chunk_rules);
+ table->offline_chunks =
+ (struct efd_offline_chunk_rules *) rte_zmalloc_socket(NULL,
+ offline_table_size,
+ RTE_CACHE_LINE_SIZE,
+ offline_cpu_socket);
+ if (table->offline_chunks == NULL) {
+ RTE_LOG(ERR, EFD, "Allocating EFD offline table on socket %u "
+ "failed\n", offline_cpu_socket);
+ goto error_unlock_exit;
+ }
+
+ RTE_LOG(DEBUG, EFD,
+ "Allocated EFD offline table of size %"PRIu64" bytes "
+ " (%.2f MB) on socket %u\n", offline_table_size,
+ (float) offline_table_size / (1024.0F * 1024.0F),
+ offline_cpu_socket);
+
+ te->data = (void *) table;
+ TAILQ_INSERT_TAIL(efd_list, te, next);
+ rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+ snprintf(ring_name, sizeof(ring_name), "HT_%s", table->name);
+ /* Create ring (Dummy slot index is not enqueued) */
+ r = rte_ring_create(ring_name, rte_align32pow2(table->max_num_rules),
+ offline_cpu_socket, 0);
+ if (r == NULL) {
+ RTE_LOG(ERR, EFD, "memory allocation failed\n");
+ goto error_unlock_exit;
+ }
+
+ /* Populate free slots ring. Entry zero is reserved for key misses. */
+ for (i = 0; i < table->max_num_rules; i++)
+ rte_ring_sp_enqueue(r, (void *) ((uintptr_t) i));
+
+ table->free_slots = r;
+ return table;
+
+error_unlock_exit:
+ rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+ rte_efd_free(table);
+
+ return NULL;
+}
+
+struct rte_efd_table *
+rte_efd_find_existing(const char *name)
+{
+ struct rte_efd_table *table = NULL;
+ struct rte_tailq_entry *te;
+ struct rte_efd_list *efd_list;
+
+ efd_list = RTE_TAILQ_CAST(rte_efd_tailq.head, rte_efd_list);
+
+ rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+ TAILQ_FOREACH(te, efd_list, next)
+ {
+ table = (struct rte_efd_table *) te->data;
+ if (strncmp(name, table->name, RTE_EFD_NAMESIZE) == 0)
+ break;
+ }
+ rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+ if (te == NULL) {
+ rte_errno = ENOENT;
+ return NULL;
+ }
+ return table;
+}
+
+void
+rte_efd_free(struct rte_efd_table *table)
+{
+ uint8_t socket_id;
+
+ if (table == NULL)
+ return;
+
+ for (socket_id = 0; socket_id < RTE_MAX_NUMA_NODES; socket_id++)
+ rte_free(table->chunks[socket_id]);
+
+ rte_ring_free(table->free_slots);
+ rte_free(table->offline_chunks);
+ rte_free(table->keys);
+ rte_free(table);
+}
+
+/**
+ * Applies a previously computed table entry to the specified table for all
+ * socket-local copies of the online table.
+ * Intended to apply an update for only a single change
+ * to a key/value pair at a time
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing values (ideally caller's socket id)
+ * @param chunk_id
+ * Chunk index to update
+ * @param group_id
+ * Group index to update
+ * @param bin_id
+ * Bin within the group that this update affects
+ * @param new_bin_choice
+ * Newly chosen permutation which this bin should use - only lower 2 bits
+ * @param new_group_entry
+ * Previously computed updated chunk/group entry
+ */
+static inline void
+efd_apply_update(struct rte_efd_table * const table, const unsigned int socket_id,
+ const uint32_t chunk_id, const uint32_t group_id,
+ const uint32_t bin_id, const uint8_t new_bin_choice,
+ const struct efd_online_group_entry * const new_group_entry)
+{
+ int i;
+ struct efd_online_chunk *chunk = &table->chunks[socket_id][chunk_id];
+ uint8_t bin_index = bin_id / EFD_CHUNK_NUM_BIN_TO_GROUP_SETS;
+
+ /*
+ * Grab the current byte that contains the choices
+ * for four neighboring bins
+ */
+ uint8_t choice_chunk =
+ chunk->bin_choice_list[bin_index];
+
+
+ /* Compute the offset into the chunk that needs to be updated */
+ int offset = (bin_id & 0x3) * 2;
+
+ /* Zero the two bits of interest and set them to new_bin_choice */
+ choice_chunk = (choice_chunk & (~(0x03 << offset)))
+ | ((new_bin_choice & 0x03) << offset);
+
+ /* Update the online table with the new data across all sockets */
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ if (table->chunks[i] != NULL) {
+ memcpy(&(table->chunks[i][chunk_id].groups[group_id]),
+ new_group_entry,
+ sizeof(struct efd_online_group_entry));
+ table->chunks[i][chunk_id].bin_choice_list[bin_index] =
+ choice_chunk;
+ }
+ }
+}
+
+/*
+ * Move the bin from prev group to the new group
+ */
+static inline void
+move_groups(uint32_t bin_id, uint8_t bin_size,
+ struct efd_offline_group_rules *new_group,
+ struct efd_offline_group_rules * const current_group)
+{
+
+ uint8_t empty_idx = 0;
+ unsigned int i;
+
+ if (new_group == current_group)
+ return;
+
+ for (i = 0; i < current_group->num_rules; i++) {
+ /*
+ * Move keys that belong to the same bin
+ * to the new group
+ */
+ if (current_group->bin_id[i] == bin_id) {
+ new_group->key_idx[new_group->num_rules] =
+ current_group->key_idx[i];
+ new_group->value[new_group->num_rules] =
+ current_group->value[i];
+ new_group->bin_id[new_group->num_rules] =
+ current_group->bin_id[i];
+ new_group->num_rules++;
+ } else {
+ if (i != empty_idx) {
+ /*
+ * Need to move this key towards
+ * the top of the array
+ */
+ current_group->key_idx[empty_idx] =
+ current_group->key_idx[i];
+ current_group->value[empty_idx] =
+ current_group->value[i];
+ current_group->bin_id[empty_idx] =
+ current_group->bin_id[i];
+ }
+ empty_idx++;
+ }
+
+ }
+ current_group->num_rules -= bin_size;
+}
+
+/*
+ * Revert group/s to their previous state before
+ * trying to insert/add a new key
+ */
+static inline void
+revert_groups(struct efd_offline_group_rules *previous_group,
+ struct efd_offline_group_rules *current_group, uint8_t bin_size)
+{
+ unsigned int i;
+
+ if (current_group == previous_group)
+ return;
+
+ /* Move keys back to previous group */
+ for (i = current_group->num_rules - bin_size;
+ i < current_group->num_rules; i++) {
+ previous_group->key_idx[previous_group->num_rules] =
+ current_group->key_idx[i];
+ previous_group->value[previous_group->num_rules] =
+ current_group->value[i];
+ previous_group->bin_id[previous_group->num_rules] =
+ current_group->bin_id[i];
+ previous_group->num_rules++;
+ }
+
+ /*
+ * Decrease number of rules after the move
+ * in the new group
+ */
+ current_group->num_rules -= bin_size;
+}
+
+/**
+ * Computes an updated table entry where the supplied key points to a new host.
+ * If no entry exists, one is inserted.
+ *
+ * This function does NOT modify the online table(s)
+ * This function DOES modify the offline table
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing values (ideally caller's socket id)
+ * @param key
+ * Key to insert
+ * @param value
+ * Value to associate with key
+ * @param chunk_id
+ * Chunk ID of the chunk that was modified
+ * @param group_id
+ * Group ID of the group that was modified
+ * @param bin_id
+ * Bin ID that was modified
+ * @param new_bin_choice
+ * Newly chosen permutation which this bin will use
+ * @param entry
+ * Newly computed online entry to apply later with efd_apply_update
+ *
+ * @return
+ * RTE_EFD_UPDATE_WARN_GROUP_FULL
+ * Operation is insert, and the last available space in the
+ * key's group was just used. Future inserts may fail as groups fill up.
+ * This operation was still successful, and entry contains a valid update
+ * RTE_EFD_UPDATE_FAILED
+ * Either the EFD failed to find a suitable perfect hash or the group was full
+ * This is a fatal error, and the table is now in an indeterminite state
+ * RTE_EFD_UPDATE_NO_CHANGE
+ * Operation resulted in no change to the table (same value already exists)
+ * 0
+ * Insert or update was successful, and the new efd_online_group_entry
+ * is stored in *entry
+ *
+ * @warning
+ * Note that entry will be UNCHANGED if the update has no effect, and thus any
+ * subsequent use of the entry content will likely be invalid
+ */
+static inline int
+efd_compute_update(struct rte_efd_table * const table,
+ const unsigned int socket_id, const void *key,
+ const efd_value_t value, uint32_t * const chunk_id,
+ uint32_t * const group_id, uint32_t * const bin_id,
+ uint8_t * const new_bin_choice,
+ struct efd_online_group_entry * const entry)
+{
+ unsigned int i;
+ int ret;
+ uint32_t new_idx;
+ void *new_k, *slot_id = NULL;
+ int status = EXIT_SUCCESS;
+ unsigned int found = 0;
+
+ efd_compute_ids(table, key, chunk_id, bin_id);
+
+ struct efd_offline_chunk_rules * const chunk =
+ &table->offline_chunks[*chunk_id];
+ struct efd_offline_group_rules *new_group;
+
+ uint8_t current_choice = efd_get_choice(table, socket_id,
+ *chunk_id, *bin_id);
+ uint32_t current_group_id = efd_bin_to_group[current_choice][*bin_id];
+ struct efd_offline_group_rules * const current_group =
+ &chunk->group_rules[current_group_id];
+ uint8_t bin_size = 0;
+ uint8_t key_changed_index = 0;
+ efd_value_t key_changed_previous_value = 0;
+ uint32_t key_idx_previous = 0;
+
+ /* Scan the current group and see if the key is already present */
+ for (i = 0; i < current_group->num_rules; i++) {
+ if (current_group->bin_id[i] == *bin_id)
+ bin_size++;
+ else
+ continue;
+
+ void *key_stored = EFD_KEY(current_group->key_idx[i], table);
+ if (found == 0 && unlikely(memcmp(key_stored, key,
+ table->key_len) == 0)) {
+ /* Key is already present */
+
+ /*
+ * If previous value is same as new value,
+ * no additional work is required
+ */
+ if (current_group->value[i] == value)
+ return RTE_EFD_UPDATE_NO_CHANGE;
+
+ key_idx_previous = current_group->key_idx[i];
+ key_changed_previous_value = current_group->value[i];
+ key_changed_index = i;
+ current_group->value[i] = value;
+ found = 1;
+ }
+ }
+
+ if (found == 0) {
+ /* Key does not exist. Insert the rule into the bin/group */
+ if (unlikely(current_group->num_rules >= EFD_MAX_GROUP_NUM_RULES)) {
+ RTE_LOG(ERR, EFD,
+ "Fatal: No room remaining for insert into "
+ "chunk %u group %u bin %u\n",
+ *chunk_id,
+ current_group_id, *bin_id);
+ return RTE_EFD_UPDATE_FAILED;
+ }
+
+ if (unlikely(current_group->num_rules ==
+ (EFD_MAX_GROUP_NUM_RULES - 1))) {
+ RTE_LOG(INFO, EFD, "Warn: Insert into last "
+ "available slot in chunk %u "
+ "group %u bin %u\n", *chunk_id,
+ current_group_id, *bin_id);
+ status = RTE_EFD_UPDATE_WARN_GROUP_FULL;
+ }
+
+ if (rte_ring_sc_dequeue(table->free_slots, &slot_id) != 0)
+ return RTE_EFD_UPDATE_FAILED;
+
+ new_k = RTE_PTR_ADD(table->keys, (uintptr_t) slot_id *
+ table->key_len);
+ rte_prefetch0(new_k);
+ new_idx = (uint32_t) ((uintptr_t) slot_id);
+
+ rte_memcpy(EFD_KEY(new_idx, table), key, table->key_len);
+ current_group->key_idx[current_group->num_rules] = new_idx;
+ current_group->value[current_group->num_rules] = value;
+ current_group->bin_id[current_group->num_rules] = *bin_id;
+ current_group->num_rules++;
+ table->num_rules++;
+ bin_size++;
+ } else {
+ uint32_t last = current_group->num_rules - 1;
+ /* Swap the key with the last key inserted*/
+ current_group->key_idx[key_changed_index] =
+ current_group->key_idx[last];
+ current_group->value[key_changed_index] =
+ current_group->value[last];
+ current_group->bin_id[key_changed_index] =
+ current_group->bin_id[last];
+
+ /*
+ * Key to be updated will always be available
+ * at the end of the group
+ */
+ current_group->key_idx[last] = key_idx_previous;
+ current_group->value[last] = value;
+ current_group->bin_id[last] = *bin_id;
+ }
+
+ *new_bin_choice = current_choice;
+ *group_id = current_group_id;
+ new_group = current_group;
+
+ /* Group need to be rebalanced when it starts to get loaded */
+ if (current_group->num_rules > EFD_MIN_BALANCED_NUM_RULES) {
+
+ /*
+ * Subtract the number of entries in the bin from
+ * the original group
+ */
+ current_group->num_rules -= bin_size;
+
+ /*
+ * Figure out which of the available groups that this bin
+ * can map to is the smallest (using the current group
+ * as baseline)
+ */
+ uint8_t smallest_choice = current_choice;
+ uint8_t smallest_size = current_group->num_rules;
+ uint32_t smallest_group_id = current_group_id;
+ unsigned char choice;
+
+ for (choice = 0; choice < EFD_CHUNK_NUM_BIN_TO_GROUP_SETS;
+ choice++) {
+ uint32_t test_group_id =
+ efd_bin_to_group[choice][*bin_id];
+ uint32_t num_rules =
+ chunk->group_rules[test_group_id].num_rules;
+ if (num_rules < smallest_size) {
+ smallest_choice = choice;
+ smallest_size = num_rules;
+ smallest_group_id = test_group_id;
+ }
+ }
+
+ *new_bin_choice = smallest_choice;
+ *group_id = smallest_group_id;
+ new_group = &chunk->group_rules[smallest_group_id];
+ current_group->num_rules += bin_size;
+
+ }
+
+ uint8_t choice = 0;
+ for (;;) {
+ if (current_group != new_group &&
+ new_group->num_rules + bin_size >
+ EFD_MAX_GROUP_NUM_RULES) {
+ RTE_LOG(DEBUG, EFD,
+ "Unable to move_groups to dest group "
+ "containing %u entries."
+ "bin_size:%u choice:%02x\n",
+ new_group->num_rules, bin_size,
+ choice - 1);
+ goto next_choice;
+ }
+ move_groups(*bin_id, bin_size, new_group, current_group);
+ /*
+ * Recompute the hash function for the modified group,
+ * and return it to the caller
+ */
+ ret = efd_search_hash(table, new_group, entry);
+
+ if (!ret)
+ return status;
+
+ RTE_LOG(DEBUG, EFD,
+ "Failed to find perfect hash for group "
+ "containing %u entries. bin_size:%u choice:%02x\n",
+ new_group->num_rules, bin_size, choice - 1);
+ /* Restore groups modified to their previous state */
+ revert_groups(current_group, new_group, bin_size);
+
+next_choice:
+ if (choice == EFD_CHUNK_NUM_BIN_TO_GROUP_SETS)
+ break;
+ *new_bin_choice = choice;
+ *group_id = efd_bin_to_group[choice][*bin_id];
+ new_group = &chunk->group_rules[*group_id];
+ choice++;
+ }
+
+ if (!found) {
+ current_group->num_rules--;
+ table->num_rules--;
+ } else
+ current_group->value[current_group->num_rules - 1] =
+ key_changed_previous_value;
+ return RTE_EFD_UPDATE_FAILED;
+}
+
+int
+rte_efd_update(struct rte_efd_table * const table, const unsigned int socket_id,
+ const void *key, const efd_value_t value)
+{
+ uint32_t chunk_id = 0, group_id = 0, bin_id = 0;
+ uint8_t new_bin_choice = 0;
+ struct efd_online_group_entry entry;
+
+ int status = efd_compute_update(table, socket_id, key, value,
+ &chunk_id, &group_id, &bin_id,
+ &new_bin_choice, &entry);
+
+ if (status == RTE_EFD_UPDATE_NO_CHANGE)
+ return EXIT_SUCCESS;
+
+ if (status == RTE_EFD_UPDATE_FAILED)
+ return status;
+
+ efd_apply_update(table, socket_id, chunk_id, group_id, bin_id,
+ new_bin_choice, &entry);
+ return status;
+}
+
+int
+rte_efd_delete(struct rte_efd_table * const table, const unsigned int socket_id,
+ const void *key, efd_value_t * const prev_value)
+{
+ unsigned int i;
+ uint32_t chunk_id, bin_id;
+ uint8_t not_found = 1;
+
+ efd_compute_ids(table, key, &chunk_id, &bin_id);
+
+ struct efd_offline_chunk_rules * const chunk =
+ &table->offline_chunks[chunk_id];
+
+ uint8_t current_choice = efd_get_choice(table, socket_id,
+ chunk_id, bin_id);
+ uint32_t current_group_id = efd_bin_to_group[current_choice][bin_id];
+ struct efd_offline_group_rules * const current_group =
+ &chunk->group_rules[current_group_id];
+
+ /*
+ * Search the current group for the specified key.
+ * If it exists, remove it and re-pack the other values
+ */
+ for (i = 0; i < current_group->num_rules; i++) {
+ if (not_found) {
+ /* Found key that needs to be removed */
+ if (memcmp(EFD_KEY(current_group->key_idx[i], table),
+ key, table->key_len) == 0) {
+ /* Store previous value if requested by caller */
+ if (prev_value != NULL)
+ *prev_value = current_group->value[i];
+
+ not_found = 0;
+ rte_ring_sp_enqueue(table->free_slots,
+ (void *)((uintptr_t)current_group->key_idx[i]));
+ }
+ } else {
+ /*
+ * If the desired key has been found,
+ * need to shift other values up one
+ */
+
+ /* Need to shift this entry back up one index */
+ current_group->key_idx[i - 1] = current_group->key_idx[i];
+ current_group->value[i - 1] = current_group->value[i];
+ current_group->bin_id[i - 1] = current_group->bin_id[i];
+ }
+ }
+
+ if (not_found == 0) {
+ table->num_rules--;
+ current_group->num_rules--;
+ }
+
+ return not_found;
+}
+
+
+#if (RTE_EFD_VALUE_NUM_BITS == 8 || RTE_EFD_VALUE_NUM_BITS == 16 || \
+ RTE_EFD_VALUE_NUM_BITS == 24 || RTE_EFD_VALUE_NUM_BITS == 32)
+#define EFD_LOAD_SI128(val) _mm_load_si128(val)
+#else
+#define EFD_LOAD_SI128(val) _mm_lddqu_si128(val)
+#endif
+
+static inline efd_value_t
+efd_lookup_internal(const struct efd_online_group_entry * const group,
+ const uint32_t hash_val_a, const uint32_t hash_val_b,
+ enum rte_efd_compare_function cmp_fn)
+{
+ efd_value_t value = 0;
+ uint32_t i;
+
+ switch (cmp_fn) {
+#ifdef RTE_MACHINE_CPUFLAG_AVX2
+ case RTE_HASH_COMPARE_AVX2:
+
+ i = 0;
+ __m256i vhash_val_a = _mm256_set1_epi32(hash_val_a);
+ __m256i vhash_val_b = _mm256_set1_epi32(hash_val_b);
+
+ for (; i < RTE_EFD_VALUE_NUM_BITS; i += 8) {
+ __m256i vhash_idx =
+ _mm256_cvtepu16_epi32(EFD_LOAD_SI128(
+ (__m128i const *) &group->hash_idx[i]));
+ __m256i vlookup_table = _mm256_cvtepu16_epi32(
+ EFD_LOAD_SI128((__m128i const *)
+ &group->lookup_table[i]));
+ __m256i vhash = _mm256_add_epi32(vhash_val_a,
+ _mm256_mullo_epi32(vhash_idx, vhash_val_b));
+ __m256i vbucket_idx = _mm256_srli_epi32(vhash,
+ EFD_LOOKUPTBL_SHIFT);
+ __m256i vresult = _mm256_srlv_epi32(vlookup_table,
+ vbucket_idx);
+
+ value |= (_mm256_movemask_ps(
+ (__m256) _mm256_slli_epi32(vresult, 31))
+ & ((1 << (RTE_EFD_VALUE_NUM_BITS - i)) - 1)) << i;
+ }
+ break;
+#endif
+ default:
+
+ i = 0;
+ for (; i < RTE_EFD_VALUE_NUM_BITS; i++) {
+ value <<= 1;
+
+ uint32_t h = hash_val_a + (hash_val_b *
+ group->hash_idx[RTE_EFD_VALUE_NUM_BITS - i - 1]);
+ uint16_t bucket_idx = h >> EFD_LOOKUPTBL_SHIFT;
+
+ value |= (group->lookup_table[
+ RTE_EFD_VALUE_NUM_BITS - i - 1] >>
+ bucket_idx) & 0x1;
+ }
+ }
+ return value;
+}
+
+efd_value_t
+rte_efd_lookup(const struct rte_efd_table * const table,
+ const unsigned int socket_id, const void *key)
+{
+ uint32_t chunk_id, group_id, bin_id;
+ uint8_t bin_choice;
+ const struct efd_online_group_entry *group;
+ const struct efd_online_chunk * const chunks = table->chunks[socket_id];
+
+ /* Determine the chunk and group location for the given key */
+ efd_compute_ids(table, key, &chunk_id, &bin_id);
+ bin_choice = efd_get_choice(table, socket_id, chunk_id, bin_id);
+ group_id = efd_bin_to_group[bin_choice][bin_id];
+ group = &chunks[chunk_id].groups[group_id];
+
+ return efd_lookup_internal(group,
+ EFD_HASHFUNCA(key, table),
+ EFD_HASHFUNCB(key, table),
+ table->cmp_fn);
+}
+
+void rte_efd_lookup_bulk(const struct rte_efd_table * const table,
+ const unsigned int socket_id, const int num_keys,
+ const void **key_list, efd_value_t * const value_list)
+{
+ int i;
+ uint32_t chunk_id_list[RTE_EFD_BURST_MAX];
+ uint32_t bin_id_list[RTE_EFD_BURST_MAX];
+ uint8_t bin_choice_list[RTE_EFD_BURST_MAX];
+ uint32_t group_id_list[RTE_EFD_BURST_MAX];
+ struct efd_online_group_entry *group;
+
+ struct efd_online_chunk *chunks = table->chunks[socket_id];
+
+ for (i = 0; i < num_keys; i++) {
+ efd_compute_ids(table, key_list[i], &chunk_id_list[i],
+ &bin_id_list[i]);
+ rte_prefetch0(&chunks[chunk_id_list[i]].bin_choice_list);
+ }
+
+ for (i = 0; i < num_keys; i++) {
+ bin_choice_list[i] = efd_get_choice(table, socket_id,
+ chunk_id_list[i], bin_id_list[i]);
+ group_id_list[i] =
+ efd_bin_to_group[bin_choice_list[i]][bin_id_list[i]];
+ group = &chunks[chunk_id_list[i]].groups[group_id_list[i]];
+ rte_prefetch0(group);
+ }
+
+ for (i = 0; i < num_keys; i++) {
+ group = &chunks[chunk_id_list[i]].groups[group_id_list[i]];
+ value_list[i] = efd_lookup_internal(group,
+ EFD_HASHFUNCA(key_list[i], table),
+ EFD_HASHFUNCB(key_list[i], table),
+ table->cmp_fn);
+ }
+}
diff --git a/lib/librte_efd/rte_efd.h b/lib/librte_efd/rte_efd.h
new file mode 100644
index 0000000..cb614c7
--- /dev/null
+++ b/lib/librte_efd/rte_efd.h
@@ -0,0 +1,294 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef _RTE_EFD_H_
+#define _RTE_EFD_H_
+
+/**
+ * @file
+ *
+ * RTE EFD Table
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*************************************************************************
+ * User selectable constants
+ *************************************************************************/
+
+/*
+ * If possible, best lookup performance will be achieved by ensuring that
+ * the entire table fits in the L3 cache.
+ *
+ * Some formulas for calculating various sizes are listed below:
+ *
+ * # of chunks =
+ * 2 ^ (ceiling(log2((requested # of rules) /
+ * (EFD_CHUNK_NUM_GROUPS * EFD_TARGET_GROUP_NUM_RULES))))
+ *
+ * Target # of rules = (# of chunks) * EFD_CHUNK_NUM_GROUPS *
+ * EFD_TARGET_GROUP_NUM_RULES
+ *
+ * Group Size (in bytes) = 4 (per value bit)
+ *
+ * Table size (in bytes) = RTE_EFD_VALUE_NUM_BITS * (# of chunks) *
+ * EFD_CHUNK_NUM_GROUPS * (group size)
+ */
+
+/**
+ * !!! This parameter should be adjusted for your application !!!
+ *
+ * This parameter adjusts the number of bits of value that can be
+ * stored in the table.
+ * For example, setting the number of bits to 3 will allow storing 8 values
+ * in the table (between 0 and 7).
+ *
+ * This number directly affects the performance of both lookups and insertion.
+ * In general, performance decreases as more bits are stored in the table.
+ *
+ * This number is directly proportional to the size of the online region
+ * used for lookups.
+ *
+ * Note that due to the way the CPU operates on memory, best lookup performance
+ * will be achieved when RTE_EFD_VALUE_NUM_BITS is a multiple of 8.
+ * These values align the hash indexes on 16-byte boundaries.
+ * The greatest performance drop is moving from 8->9 bits, 16->17 bits, etc.
+ *
+ * This value must be between 1 and 32
+ */
+#ifndef RTE_EFD_VALUE_NUM_BITS
+#define RTE_EFD_VALUE_NUM_BITS (8)
+#endif
+
+/*
+ * EFD_TARGET_GROUP_NUM_RULES:
+ * Adjusts how many groups/chunks are allocated at table creation time
+ * to support the requested number of rules. Higher values pack entries
+ * more tightly in memory, resulting in a smaller memory footprint
+ * for the online table.
+ * This comes at the cost of lower insert/update performance.
+ *
+ * EFD_MAX_GROUP_NUM_RULES:
+ * This adjusts the amount of offline memory allocated to store key/value
+ * pairs for the table. The recommended numbers are upper-bounds for
+ * this parameter
+ * - any higher and it becomes very unlikely that a perfect hash function
+ * can be found for that group size. This value should be at
+ * least 40% larger than EFD_TARGET_GROUP_NUM_RULES
+ *
+ * Recommended values for various lookuptable and hashfunc sizes are:
+ *
+ * HASH_FUNC_SIZE = 16, LOOKUPTBL_SIZE = 16:
+ * EFD_TARGET_GROUP_NUM_RULES = 22
+ * EFD_MAX_GROUP_NUM_RULES = 28
+ */
+#define EFD_TARGET_GROUP_NUM_RULES (22)
+#define EFD_MAX_GROUP_NUM_RULES (28LU)
+
+#define EFD_MIN_BALANCED_NUM_RULES 5
+
+/**
+ * Maximum number of keys that can be looked up in one call to efd_lookup_bulk
+ */
+#ifndef RTE_EFD_BURST_MAX
+#define RTE_EFD_BURST_MAX (32)
+#endif
+
+/** Maximum number of characters in efd name.*/
+#define RTE_EFD_NAMESIZE 32
+
+#if (RTE_EFD_VALUE_NUM_BITS > 0 && RTE_EFD_VALUE_NUM_BITS <= 8)
+typedef uint8_t efd_value_t;
+#elif (RTE_EFD_VALUE_NUM_BITS > 8 && RTE_EFD_VALUE_NUM_BITS <= 16)
+typedef uint16_t efd_value_t;
+#elif (RTE_EFD_VALUE_NUM_BITS > 16 && RTE_EFD_VALUE_NUM_BITS <= 32)
+typedef uint32_t efd_value_t;
+#else
+#error("RTE_EFD_VALUE_NUM_BITS must be in the range [1:32]")
+#endif
+
+/**
+ * Creates an EFD table with a single offline region and multiple per-socket
+ * internally-managed copies of the online table used for lookups
+ *
+ * @param name
+ * EFD table name
+ * @param max_num_rules
+ * Minimum number of rules the table should be sized to hold.
+ * Will be rounded up to the next smallest valid table size
+ * @param online_cpu_socket_bitmask
+ * Bitmask specifying which sockets should get a copy of the online table.
+ * LSB = socket 0, etc.
+ * @param offline_cpu_socket
+ * Identifies the socket where the offline table will be allocated
+ * (and most efficiently accessed in the case of updates/insertions)
+ *
+ * @return
+ * EFD table, or NULL if table allocation failed or the bitmask is invalid
+ */
+struct rte_efd_table *
+rte_efd_create(const char *name, uint32_t max_num_rules, uint32_t key_len,
+ uint8_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket);
+
+/**
+ * Releases the resources from an EFD table
+ *
+ * @param table
+ * Table to free
+ */
+void
+rte_efd_free(struct rte_efd_table *table);
+
+/**
+ * Find an existing EFD table object and return a pointer to it.
+ *
+ * @param name
+ * Name of the EFD table as passed to rte_efd_create()
+ * @return
+ * Pointer to EFD table or NULL if object not found
+ * with rte_errno set appropriately. Possible rte_errno values include:
+ * - ENOENT - value not available for return
+ */
+struct rte_efd_table*
+rte_efd_find_existing(const char *name);
+
+#define RTE_EFD_UPDATE_WARN_GROUP_FULL (1)
+#define RTE_EFD_UPDATE_NO_CHANGE (2)
+#define RTE_EFD_UPDATE_FAILED (3)
+
+/**
+ * Computes an updated table entry for the supplied key/value pair.
+ * The update is then immediately applied to the provided table and
+ * all socket-local copies of the chunks are updated.
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param key
+ * EFD table key to modify
+ * @param value
+ * Value to associate with the key
+ *
+ * @return
+ * RTE_EFD_UPDATE_WARN_GROUP_FULL
+ * Operation is insert, and the last available space in the
+ * key's group was just used
+ * Future inserts may fail as groups fill up
+ * This operation was still successful, and entry contains a valid update
+ * RTE_EFD_UPDATE_FAILED
+ * Either the EFD failed to find a suitable perfect hash or the group was full
+ * This is a fatal error, and the table is now in an indeterminite state
+ * RTE_EFD_UPDATE_NO_CHANGE
+ * Operation resulted in no change to the table (same value already exists)
+ * 0 - success
+ */
+int
+rte_efd_update(struct rte_efd_table *table, unsigned int socket_id,
+ const void *key, efd_value_t value);
+
+/**
+ * Removes any value currently associated with the specified key from the table
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param key
+ * EFD table key to delete
+ * @param prev_value
+ * If not NULL, will store the previous value here before deleting it
+ *
+ * @return
+ * 0 - successfully found and deleted the key
+ * nonzero otherwise
+ */
+int
+rte_efd_delete(struct rte_efd_table *table, unsigned int socket_id,
+ const void *key, efd_value_t *prev_value);
+
+/**
+ * Looks up the value associated with a key
+ *
+ * NOTE: Lookups will *always* succeed - this is a property of
+ * using a perfect hash table.
+ * If the specified key was never inserted, a pseudorandom answer will be returned.
+ * There is no way to know based on the lookup if the key was ever inserted
+ * originally, so this must be tracked elsewhere.
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param key
+ * EFD table key to look up
+ *
+ * @return
+ * Value associated with the key, or random junk if they key was never inserted
+ */
+efd_value_t
+rte_efd_lookup(const struct rte_efd_table *table, unsigned int socket_id,
+ const void *key);
+
+/**
+ * Looks up the value associated with several keys.
+ *
+ * NOTE: Lookups will *always* succeed - this is a property of
+ * using a perfect hash table.
+ * If the specified key was never inserted, a pseudorandom answer will be returned.
+ * There is no way to know based on the lookup if the key was ever inserted
+ * originally, so this must be tracked elsewhere.
+ *
+ * @param table
+ * EFD table to reference
+ * @param socket_id
+ * Socket ID to use to lookup existing value (ideally caller's socket id)
+ * @param num_keys
+ * Number of keys in the key_list array, must be less than RTE_EFD_BURST_MAX
+ * @param key_list
+ * Array of num_keys pointers which point to keys to look up
+ * @param value_list
+ * Array of size num_keys where lookup values will be stored
+ */
+void
+rte_efd_lookup_bulk(const struct rte_efd_table *table, unsigned int socket_id,
+ int num_keys, const void **key_list,
+ efd_value_t *value_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_EFD_H_ */
diff --git a/lib/librte_efd/rte_efd_version.map b/lib/librte_efd/rte_efd_version.map
new file mode 100644
index 0000000..91810b3
--- /dev/null
+++ b/lib/librte_efd/rte_efd_version.map
@@ -0,0 +1,12 @@
+DPDK_17.02 {
+ global:
+
+ rte_efd_create;
+ rte_efd_delete;
+ rte_efd_free;
+ rte_efd_lookup;
+ rte_efd_lookup_bulk;
+ rte_efd_update;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f75f0e2..3956849 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -86,6 +86,7 @@ _LDLIBS-y += --whole-archive

_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
_LDLIBS-$(CONFIG_RTE_LIBRTE_HASH) += -lrte_hash
+_LDLIBS-$(CONFIG_RTE_LIBRTE_EFD) += -lrte_efd
_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lrte_vhost

_LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS) += -lrte_kvargs
--
2.7.4
Pablo de Lara
2017-01-07 01:06:03 UTC
Permalink
Signed-off-by: Byron Marohn <***@intel.com>
Signed-off-by: Karla Saur <***@intel.com>
Signed-off-by: Saikrishna Edupuganti <***@intel.com>
Signed-off-by: Pablo de Lara <***@intel.com>
---
MAINTAINERS | 1 +
app/test/Makefile | 3 +
app/test/test_efd.c | 494 +++++++++++++++++++++++++++++++++++++++++++++++
app/test/test_efd_perf.c | 407 ++++++++++++++++++++++++++++++++++++++
4 files changed, 905 insertions(+)
create mode 100644 app/test/test_efd.c
create mode 100644 app/test/test_efd_perf.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9c60d67..d812962 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -532,6 +532,7 @@ EFD
M: Byron Marohn <***@intel.com>
M: Pablo de Lara Guarch <***@intel.com>
F: lib/librte_efd/
+F: app/test/test_efd*

Hashes
M: Bruce Richardson <***@intel.com>
diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..5adb26d 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -123,6 +123,9 @@ SRCS-y += test_logs.c
SRCS-y += test_memcpy.c
SRCS-y += test_memcpy_perf.c

+SRCS-$(CONFIG_RTE_LIBRTE_EFD) += test_efd.c
+SRCS-$(CONFIG_RTE_LIBRTE_EFD) += test_efd_perf.c
+
SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash.c
SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_thash.c
SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_perf.c
diff --git a/app/test/test_efd.c b/app/test/test_efd.c
new file mode 100644
index 0000000..1cc8608
--- /dev/null
+++ b/app/test/test_efd.c
@@ -0,0 +1,494 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <rte_memcpy.h>
+#include <rte_malloc.h>
+#include <rte_efd.h>
+#include <rte_byteorder.h>
+#include <rte_random.h>
+#include <rte_debug.h>
+#include <rte_ip.h>
+
+#include "test.h"
+
+#define EFD_TEST_KEY_LEN 8
+#define TABLE_SIZE (1 << 21)
+#define ITERATIONS 3
+static unsigned int test_socket_id;
+
+/* 5-tuple key type */
+struct flow_key {
+ uint32_t ip_src;
+ uint32_t ip_dst;
+ uint16_t port_src;
+ uint16_t port_dst;
+ uint8_t proto;
+} __attribute__((packed));
+/*
+ * Print out result of unit test efd operation.
+ */
+#if defined(UNIT_TEST_EFD_VERBOSE)
+
+static void print_key_info(const char *msg, const struct flow_key *key,
+ efd_value_t val)
+{
+ const uint8_t *p = (const uint8_t *) key;
+ unsigned int i;
+
+ printf("%s key:0x", msg);
+ for (i = 0; i < sizeof(struct flow_key); i++)
+ printf("%02X", p[i]);
+
+ printf(" @ val %d\n", val);
+}
+#else
+
+static void print_key_info(__attribute__((unused)) const char *msg,
+ __attribute__((unused)) const struct flow_key *key,
+ __attribute__((unused)) efd_value_t val)
+{
+}
+#endif
+
+/* Keys used by unit test functions */
+static struct flow_key keys[5] = {
+ {
+ .ip_src = IPv4(0x03, 0x02, 0x01, 0x00),
+ .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04),
+ .port_src = 0x0908,
+ .port_dst = 0x0b0a,
+ .proto = 0x0c,
+ },
+ {
+ .ip_src = IPv4(0x13, 0x12, 0x11, 0x10),
+ .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14),
+ .port_src = 0x1918,
+ .port_dst = 0x1b1a,
+ .proto = 0x1c,
+ },
+ {
+ .ip_src = IPv4(0x23, 0x22, 0x21, 0x20),
+ .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24),
+ .port_src = 0x2928,
+ .port_dst = 0x2b2a,
+ .proto = 0x2c,
+ },
+ {
+ .ip_src = IPv4(0x33, 0x32, 0x31, 0x30),
+ .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34),
+ .port_src = 0x3938,
+ .port_dst = 0x3b3a,
+ .proto = 0x3c,
+ },
+ {
+ .ip_src = IPv4(0x43, 0x42, 0x41, 0x40),
+ .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44),
+ .port_src = 0x4948,
+ .port_dst = 0x4b4a,
+ .proto = 0x4c,
+ }
+};
+/* Array to store the data */
+efd_value_t data[5];
+
+static inline uint8_t efd_get_all_sockets_bitmask(void)
+{
+ uint8_t all_cpu_sockets_bitmask = 0;
+ unsigned int i;
+ unsigned int next_lcore = rte_get_master_lcore();
+ const int val_true = 1, val_false = 0;
+ for (i = 0; i < rte_lcore_count(); i++) {
+ all_cpu_sockets_bitmask |= 1 << rte_lcore_to_socket_id(next_lcore);
+ next_lcore = rte_get_next_lcore(next_lcore, val_false, val_true);
+ }
+
+ return all_cpu_sockets_bitmask;
+}
+
+/*
+ * Basic sequence of operations for a single key:
+ * - add
+ * - lookup (hit)
+ * - delete
+ * Note: lookup (miss) is not applicable since this is a filter
+ */
+static int test_add_delete(void)
+{
+ struct rte_efd_table *handle;
+ /* test with standard add/lookup/delete functions */
+ efd_value_t prev_value;
+ printf("Entering %s\n", __func__);
+
+ handle = rte_efd_create("test_add_delete",
+ TABLE_SIZE, sizeof(struct flow_key),
+ efd_get_all_sockets_bitmask(), test_socket_id);
+ TEST_ASSERT_NOT_NULL(handle, "Error creating the EFD table\n");
+
+ data[0] = mrand48() & ((1 << RTE_EFD_VALUE_NUM_BITS) - 1);
+ TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[0],
+ data[0]),
+ "Error inserting the key");
+ print_key_info("Add", &keys[0], data[0]);
+
+ TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[0]),
+ data[0],
+ "failed to find key");
+
+ TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, &keys[0],
+ &prev_value),
+ "failed to delete key");
+ TEST_ASSERT_EQUAL(prev_value, data[0],
+ "failed to delete the expected value, got %d, "
+ "expected %d", prev_value, data[0]);
+ print_key_info("Del", &keys[0], data[0]);
+
+ rte_efd_free(handle);
+
+ return 0;
+}
+
+/*
+ * Sequence of operations for a single key:
+ * - add
+ * - lookup: hit
+ * - add: update
+ * - lookup: hit (updated data)
+ * - delete: hit
+ */
+static int test_add_update_delete(void)
+{
+ struct rte_efd_table *handle;
+ printf("Entering %s\n", __func__);
+ /* test with standard add/lookup/delete functions */
+ efd_value_t prev_value;
+ data[1] = mrand48() & ((1 << RTE_EFD_VALUE_NUM_BITS) - 1);
+
+ handle = rte_efd_create("test_add_update_delete", TABLE_SIZE,
+ sizeof(struct flow_key),
+ efd_get_all_sockets_bitmask(), test_socket_id);
+ TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n");
+
+ TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[1],
+ data[1]), "Error inserting the key");
+ print_key_info("Add", &keys[1], data[1]);
+
+ TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[1]),
+ data[1], "failed to find key");
+ print_key_info("Lkp", &keys[1], data[1]);
+
+ data[1] = data[1] + 1;
+ TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[1],
+ data[1]), "Error re-inserting the key");
+ print_key_info("Add", &keys[1], data[1]);
+
+ TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[1]),
+ data[1], "failed to find key");
+ print_key_info("Lkp", &keys[1], data[1]);
+
+ TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, &keys[1],
+ &prev_value), "failed to delete key");
+ TEST_ASSERT_EQUAL(prev_value, data[1],
+ "failed to delete the expected value, got %d, "
+ "expected %d", prev_value, data[1]);
+ print_key_info("Del", &keys[1], data[1]);
+
+
+ rte_efd_free(handle);
+ return 0;
+}
+
+/*
+ * Sequence of operations for find existing EFD table
+ *
+ * - create table
+ * - find existing table: hit
+ * - find non-existing table: miss
+ *
+ */
+static int test_efd_find_existing(void)
+{
+ struct rte_efd_table *handle = NULL, *result = NULL;
+
+ printf("Entering %s\n", __func__);
+
+ /* Create EFD table. */
+ handle = rte_efd_create("efd_find_existing", TABLE_SIZE,
+ sizeof(struct flow_key),
+ efd_get_all_sockets_bitmask(), test_socket_id);
+ TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n");
+
+ /* Try to find existing EFD table */
+ result = rte_efd_find_existing("efd_find_existing");
+ TEST_ASSERT_EQUAL(result, handle, "could not find existing efd table");
+
+ /* Try to find non-existing EFD table */
+ result = rte_efd_find_existing("efd_find_non_existing");
+ TEST_ASSERT_NULL(result, "found table that shouldn't exist");
+
+ /* Cleanup. */
+ rte_efd_free(handle);
+
+ return 0;
+}
+
+/*
+ * Sequence of operations for 5 keys
+ * - add keys
+ * - lookup keys: hit (bulk)
+ * - add keys (update)
+ * - lookup keys: hit (updated data)
+ * - delete keys : hit
+ */
+static int test_five_keys(void)
+{
+ struct rte_efd_table *handle;
+ const void *key_array[5] = {0};
+ efd_value_t result[5] = {0};
+ efd_value_t prev_value;
+ unsigned int i;
+ printf("Entering %s\n", __func__);
+
+ handle = rte_efd_create("test_five_keys", TABLE_SIZE,
+ sizeof(struct flow_key),
+ efd_get_all_sockets_bitmask(), test_socket_id);
+ TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n");
+
+ /* Setup data */
+ for (i = 0; i < 5; i++)
+ data[i] = mrand48() & ((1 << RTE_EFD_VALUE_NUM_BITS) - 1);
+
+ /* Add */
+ for (i = 0; i < 5; i++) {
+ TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id,
+ &keys[i], data[i]),
+ "Error inserting the key");
+ print_key_info("Add", &keys[i], data[i]);
+ }
+
+ /* Lookup */
+ for (i = 0; i < 5; i++)
+ key_array[i] = &keys[i];
+
+ rte_efd_lookup_bulk(handle, test_socket_id, 5,
+ (const void **) (void *) &key_array, result);
+
+ for (i = 0; i < 5; i++) {
+ TEST_ASSERT_EQUAL(result[i], data[i],
+ "bulk: failed to find key. Expected %d, got %d",
+ data[i], result[i]);
+ print_key_info("Lkp", &keys[i], data[i]);
+ }
+
+ /* Modify data (bulk) */
+ for (i = 0; i < 5; i++)
+ data[i] = data[i] + 1;
+
+ /* Add - update */
+ for (i = 0; i < 5; i++) {
+ TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id,
+ &keys[i], data[i]),
+ "Error inserting the key");
+ print_key_info("Add", &keys[i], data[i]);
+ }
+
+ /* Lookup */
+ for (i = 0; i < 5; i++) {
+ TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id,
+ &keys[i]), data[i],
+ "failed to find key");
+ print_key_info("Lkp", &keys[i], data[i]);
+ }
+
+ /* Delete */
+ for (i = 0; i < 5; i++) {
+ TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id,
+ &keys[i], &prev_value),
+ "failed to delete key");
+ TEST_ASSERT_EQUAL(prev_value, data[i],
+ "failed to delete the expected value, got %d, "
+ "expected %d", prev_value, data[i]);
+ print_key_info("Del", &keys[i], data[i]);
+ }
+
+
+ rte_efd_free(handle);
+
+ return 0;
+}
+
+/*
+ * Test to see the average table utilization (entries added/max entries)
+ * before hitting a random entry that cannot be added
+ */
+static int test_average_table_utilization(void)
+{
+ struct rte_efd_table *handle = NULL;
+ uint32_t num_rules_in = TABLE_SIZE;
+ uint8_t simple_key[EFD_TEST_KEY_LEN];
+ unsigned int i, j;
+ unsigned int added_keys, average_keys_added = 0;
+
+ printf("Evaluating table utilization and correctness, please wait\n");
+ fflush(stdout);
+
+ for (j = 0; j < ITERATIONS; j++) {
+ handle = rte_efd_create("test_efd", num_rules_in,
+ EFD_TEST_KEY_LEN, efd_get_all_sockets_bitmask(),
+ test_socket_id);
+ if (handle == NULL) {
+ printf("efd table creation failed\n");
+ return -1;
+ }
+
+ unsigned int succeeded = 0;
+ unsigned int lost_keys = 0;
+
+ /* Add random entries until key cannot be added */
+ for (added_keys = 0; added_keys < num_rules_in; added_keys++) {
+
+ for (i = 0; i < EFD_TEST_KEY_LEN; i++)
+ simple_key[i] = rte_rand() & 0xFF;
+
+ efd_value_t val = simple_key[0];
+
+ if (rte_efd_update(handle, test_socket_id, simple_key,
+ val))
+ break; /* continue;*/
+ if (rte_efd_lookup(handle, test_socket_id, simple_key)
+ != val)
+ lost_keys++;
+ else
+ succeeded++;
+ }
+
+ average_keys_added += succeeded;
+
+ /* Reset the table */
+ rte_efd_free(handle);
+
+ /* Print progress on operations */
+ printf("Added %10u Succeeded %10u Lost %10u\n",
+ added_keys, succeeded, lost_keys);
+ fflush(stdout);
+ }
+
+ average_keys_added /= ITERATIONS;
+
+ printf("\nAverage table utilization = %.2f%% (%u/%u)\n",
+ ((double) average_keys_added / num_rules_in * 100),
+ average_keys_added, num_rules_in);
+
+ return 0;
+}
+
+/*
+ * Do tests for EFD creation with bad parameters.
+ */
+static int test_efd_creation_with_bad_parameters(void)
+{
+ struct rte_efd_table *handle, *tmp;
+ printf("Entering %s, **Errors are expected **\n", __func__);
+
+ handle = rte_efd_create("creation_with_bad_parameters_0", TABLE_SIZE, 0,
+ efd_get_all_sockets_bitmask(), test_socket_id);
+ if (handle != NULL) {
+ rte_efd_free(handle);
+ printf("Impossible creating EFD table successfully "
+ "if key_len in parameter is zero\n");
+ return -1;
+ }
+
+ handle = rte_efd_create("creation_with_bad_parameters_1", TABLE_SIZE,
+ sizeof(struct flow_key), 0, test_socket_id);
+ if (handle != NULL) {
+ rte_efd_free(handle);
+ printf("Impossible creating EFD table successfully "
+ "with invalid socket bitmask\n");
+ return -1;
+ }
+
+ handle = rte_efd_create("creation_with_bad_parameters_2", TABLE_SIZE,
+ sizeof(struct flow_key), efd_get_all_sockets_bitmask(),
+ 255);
+ if (handle != NULL) {
+ rte_efd_free(handle);
+ printf("Impossible creating EFD table successfully "
+ "with invalid socket\n");
+ return -1;
+ }
+
+ /* test with same name should fail */
+ handle = rte_efd_create("same_name", TABLE_SIZE,
+ sizeof(struct flow_key),
+ efd_get_all_sockets_bitmask(), 0);
+ if (handle == NULL) {
+ printf("Cannot create first EFD table with 'same_name'\n");
+ return -1;
+ }
+ tmp = rte_efd_create("same_name", TABLE_SIZE, sizeof(struct flow_key),
+ efd_get_all_sockets_bitmask(), 0);
+ if (tmp != NULL) {
+ printf("Creation of EFD table with same name should fail\n");
+ rte_efd_free(handle);
+ rte_efd_free(tmp);
+ return -1;
+ }
+ rte_efd_free(handle);
+
+ printf("# Test successful. No more errors expected\n");
+
+ return 0;
+}
+
+static int
+test_efd(void)
+{
+
+ /* Unit tests */
+ if (test_add_delete() < 0)
+ return -1;
+ if (test_efd_find_existing() < 0)
+ return -1;
+ if (test_add_update_delete() < 0)
+ return -1;
+ if (test_five_keys() < 0)
+ return -1;
+ if (test_efd_creation_with_bad_parameters() < 0)
+ return -1;
+ if (test_average_table_utilization() < 0)
+ return -1;
+
+ return 0;
+}
+
+REGISTER_TEST_COMMAND(efd_autotest, test_efd);
diff --git a/app/test/test_efd_perf.c b/app/test/test_efd_perf.c
new file mode 100644
index 0000000..79fc893
--- /dev/null
+++ b/app/test/test_efd_perf.c
@@ -0,0 +1,407 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_malloc.h>
+#include <rte_random.h>
+#include <rte_efd.h>
+#include <rte_memcpy.h>
+#include <rte_thash.h>
+
+#include "test.h"
+#define NUM_KEYSIZES 10
+#define NUM_SHUFFLES 10
+#define MAX_KEYSIZE 64
+#define MAX_ENTRIES (1 << 19)
+#define KEYS_TO_ADD (MAX_ENTRIES * 3 / 4) /* 75% table utilization */
+#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */
+static unsigned int test_socket_id;
+
+static inline uint8_t efd_get_all_sockets_bitmask(void)
+{
+ uint8_t all_cpu_sockets_bitmask = 0;
+ unsigned int i;
+ unsigned int next_lcore = rte_get_master_lcore();
+ const int val_true = 1, val_false = 0;
+ for (i = 0; i < rte_lcore_count(); i++) {
+ all_cpu_sockets_bitmask |= 1 << rte_lcore_to_socket_id(next_lcore);
+ next_lcore = rte_get_next_lcore(next_lcore, val_false, val_true);
+ }
+
+ return all_cpu_sockets_bitmask;
+}
+
+enum operations {
+ ADD = 0,
+ LOOKUP,
+ LOOKUP_MULTI,
+ DELETE,
+ NUM_OPERATIONS
+};
+
+struct efd_perf_params {
+ struct rte_efd_table *efd_table;
+ uint32_t key_size;
+ unsigned int cycle;
+};
+
+static uint32_t hashtest_key_lens[] = {
+ /* standard key sizes */
+ 4, 8, 16, 32, 48, 64,
+ /* IPv4 SRC + DST + protocol, unpadded */
+ 9,
+ /* IPv4 5-tuple, unpadded */
+ 13,
+ /* IPv6 5-tuple, unpadded */
+ 37,
+ /* IPv6 5-tuple, padded to 8-byte boundary */
+ 40
+};
+
+/* Array to store number of cycles per operation */
+uint64_t cycles[NUM_KEYSIZES][NUM_OPERATIONS];
+
+/* Array to store the data */
+efd_value_t data[KEYS_TO_ADD];
+
+/* Array to store all input keys */
+uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE];
+
+/* Shuffle the keys that have been added, so lookups will be totally random */
+static void
+shuffle_input_keys(struct efd_perf_params *params)
+{
+ efd_value_t temp_data;
+ unsigned int i;
+ uint32_t swap_idx;
+ uint8_t temp_key[MAX_KEYSIZE];
+
+ for (i = KEYS_TO_ADD - 1; i > 0; i--) {
+ swap_idx = rte_rand() % i;
+
+ memcpy(temp_key, keys[i], hashtest_key_lens[params->cycle]);
+ temp_data = data[i];
+
+ memcpy(keys[i], keys[swap_idx], hashtest_key_lens[params->cycle]);
+ data[i] = data[swap_idx];
+
+ memcpy(keys[swap_idx], temp_key, hashtest_key_lens[params->cycle]);
+ data[swap_idx] = temp_data;
+ }
+}
+
+static int key_compare(const void *key1, const void *key2)
+{
+ return memcmp(key1, key2, MAX_KEYSIZE);
+}
+
+/*
+ * TODO: we could "error proof" these as done in test_hash_perf.c ln 165:
+ *
+ * The current setup may give errors if too full in some cases which we check
+ * for. However, since EFD allows for ~99% capacity, these errors are rare for
+ * #"KEYS_TO_ADD" which is 75% capacity.
+ */
+static int
+setup_keys_and_data(struct efd_perf_params *params, unsigned int cycle)
+{
+ unsigned int i, j;
+ int num_duplicates;
+
+ params->key_size = hashtest_key_lens[cycle];
+ params->cycle = cycle;
+
+ /* Reset all arrays */
+ for (i = 0; i < params->key_size; i++)
+ keys[0][i] = 0;
+
+ /* Generate a list of keys, some of which may be duplicates */
+ for (i = 0; i < KEYS_TO_ADD; i++) {
+ for (j = 0; j < params->key_size; j++)
+ keys[i][j] = rte_rand() & 0xFF;
+
+ data[i] = rte_rand() & ((1 << RTE_EFD_VALUE_NUM_BITS) - 1);
+ }
+
+ /* Remove duplicates from the keys array */
+ do {
+ num_duplicates = 0;
+
+ /* Sort the list of keys to make it easier to find duplicates */
+ qsort(keys, KEYS_TO_ADD, MAX_KEYSIZE, key_compare);
+
+ /* Sift through the list of keys and look for duplicates */
+ int num_duplicates = 0;
+ for (i = 0; i < KEYS_TO_ADD - 1; i++) {
+ if (memcmp(keys[i], keys[i + 1], params->key_size) == 0) {
+ /* This key already exists, try again */
+ num_duplicates++;
+ for (j = 0; j < params->key_size; j++)
+ keys[i][j] = rte_rand() & 0xFF;
+ }
+ }
+ } while (num_duplicates != 0);
+
+ /* Shuffle the random values again */
+ shuffle_input_keys(params);
+
+ params->efd_table = rte_efd_create("test_efd_perf",
+ MAX_ENTRIES, params->key_size,
+ efd_get_all_sockets_bitmask(), test_socket_id);
+ TEST_ASSERT_NOT_NULL(params->efd_table, "Error creating the efd table\n");
+
+ return 0;
+}
+
+static int
+timed_adds(struct efd_perf_params *params)
+{
+ const uint64_t start_tsc = rte_rdtsc();
+ unsigned int i, a;
+ int32_t ret;
+
+ for (i = 0; i < KEYS_TO_ADD; i++) {
+ ret = rte_efd_update(params->efd_table, test_socket_id, keys[i],
+ data[i]);
+ if (ret != 0) {
+ printf("Error %d in rte_efd_update - key=0x", ret);
+ for (a = 0; a < params->key_size; a++)
+ printf("%02x", keys[i][a]);
+ printf(" value=%d\n", data[i]);
+
+ return -1;
+ }
+ }
+
+ const uint64_t end_tsc = rte_rdtsc();
+ const uint64_t time_taken = end_tsc - start_tsc;
+
+ cycles[params->cycle][ADD] = time_taken / KEYS_TO_ADD;
+ return 0;
+}
+
+static int
+timed_lookups(struct efd_perf_params *params)
+{
+ unsigned int i, j, a;
+ const uint64_t start_tsc = rte_rdtsc();
+ efd_value_t ret_data;
+
+ for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) {
+ for (j = 0; j < KEYS_TO_ADD; j++) {
+ ret_data = rte_efd_lookup(params->efd_table,
+ test_socket_id, keys[j]);
+ if (ret_data != data[j]) {
+ printf("Value mismatch using rte_efd_lookup: "
+ "key #%d (0x", i);
+ for (a = 0; a < params->key_size; a++)
+ printf("%02x", keys[i][a]);
+ printf(")\n");
+ printf(" Expected %d, got %d\n", data[i],
+ ret_data);
+
+ return -1;
+ }
+
+ }
+ }
+
+ const uint64_t end_tsc = rte_rdtsc();
+ const uint64_t time_taken = end_tsc - start_tsc;
+
+ cycles[params->cycle][LOOKUP] = time_taken / NUM_LOOKUPS;
+
+ return 0;
+}
+
+static int
+timed_lookups_multi(struct efd_perf_params *params)
+{
+ unsigned int i, j, k, a;
+ efd_value_t result[RTE_EFD_BURST_MAX] = {0};
+ const void *keys_burst[RTE_EFD_BURST_MAX];
+ const uint64_t start_tsc = rte_rdtsc();
+
+ for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) {
+ for (j = 0; j < KEYS_TO_ADD / RTE_EFD_BURST_MAX; j++) {
+ for (k = 0; k < RTE_EFD_BURST_MAX; k++)
+ keys_burst[k] = keys[j * RTE_EFD_BURST_MAX + k];
+
+ rte_efd_lookup_bulk(params->efd_table, test_socket_id,
+ RTE_EFD_BURST_MAX,
+ keys_burst, result);
+
+ for (k = 0; k < RTE_EFD_BURST_MAX; k++) {
+ uint32_t data_idx = j * RTE_EFD_BURST_MAX + k;
+ if (result[k] != data[data_idx]) {
+ printf("Value mismatch using "
+ "rte_efd_lookup_bulk: key #%d "
+ "(0x", i);
+ for (a = 0; a < params->key_size; a++)
+ printf("%02x",
+ keys[data_idx][a]);
+ printf(")\n");
+ printf(" Expected %d, got %d\n",
+ data[data_idx], result[k]);
+
+ return -1;
+ }
+ }
+ }
+ }
+
+ const uint64_t end_tsc = rte_rdtsc();
+ const uint64_t time_taken = end_tsc - start_tsc;
+
+ cycles[params->cycle][LOOKUP_MULTI] = time_taken / NUM_LOOKUPS;
+
+ return 0;
+}
+
+static int
+timed_deletes(struct efd_perf_params *params)
+{
+ unsigned int i, a;
+ const uint64_t start_tsc = rte_rdtsc();
+ int32_t ret;
+
+ for (i = 0; i < KEYS_TO_ADD; i++) {
+ ret = rte_efd_delete(params->efd_table, test_socket_id, keys[i],
+ NULL);
+
+ if (ret != 0) {
+ printf("Error %d in rte_efd_delete - key=0x", ret);
+ for (a = 0; a < params->key_size; a++)
+ printf("%02x", keys[i][a]);
+ printf("\n");
+
+ return -1;
+ }
+ }
+
+ const uint64_t end_tsc = rte_rdtsc();
+ const uint64_t time_taken = end_tsc - start_tsc;
+
+ cycles[params->cycle][DELETE] = time_taken / KEYS_TO_ADD;
+
+ return 0;
+}
+
+static void
+perform_frees(struct efd_perf_params *params)
+{
+ if (params->efd_table != NULL) {
+ rte_efd_free(params->efd_table);
+ params->efd_table = NULL;
+ }
+}
+
+static int
+exit_with_fail(const char *testname, struct efd_perf_params *params,
+ unsigned int i)
+{
+
+ printf("<<<<<Test %s failed at keysize %d iteration %d >>>>>\n",
+ testname, hashtest_key_lens[params->cycle], i);
+ perform_frees(params);
+ return -1;
+}
+
+static int
+run_all_tbl_perf_tests(void)
+{
+ unsigned int i, j;
+ struct efd_perf_params params;
+
+ printf("Measuring performance, please wait\n");
+ fflush(stdout);
+
+ test_socket_id = rte_socket_id();
+
+ for (i = 0; i < NUM_KEYSIZES; i++) {
+
+ if (setup_keys_and_data(&params, i) < 0) {
+ printf("Could not create keys/data/table\n");
+ return -1;
+ }
+
+ if (timed_adds(&params) < 0)
+ return exit_with_fail("timed_adds", &params, i);
+
+ for (j = 0; j < NUM_SHUFFLES; j++)
+ shuffle_input_keys(&params);
+
+ if (timed_lookups(&params) < 0)
+ return exit_with_fail("timed_lookups", &params, i);
+
+ if (timed_lookups_multi(&params) < 0)
+ return exit_with_fail("timed_lookups_multi", &params, i);
+
+ if (timed_deletes(&params) < 0)
+ return exit_with_fail("timed_deletes", &params, i);
+
+ /* Print a dot to show progress on operations */
+ printf(".");
+ fflush(stdout);
+
+ perform_frees(&params);
+ }
+
+ printf("\nResults (in CPU cycles/operation)\n");
+ printf("-----------------------------------\n");
+ printf("\n%-18s%-18s%-18s%-18s%-18s\n",
+ "Keysize", "Add", "Lookup", "Lookup_bulk", "Delete");
+ for (i = 0; i < NUM_KEYSIZES; i++) {
+ printf("%-18d", hashtest_key_lens[i]);
+ for (j = 0; j < NUM_OPERATIONS; j++)
+ printf("%-18"PRIu64, cycles[i][j]);
+ printf("\n");
+ }
+ return 0;
+}
+
+static int
+test_efd_perf(void)
+{
+
+ if (run_all_tbl_perf_tests() < 0)
+ return -1;
+
+ return 0;
+}
+
+REGISTER_TEST_COMMAND(efd_perf_autotest, test_efd_perf);
--
2.7.4
Pablo de Lara
2017-01-07 01:06:04 UTC
Permalink
This new sample app, based on the client/server sample app,
shows the user an scenario using the EFD library.
It consists of:

- A front-end server which has an EFD table that stores the
node id for each flow key, which will distribute the incoming
packets to the different nodes

- A back-end node, which has a hash table where node checks,
after reading packets coming from the server, whether the packet
is meant to be used in such node, in which case it will be TXed,
or not, in which case, packet will be dropped.

Signed-off-by: Pablo de Lara <***@intel.com>
Signed-off-by: Saikrishna Edupuganti <***@intel.com>
---
MAINTAINERS | 1 +
doc/api/examples.dox | 4 +
examples/Makefile | 1 +
examples/flow_distributor/Makefile | 44 +++
examples/flow_distributor/distributor/Makefile | 57 ++++
examples/flow_distributor/distributor/args.c | 200 ++++++++++++
examples/flow_distributor/distributor/args.h | 39 +++
examples/flow_distributor/distributor/init.c | 371 ++++++++++++++++++++++
examples/flow_distributor/distributor/init.h | 76 +++++
examples/flow_distributor/distributor/main.c | 362 +++++++++++++++++++++
examples/flow_distributor/node/Makefile | 48 +++
examples/flow_distributor/node/node.c | 417 +++++++++++++++++++++++++
examples/flow_distributor/shared/common.h | 99 ++++++
13 files changed, 1719 insertions(+)
create mode 100644 examples/flow_distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/Makefile
create mode 100644 examples/flow_distributor/distributor/args.c
create mode 100644 examples/flow_distributor/distributor/args.h
create mode 100644 examples/flow_distributor/distributor/init.c
create mode 100644 examples/flow_distributor/distributor/init.h
create mode 100644 examples/flow_distributor/distributor/main.c
create mode 100644 examples/flow_distributor/node/Makefile
create mode 100644 examples/flow_distributor/node/node.c
create mode 100644 examples/flow_distributor/shared/common.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d812962..b124f6e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -533,6 +533,7 @@ M: Byron Marohn <***@intel.com>
M: Pablo de Lara Guarch <***@intel.com>
F: lib/librte_efd/
F: app/test/test_efd*
+F: examples/flow_distributor/

Hashes
M: Bruce Richardson <***@intel.com>
diff --git a/doc/api/examples.dox b/doc/api/examples.dox
index 1626852..c13e574 100644
--- a/doc/api/examples.dox
+++ b/doc/api/examples.dox
@@ -52,6 +52,10 @@
@example load_balancer/init.c
@example load_balancer/main.c
@example load_balancer/runtime.c
+@example flow_distributor/distributor/args.c
+@example flow_distributor/distributor/init.c
+@example flow_distributor/distributor/main.c
+@example flow_distributor/node/node.c
@example multi_process/client_server_mp/mp_client/client.c
@example multi_process/client_server_mp/mp_server/args.c
@example multi_process/client_server_mp/mp_server/init.c
diff --git a/examples/Makefile b/examples/Makefile
index d49c7f2..b404982 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -45,6 +45,7 @@ DIRS-y += dpdk_qat
endif
DIRS-y += ethtool
DIRS-y += exception_path
+DIRS-$(CONFIG_RTE_LIBRTE_EFD) += flow_distributor
DIRS-y += helloworld
DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += ip_pipeline
ifeq ($(CONFIG_RTE_LIBRTE_LPM),y)
diff --git a/examples/flow_distributor/Makefile b/examples/flow_distributor/Makefile
new file mode 100644
index 0000000..d085e49
--- /dev/null
+++ b/examples/flow_distributor/Makefile
@@ -0,0 +1,44 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += distributor
+DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += node
+
+include $(RTE_SDK)/mk/rte.extsubdir.mk
diff --git a/examples/flow_distributor/distributor/Makefile b/examples/flow_distributor/distributor/Makefile
new file mode 100644
index 0000000..5a709ab
--- /dev/null
+++ b/examples/flow_distributor/distributor/Makefile
@@ -0,0 +1,57 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV), "linuxapp")
+$(error This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+endif
+
+# binary name
+APP = distributor
+
+# all source are stored in SRCS-y
+SRCS-y := main.c init.c args.c
+
+INC := $(wildcard *.h)
+
+CFLAGS += $(WERROR_FLAGS) -O3
+CFLAGS += -I$(SRCDIR)/../shared
+
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/flow_distributor/distributor/args.c b/examples/flow_distributor/distributor/args.c
new file mode 100644
index 0000000..3bd1ad6
--- /dev/null
+++ b/examples/flow_distributor/distributor/args.c
@@ -0,0 +1,200 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <rte_memory.h>
+#include <rte_string_fns.h>
+
+#include "common.h"
+#include "args.h"
+#include "init.h"
+
+/* 1M flows by default */
+#define DEFAULT_NUM_FLOWS 0x100000
+
+/* global var for number of nodes - extern in header */
+uint8_t num_nodes;
+/* global var for number of flows - extern in header */
+uint32_t num_flows = DEFAULT_NUM_FLOWS;
+
+static const char *progname;
+
+/**
+ * Prints out usage information to stdout
+ */
+static void
+usage(void)
+{
+ printf("%s [EAL options] -- -p PORTMASK -n NUM_NODES -f NUM_FLOWS\n"
+ " -p PORTMASK: hexadecimal bitmask of ports to use\n"
+ " -n NUM_NODES: number of node processes to use\n"
+ " -f NUM_FLOWS: number of flows to be added in the EFD table\n",
+ progname);
+}
+
+/**
+ * The ports to be used by the application are passed in
+ * the form of a bitmask. This function parses the bitmask
+ * and places the port numbers to be used into the port[]
+ * array variable
+ */
+static int
+parse_portmask(uint8_t max_ports, const char *portmask)
+{
+ char *end = NULL;
+ unsigned long pm;
+ uint8_t count = 0;
+
+ if (portmask == NULL || *portmask == '\0')
+ return -1;
+
+ /* convert parameter to a number and verify */
+ pm = strtoul(portmask, &end, 16);
+ if (end == NULL || *end != '\0' || pm == 0)
+ return -1;
+
+ /* loop through bits of the mask and mark ports */
+ while (pm != 0) {
+ if (pm & 0x01) { /* bit is set in mask, use port */
+ if (count >= max_ports)
+ printf("WARNING: requested port %u not present"
+ " - ignoring\n", (unsigned int)count);
+ else
+ info->id[info->num_ports++] = count;
+ }
+ pm = (pm >> 1);
+ count++;
+ }
+
+ return 0;
+}
+
+/**
+ * Take the number of nodes parameter passed to the app
+ * and convert to a number to store in the num_nodes variable
+ */
+static int
+parse_num_nodes(const char *nodes)
+{
+ char *end = NULL;
+ unsigned long temp;
+
+ if (nodes == NULL || *nodes == '\0')
+ return -1;
+
+ temp = strtoul(nodes, &end, 10);
+ if (end == NULL || *end != '\0' || temp == 0)
+ return -1;
+
+ num_nodes = (uint8_t)temp;
+ return 0;
+}
+
+static int
+parse_num_flows(const char *flows)
+{
+ char *end = NULL;
+
+ /* parse hexadecimal string */
+ num_flows = strtoul(flows, &end, 16);
+ if ((flows[0] == '\0') || (end == NULL) || (*end != '\0'))
+ return -1;
+
+ if (num_flows == 0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * The application specific arguments follow the DPDK-specific
+ * arguments which are stripped by the DPDK init. This function
+ * processes these application arguments, printing usage info
+ * on error.
+ */
+int
+parse_app_args(uint8_t max_ports, int argc, char *argv[])
+{
+ int option_index, opt;
+ char **argvopt = argv;
+ static struct option lgopts[] = { /* no long options */
+ {NULL, 0, 0, 0 }
+ };
+ progname = argv[0];
+
+ while ((opt = getopt_long(argc, argvopt, "n:f:p:", lgopts,
+ &option_index)) != EOF) {
+ switch (opt) {
+ case 'p':
+ if (parse_portmask(max_ports, optarg) != 0) {
+ usage();
+ return -1;
+ }
+ break;
+ case 'n':
+ if (parse_num_nodes(optarg) != 0) {
+ usage();
+ return -1;
+ }
+ break;
+ case 'f':
+ if (parse_num_flows(optarg) != 0) {
+ usage();
+ return -1;
+ }
+ break;
+ default:
+ printf("ERROR: Unknown option '%c'\n", opt);
+ usage();
+ return -1;
+ }
+ }
+
+ if (info->num_ports == 0 || num_nodes == 0) {
+ usage();
+ return -1;
+ }
+
+ if (info->num_ports % 2 != 0) {
+ printf("ERROR: application requires an even "
+ "number of ports to use\n");
+ return -1;
+ }
+ return 0;
+}
diff --git a/examples/flow_distributor/distributor/args.h b/examples/flow_distributor/distributor/args.h
new file mode 100644
index 0000000..8b36148
--- /dev/null
+++ b/examples/flow_distributor/distributor/args.h
@@ -0,0 +1,39 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef _ARGS_H_
+#define _ARGS_H_
+
+int parse_app_args(uint8_t max_ports, int argc, char *argv[]);
+
+#endif /* ifndef _ARGS_H_ */
diff --git a/examples/flow_distributor/distributor/init.c b/examples/flow_distributor/distributor/init.c
new file mode 100644
index 0000000..5d3b1a6
--- /dev/null
+++ b/examples/flow_distributor/distributor/init.c
@@ -0,0 +1,371 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_byteorder.h>
+#include <rte_atomic.h>
+#include <rte_launch.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_branch_prediction.h>
+#include <rte_debug.h>
+#include <rte_ring.h>
+#include <rte_log.h>
+#include <rte_mempool.h>
+#include <rte_memcpy.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_cycles.h>
+#include <rte_efd.h>
+#include <rte_hash.h>
+
+#include "common.h"
+#include "args.h"
+#include "init.h"
+
+#define MBUFS_PER_NODE 1536
+#define MBUFS_PER_PORT 1536
+#define MBUF_CACHE_SIZE 512
+
+#define RTE_MP_RX_DESC_DEFAULT 512
+#define RTE_MP_TX_DESC_DEFAULT 512
+#define NODE_QUEUE_RINGSIZE 128
+
+#define NO_FLAGS 0
+
+/* The mbuf pool for packet rx */
+struct rte_mempool *pktmbuf_pool;
+
+/* array of info/queues for nodes */
+struct node *nodes;
+
+/* Flow distributor table */
+struct rte_efd_table *efd_table;
+
+/* Shared info between distributor and nodes */
+struct shared_info *info;
+
+/**
+ * Initialise the mbuf pool for packet reception for the NIC, and any other
+ * buffer pools needed by the app - currently none.
+ */
+static int
+init_mbuf_pools(void)
+{
+ const unsigned int num_mbufs = (num_nodes * MBUFS_PER_NODE) +
+ (info->num_ports * MBUFS_PER_PORT);
+
+ /*
+ * Don't pass single-producer/single-consumer flags to mbuf create as it
+ * seems faster to use a cache instead
+ */
+ printf("Creating mbuf pool '%s' [%u mbufs] ...\n",
+ PKTMBUF_POOL_NAME, num_mbufs);
+ pktmbuf_pool = rte_pktmbuf_pool_create(PKTMBUF_POOL_NAME, num_mbufs,
+ MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+
+ return pktmbuf_pool == NULL; /* 0 on success */
+}
+
+/**
+ * Initialise an individual port:
+ * - configure number of rx and tx rings
+ * - set up each rx ring, to pull from the main mbuf pool
+ * - set up each tx ring
+ * - start the port and report its status to stdout
+ */
+static int
+init_port(uint8_t port_num)
+{
+ /* for port configuration all features are off by default */
+ const struct rte_eth_conf port_conf = {
+ .rxmode = {
+ .mq_mode = ETH_MQ_RX_RSS
+ }
+ };
+ const uint16_t rx_rings = 1, tx_rings = num_nodes;
+ const uint16_t rx_ring_size = RTE_MP_RX_DESC_DEFAULT;
+ const uint16_t tx_ring_size = RTE_MP_TX_DESC_DEFAULT;
+
+ uint16_t q;
+ int retval;
+
+ printf("Port %u init ... ", (unsigned int)port_num);
+ fflush(stdout);
+
+ /*
+ * Standard DPDK port initialisation - config port, then set up
+ * rx and tx rings.
+ */
+ retval = rte_eth_dev_configure(port_num, rx_rings, tx_rings, &port_conf);
+ if (retval != 0)
+ return retval;
+
+ for (q = 0; q < rx_rings; q++) {
+ retval = rte_eth_rx_queue_setup(port_num, q, rx_ring_size,
+ rte_eth_dev_socket_id(port_num),
+ NULL, pktmbuf_pool);
+ if (retval < 0)
+ return retval;
+ }
+
+ for (q = 0; q < tx_rings; q++) {
+ retval = rte_eth_tx_queue_setup(port_num, q, tx_ring_size,
+ rte_eth_dev_socket_id(port_num),
+ NULL);
+ if (retval < 0)
+ return retval;
+ }
+
+ rte_eth_promiscuous_enable(port_num);
+
+ retval = rte_eth_dev_start(port_num);
+ if (retval < 0)
+ return retval;
+
+ printf("done:\n");
+
+ return 0;
+}
+
+/**
+ * Set up the DPDK rings which will be used to pass packets, via
+ * pointers, between the multi-process distributor and node processes.
+ * Each node needs one RX queue.
+ */
+static int
+init_shm_rings(void)
+{
+ unsigned int i;
+ unsigned int socket_id;
+ const char *q_name;
+ const unsigned int ringsize = NODE_QUEUE_RINGSIZE;
+
+ nodes = rte_malloc("node details",
+ sizeof(*nodes) * num_nodes, 0);
+ if (nodes == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot allocate memory for "
+ "node program details\n");
+
+ for (i = 0; i < num_nodes; i++) {
+ /* Create an RX queue for each node */
+ socket_id = rte_socket_id();
+ q_name = get_rx_queue_name(i);
+ nodes[i].rx_q = rte_ring_create(q_name,
+ ringsize, socket_id,
+ RING_F_SP_ENQ | RING_F_SC_DEQ);
+ if (nodes[i].rx_q == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot create rx ring queue "
+ "for node %u\n", i);
+ }
+ return 0;
+}
+
+/*
+ * Create flow distributor table which will contain all the flows
+ * that will be distributed among the nodes
+ */
+static void
+create_flow_distributor_table(void)
+{
+ uint8_t socket_id = rte_socket_id();
+
+ /* create table */
+ efd_table = rte_efd_create("flow table", num_flows * 2, sizeof(uint32_t),
+ 1 << socket_id, socket_id);
+
+ if (efd_table == NULL)
+ rte_exit(EXIT_FAILURE, "Problem creating the flow table\n");
+}
+
+static void
+populate_flow_distributor_table(void)
+{
+ unsigned int i;
+ int32_t ret;
+ uint32_t ip_dst;
+ uint8_t socket_id = rte_socket_id();
+ uint64_t node_id;
+
+ /* Add flows in table */
+ for (i = 0; i < num_flows; i++) {
+ node_id = i % num_nodes;
+
+ ip_dst = rte_cpu_to_be_32(i);
+ ret = rte_efd_update(efd_table, socket_id,
+ (void *)&ip_dst, (efd_value_t)node_id);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Unable to add entry %u in "
+ "flow distributor table\n", i);
+ }
+
+ printf("EFD table: Adding 0x%x keys\n", num_flows);
+}
+
+/* Check the link status of all ports in up to 9s, and print them finally */
+static void
+check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
+ uint8_t portid, count, all_ports_up, print_flag = 0;
+ struct rte_eth_link link;
+
+ printf("\nChecking link status");
+ fflush(stdout);
+ for (count = 0; count <= MAX_CHECK_TIME; count++) {
+ all_ports_up = 1;
+ for (portid = 0; portid < port_num; portid++) {
+ if ((port_mask & (1 << info->id[portid])) == 0)
+ continue;
+ memset(&link, 0, sizeof(link));
+ rte_eth_link_get_nowait(info->id[portid], &link);
+ /* print link status if flag set */
+ if (print_flag == 1) {
+ if (link.link_status)
+ printf("Port %d Link Up - speed %u "
+ "Mbps - %s\n", info->id[portid],
+ (unsigned int)link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ else
+ printf("Port %d Link Down\n",
+ (uint8_t)info->id[portid]);
+ continue;
+ }
+ /* clear all_ports_up flag if any link down */
+ if (link.link_status == ETH_LINK_DOWN) {
+ all_ports_up = 0;
+ break;
+ }
+ }
+ /* after finally printing all link status, get out */
+ if (print_flag == 1)
+ break;
+
+ if (all_ports_up == 0) {
+ printf(".");
+ fflush(stdout);
+ rte_delay_ms(CHECK_INTERVAL);
+ }
+
+ /* set the print_flag if all ports up or timeout */
+ if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
+ print_flag = 1;
+ printf("done\n");
+ }
+ }
+}
+
+/**
+ * Main init function for the multi-process distributor app,
+ * calls subfunctions to do each stage of the initialisation.
+ */
+int
+init(int argc, char *argv[])
+{
+ int retval;
+ const struct rte_memzone *mz;
+ uint8_t i, total_ports;
+
+ /* init EAL, parsing EAL args */
+ retval = rte_eal_init(argc, argv);
+ if (retval < 0)
+ return -1;
+ argc -= retval;
+ argv += retval;
+
+ /* get total number of ports */
+ total_ports = rte_eth_dev_count();
+
+ /* set up array for port data */
+ mz = rte_memzone_reserve(MZ_SHARED_INFO, sizeof(*info),
+ rte_socket_id(), NO_FLAGS);
+ if (mz == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot reserve memory zone "
+ "for port information\n");
+ memset(mz->addr, 0, sizeof(*info));
+ info = mz->addr;
+
+ /* parse additional, application arguments */
+ retval = parse_app_args(total_ports, argc, argv);
+ if (retval != 0)
+ return -1;
+
+ /* initialise mbuf pools */
+ retval = init_mbuf_pools();
+ if (retval != 0)
+ rte_exit(EXIT_FAILURE, "Cannot create needed mbuf pools\n");
+
+ /* now initialise the ports we will use */
+ for (i = 0; i < info->num_ports; i++) {
+ retval = init_port(info->id[i]);
+ if (retval != 0)
+ rte_exit(EXIT_FAILURE, "Cannot initialise port %u\n",
+ (unsigned int) i);
+ }
+
+ check_all_ports_link_status(info->num_ports, (~0x0));
+
+ /* initialise the node queues/rings for inter-eu comms */
+ init_shm_rings();
+
+ /* Create the flow distributor table */
+ create_flow_distributor_table();
+
+ /* Populate the flow distributor table */
+ populate_flow_distributor_table();
+
+ /* Share the total number of nodes */
+ info->num_nodes = num_nodes;
+
+ /* Share the total number of flows */
+ info->num_flows = num_flows;
+ return 0;
+}
diff --git a/examples/flow_distributor/distributor/init.h b/examples/flow_distributor/distributor/init.h
new file mode 100644
index 0000000..ea0c0d4
--- /dev/null
+++ b/examples/flow_distributor/distributor/init.h
@@ -0,0 +1,76 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef _INIT_H_
+#define _INIT_H_
+
+/*
+ * #include <rte_ring.h>
+ * #include "args.h"
+ */
+
+/*
+ * Define a node structure with all needed info, including
+ * stats from the nodes.
+ */
+struct node {
+ struct rte_ring *rx_q;
+ unsigned int node_id;
+ /* these stats hold how many packets the node will actually receive,
+ * and how many packets were dropped because the node's queue was full.
+ * The port-info stats, in contrast, record how many packets were received
+ * or transmitted on an actual NIC port.
+ */
+ struct {
+ uint64_t rx;
+ uint64_t rx_drop;
+ } stats;
+};
+
+extern struct rte_efd_table *efd_table;
+extern struct node *nodes;
+
+/*
+ * shared information between distributor and nodes: number of clients,
+ * port numbers, rx and tx stats etc.
+ */
+extern struct shared_info *info;
+
+extern struct rte_mempool *pktmbuf_pool;
+extern uint8_t num_nodes;
+extern unsigned int num_sockets;
+extern uint32_t num_flows;
+
+int init(int argc, char *argv[]);
+
+#endif /* ifndef _INIT_H_ */
diff --git a/examples/flow_distributor/distributor/main.c b/examples/flow_distributor/distributor/main.c
new file mode 100644
index 0000000..678b8ff
--- /dev/null
+++ b/examples/flow_distributor/distributor/main.c
@@ -0,0 +1,362 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <inttypes.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <netinet/ip.h>
+
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_byteorder.h>
+#include <rte_launch.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_branch_prediction.h>
+#include <rte_atomic.h>
+#include <rte_ring.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_mempool.h>
+#include <rte_memcpy.h>
+#include <rte_mbuf.h>
+#include <rte_ether.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ethdev.h>
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_efd.h>
+#include <rte_ip.h>
+
+#include "common.h"
+#include "args.h"
+#include "init.h"
+
+/*
+ * When doing reads from the NIC or the node queues,
+ * use this batch size
+ */
+#define PACKET_READ_SIZE 32
+
+/*
+ * Local buffers to put packets in, used to send packets in bursts to the
+ * nodes
+ */
+struct node_rx_buf {
+ struct rte_mbuf *buffer[PACKET_READ_SIZE];
+ uint16_t count;
+};
+
+struct flow_distributor_stats {
+ uint64_t distributed;
+ uint64_t drop;
+} flow_dist_stats;
+
+/* One buffer per node rx queue - dynamically allocate array */
+static struct node_rx_buf *cl_rx_buf;
+
+static const char *
+get_printable_mac_addr(uint8_t port)
+{
+ static const char err_address[] = "00:00:00:00:00:00";
+ static char addresses[RTE_MAX_ETHPORTS][sizeof(err_address)];
+ struct ether_addr mac;
+
+ if (unlikely(port >= RTE_MAX_ETHPORTS))
+ return err_address;
+ if (unlikely(addresses[port][0] == '\0')) {
+ rte_eth_macaddr_get(port, &mac);
+ snprintf(addresses[port], sizeof(addresses[port]),
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac.addr_bytes[0], mac.addr_bytes[1],
+ mac.addr_bytes[2], mac.addr_bytes[3],
+ mac.addr_bytes[4], mac.addr_bytes[5]);
+ }
+ return addresses[port];
+}
+
+/*
+ * This function displays the recorded statistics for each port
+ * and for each node. It uses ANSI terminal codes to clear
+ * screen when called. It is called from a single non-master
+ * thread in the distributor process, when the process is run with more
+ * than one lcore enabled.
+ */
+static void
+do_stats_display(void)
+{
+ unsigned int i, j;
+ const char clr[] = {27, '[', '2', 'J', '\0'};
+ const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'};
+ uint64_t port_tx[RTE_MAX_ETHPORTS], port_tx_drop[RTE_MAX_ETHPORTS];
+ uint64_t node_tx[MAX_NODES], node_tx_drop[MAX_NODES];
+
+ /* to get TX stats, we need to do some summing calculations */
+ memset(port_tx, 0, sizeof(port_tx));
+ memset(port_tx_drop, 0, sizeof(port_tx_drop));
+ memset(node_tx, 0, sizeof(node_tx));
+ memset(node_tx_drop, 0, sizeof(node_tx_drop));
+
+ for (i = 0; i < num_nodes; i++) {
+ const struct tx_stats *tx = &info->tx_stats[i];
+
+ for (j = 0; j < info->num_ports; j++) {
+ const uint64_t tx_val = tx->tx[info->id[j]];
+ const uint64_t drop_val = tx->tx_drop[info->id[j]];
+
+ port_tx[j] += tx_val;
+ port_tx_drop[j] += drop_val;
+ node_tx[i] += tx_val;
+ node_tx_drop[i] += drop_val;
+ }
+ }
+
+ /* Clear screen and move to top left */
+ printf("%s%s", clr, topLeft);
+
+ printf("PORTS\n");
+ printf("-----\n");
+ for (i = 0; i < info->num_ports; i++)
+ printf("Port %u: '%s'\t", (unsigned int)info->id[i],
+ get_printable_mac_addr(info->id[i]));
+ printf("\n\n");
+ for (i = 0; i < info->num_ports; i++) {
+ printf("Port %u - rx: %9"PRIu64"\t"
+ "tx: %9"PRIu64"\n",
+ (unsigned int)info->id[i], info->rx_stats.rx[i],
+ port_tx[i]);
+ }
+
+ printf("\nFLOW DISTRIBUTOR\n");
+ printf("-----\n");
+ printf("distributed: %9"PRIu64", drop: %9"PRIu64"\n",
+ flow_dist_stats.distributed, flow_dist_stats.drop);
+
+ printf("\nNODES\n");
+ printf("-------\n");
+ for (i = 0; i < num_nodes; i++) {
+ const unsigned long long rx = nodes[i].stats.rx;
+ const unsigned long long rx_drop = nodes[i].stats.rx_drop;
+ const struct filter_stats *filter = &info->filter_stats[i];
+
+ printf("Node %2u - rx: %9llu, rx_drop: %9llu\n"
+ " tx: %9"PRIu64", tx_drop: %9"PRIu64"\n"
+ " filter_passed: %9"PRIu64", "
+ "filter_drop: %9"PRIu64"\n",
+ i, rx, rx_drop, node_tx[i], node_tx_drop[i],
+ filter->passed, filter->drop);
+ }
+
+ printf("\n");
+}
+
+/*
+ * The function called from each non-master lcore used by the process.
+ * The test_and_set function is used to randomly pick a single lcore on which
+ * the code to display the statistics will run. Otherwise, the code just
+ * repeatedly sleeps.
+ */
+static int
+sleep_lcore(__attribute__((unused)) void *dummy)
+{
+ /* Used to pick a display thread - static, so zero-initialised */
+ static rte_atomic32_t display_stats;
+
+ /* Only one core should display stats */
+ if (rte_atomic32_test_and_set(&display_stats)) {
+ const unsigned int sleeptime = 1;
+
+ printf("Core %u displaying statistics\n", rte_lcore_id());
+
+ /* Longer initial pause so above printf is seen */
+ sleep(sleeptime * 3);
+
+ /* Loop forever: sleep always returns 0 or <= param */
+ while (sleep(sleeptime) <= sleeptime)
+ do_stats_display();
+ }
+ return 0;
+}
+
+/*
+ * Function to set all the node statistic values to zero.
+ * Called at program startup.
+ */
+static void
+clear_stats(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_nodes; i++)
+ nodes[i].stats.rx = nodes[i].stats.rx_drop = 0;
+}
+
+/*
+ * send a burst of traffic to a node, assuming there are packets
+ * available to be sent to this node
+ */
+static void
+flush_rx_queue(uint16_t node)
+{
+ uint16_t j;
+ struct node *cl;
+
+ if (cl_rx_buf[node].count == 0)
+ return;
+
+ cl = &nodes[node];
+ if (rte_ring_enqueue_bulk(cl->rx_q, (void **)cl_rx_buf[node].buffer,
+ cl_rx_buf[node].count) != 0){
+ for (j = 0; j < cl_rx_buf[node].count; j++)
+ rte_pktmbuf_free(cl_rx_buf[node].buffer[j]);
+ cl->stats.rx_drop += cl_rx_buf[node].count;
+ } else
+ cl->stats.rx += cl_rx_buf[node].count;
+
+ cl_rx_buf[node].count = 0;
+}
+
+/*
+ * marks a packet down to be sent to a particular node process
+ */
+static inline void
+enqueue_rx_packet(uint8_t node, struct rte_mbuf *buf)
+{
+ cl_rx_buf[node].buffer[cl_rx_buf[node].count++] = buf;
+}
+
+/*
+ * This function takes a group of packets and routes them
+ * individually to the node process. Very simply round-robins the packets
+ * without checking any of the packet contents.
+ */
+static void
+process_packets(uint32_t port_num __rte_unused, struct rte_mbuf *pkts[],
+ uint16_t rx_count, unsigned int socket_id)
+{
+ uint16_t i;
+ uint8_t node;
+ efd_value_t data[RTE_EFD_BURST_MAX];
+ const void *key_ptrs[RTE_EFD_BURST_MAX];
+
+ struct ipv4_hdr *ipv4_hdr;
+ uint32_t ipv4_dst_ip[RTE_EFD_BURST_MAX];
+
+ for (i = 0; i < rx_count; i++) {
+ /* Handle IPv4 header.*/
+ ipv4_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct ipv4_hdr *,
+ sizeof(struct ether_hdr));
+ ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
+ key_ptrs[i] = (void *)&ipv4_dst_ip[i];
+ }
+
+ rte_efd_lookup_bulk(efd_table, socket_id, rx_count,
+ (const void **) key_ptrs, data);
+ for (i = 0; i < rx_count; i++) {
+ node = (uint8_t) ((uintptr_t)data[i]);
+
+ if (node >= num_nodes) {
+ /*
+ * Node is out of range, which means that
+ * flow has not been inserted
+ */
+ flow_dist_stats.drop++;
+ rte_pktmbuf_free(pkts[i]);
+ } else {
+ flow_dist_stats.distributed++;
+ enqueue_rx_packet(node, pkts[i]);
+ }
+ }
+
+ for (i = 0; i < num_nodes; i++)
+ flush_rx_queue(i);
+}
+
+/*
+ * Function called by the master lcore of the DPDK process.
+ */
+static void
+do_packet_forwarding(void)
+{
+ unsigned int port_num = 0; /* indexes the port[] array */
+ unsigned int socket_id = rte_socket_id();
+
+ for (;;) {
+ struct rte_mbuf *buf[PACKET_READ_SIZE];
+ uint16_t rx_count;
+
+ /* read a port */
+ rx_count = rte_eth_rx_burst(info->id[port_num], 0,
+ buf, PACKET_READ_SIZE);
+ info->rx_stats.rx[port_num] += rx_count;
+
+ /* Now process the NIC packets read */
+ if (likely(rx_count > 0))
+ process_packets(port_num, buf, rx_count, socket_id);
+
+ /* move to next port */
+ if (++port_num == info->num_ports)
+ port_num = 0;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ /* initialise the system */
+ if (init(argc, argv) < 0)
+ return -1;
+ RTE_LOG(INFO, APP, "Finished Process Init.\n");
+
+ cl_rx_buf = calloc(num_nodes, sizeof(cl_rx_buf[0]));
+
+ /* clear statistics */
+ clear_stats();
+
+ /* put all other cores to sleep bar master */
+ rte_eal_mp_remote_launch(sleep_lcore, NULL, SKIP_MASTER);
+
+ do_packet_forwarding();
+ return 0;
+}
diff --git a/examples/flow_distributor/node/Makefile b/examples/flow_distributor/node/Makefile
new file mode 100644
index 0000000..59aac28
--- /dev/null
+++ b/examples/flow_distributor/node/Makefile
@@ -0,0 +1,48 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+# 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 Intel Corporation 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
+# OWNER 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.
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# binary name
+APP = node
+
+# all source are stored in SRCS-y
+SRCS-y := node.c
+
+CFLAGS += $(WERROR_FLAGS) -O3
+CFLAGS += -I$(SRCDIR)/../shared
+
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/flow_distributor/node/node.c b/examples/flow_distributor/node/node.c
new file mode 100644
index 0000000..24fb444
--- /dev/null
+++ b/examples/flow_distributor/node/node.c
@@ -0,0 +1,417 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_log.h>
+#include <rte_per_lcore.h>
+#include <rte_launch.h>
+#include <rte_lcore.h>
+#include <rte_ring.h>
+#include <rte_launch.h>
+#include <rte_lcore.h>
+#include <rte_debug.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+#include <rte_ip.h>
+
+#include "common.h"
+
+/* Number of packets to attempt to read from queue */
+#define PKT_READ_SIZE ((uint16_t)32)
+
+/*
+ * Our node id number - tells us which rx queue to read, and NIC TX
+ * queue to write to.
+ */
+static uint8_t node_id;
+
+#define MBQ_CAPACITY 32
+
+/* maps input ports to output ports for packets */
+static uint8_t output_ports[RTE_MAX_ETHPORTS];
+
+/* buffers up a set of packet that are ready to send */
+struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
+
+/* shared data from distributor. We update statistics here */
+static struct tx_stats *tx_stats;
+
+static struct filter_stats *filter_stats;
+
+/*
+ * print a usage message
+ */
+static void
+usage(const char *progname)
+{
+ printf("Usage: %s [EAL args] -- -n <node_id>\n\n", progname);
+}
+
+/*
+ * Convert the node id number from a string to an int.
+ */
+static int
+parse_node_num(const char *node)
+{
+ char *end = NULL;
+ unsigned long temp;
+
+ if (node == NULL || *node == '\0')
+ return -1;
+
+ temp = strtoul(node, &end, 10);
+ if (end == NULL || *end != '\0')
+ return -1;
+
+ node_id = (uint8_t)temp;
+ return 0;
+}
+
+/*
+ * Parse the application arguments to the node app.
+ */
+static int
+parse_app_args(int argc, char *argv[])
+{
+ int option_index, opt;
+ char **argvopt = argv;
+ const char *progname = NULL;
+ static struct option lgopts[] = { /* no long options */
+ {NULL, 0, 0, 0 }
+ };
+ progname = argv[0];
+
+ while ((opt = getopt_long(argc, argvopt, "n:", lgopts,
+ &option_index)) != EOF) {
+ switch (opt) {
+ case 'n':
+ if (parse_node_num(optarg) != 0) {
+ usage(progname);
+ return -1;
+ }
+ break;
+ default:
+ usage(progname);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Tx buffer error callback
+ */
+static void
+flush_tx_error_callback(struct rte_mbuf **unsent, uint16_t count,
+ void *userdata) {
+ int i;
+ uint8_t port_id = (uintptr_t)userdata;
+
+ tx_stats->tx_drop[port_id] += count;
+
+ /* free the mbufs which failed from transmit */
+ for (i = 0; i < count; i++)
+ rte_pktmbuf_free(unsent[i]);
+
+}
+
+static void
+configure_tx_buffer(uint8_t port_id, uint16_t size)
+{
+ int ret;
+
+ /* Initialize TX buffers */
+ tx_buffer[port_id] = rte_zmalloc_socket("tx_buffer",
+ RTE_ETH_TX_BUFFER_SIZE(size), 0,
+ rte_eth_dev_socket_id(port_id));
+ if (tx_buffer[port_id] == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx "
+ "on port %u\n", (unsigned int) port_id);
+
+ rte_eth_tx_buffer_init(tx_buffer[port_id], size);
+
+ ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[port_id],
+ flush_tx_error_callback, (void *)(intptr_t)port_id);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Cannot set error callback for "
+ "tx buffer on port %u\n", (unsigned int) port_id);
+}
+
+/*
+ * set up output ports so that all traffic on port gets sent out
+ * its paired port. Index using actual port numbers since that is
+ * what comes in the mbuf structure.
+ */
+static void
+configure_output_ports(const struct shared_info *info)
+{
+ int i;
+
+ if (info->num_ports > RTE_MAX_ETHPORTS)
+ rte_exit(EXIT_FAILURE, "Too many ethernet ports. "
+ "RTE_MAX_ETHPORTS = %u\n",
+ (unsigned int)RTE_MAX_ETHPORTS);
+ for (i = 0; i < info->num_ports - 1; i += 2) {
+ uint8_t p1 = info->id[i];
+ uint8_t p2 = info->id[i+1];
+
+ output_ports[p1] = p2;
+ output_ports[p2] = p1;
+
+ configure_tx_buffer(p1, MBQ_CAPACITY);
+ configure_tx_buffer(p2, MBQ_CAPACITY);
+
+ }
+}
+
+/*
+ * Create the hash table that will contain the flows that
+ * the node will handle, which will be used to decide if packet
+ * is transmitted or dropped.
+ */
+static struct rte_hash *
+create_hash_table(const struct shared_info *info)
+{
+ uint32_t num_flows_node = info->num_flows / info->num_nodes;
+ char name[RTE_HASH_NAMESIZE];
+ struct rte_hash *h;
+
+ /* create table */
+ struct rte_hash_parameters hash_params = {
+ .entries = num_flows_node * 2, /* table load = 50% */
+ .key_len = sizeof(uint32_t), /* Store IPv4 dest IP address */
+ .socket_id = rte_socket_id(),
+ .hash_func_init_val = 0,
+ };
+
+ snprintf(name, sizeof(name), "hash_table_%d", node_id);
+ hash_params.name = name;
+ h = rte_hash_create(&hash_params);
+
+ if (h == NULL)
+ rte_exit(EXIT_FAILURE,
+ "Problem creating the hash table for node %d\n",
+ node_id);
+ return h;
+}
+
+static void
+populate_hash_table(const struct rte_hash *h, const struct shared_info *info)
+{
+ unsigned int i;
+ int32_t ret;
+ uint32_t ip_dst;
+ uint32_t num_flows_node = 0;
+ uint64_t target_node;
+
+ /* Add flows in table */
+ for (i = 0; i < info->num_flows; i++) {
+ target_node = i % info->num_nodes;
+ if (target_node != node_id)
+ continue;
+
+ ip_dst = rte_cpu_to_be_32(i);
+
+ ret = rte_hash_add_key(h, (void *) &ip_dst);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Unable to add entry %u "
+ "in hash table\n", i);
+ else
+ num_flows_node++;
+
+ }
+
+ printf("Hash table: Adding 0x%x keys\n", num_flows_node);
+}
+
+/*
+ * This function performs routing of packets
+ * Just sends each input packet out an output port based solely on the input
+ * port it arrived on.
+ */
+static inline void
+transmit_packet(struct rte_mbuf *buf)
+{
+ int sent;
+ const uint8_t in_port = buf->port;
+ const uint8_t out_port = output_ports[in_port];
+ struct rte_eth_dev_tx_buffer *buffer = tx_buffer[out_port];
+
+ sent = rte_eth_tx_buffer(out_port, node_id, buffer, buf);
+ if (sent)
+ tx_stats->tx[out_port] += sent;
+
+}
+
+static inline void
+handle_packets(struct rte_hash *h, struct rte_mbuf **bufs, uint16_t num_packets)
+{
+ struct ipv4_hdr *ipv4_hdr;
+ uint32_t ipv4_dst_ip[PKT_READ_SIZE];
+ const void *key_ptrs[PKT_READ_SIZE];
+ unsigned int i;
+ int32_t positions[PKT_READ_SIZE] = {0};
+
+ for (i = 0; i < num_packets; i++) {
+ /* Handle IPv4 header.*/
+ ipv4_hdr = rte_pktmbuf_mtod_offset(bufs[i], struct ipv4_hdr *,
+ sizeof(struct ether_hdr));
+ ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
+ key_ptrs[i] = &ipv4_dst_ip[i];
+ }
+ /* Check if packets belongs to any flows handled by this node */
+ rte_hash_lookup_bulk(h, key_ptrs, num_packets, positions);
+
+ for (i = 0; i < num_packets; i++) {
+ if (likely(positions[i] >= 0)) {
+ filter_stats->passed++;
+ transmit_packet(bufs[i]);
+ } else {
+ filter_stats->drop++;
+ /* Drop packet, as flow is not handled by this node */
+ rte_pktmbuf_free(bufs[i]);
+ }
+ }
+}
+
+/*
+ * Application main function - loops through
+ * receiving and processing packets. Never returns
+ */
+int
+main(int argc, char *argv[])
+{
+ const struct rte_memzone *mz;
+ struct rte_ring *rx_ring;
+ struct rte_hash *h;
+ struct rte_mempool *mp;
+ struct shared_info *info;
+ int need_flush = 0; /* indicates whether we have unsent packets */
+ int retval;
+ void *pkts[PKT_READ_SIZE];
+ uint16_t sent;
+
+ retval = rte_eal_init(argc, argv);
+ if (retval < 0)
+ return -1;
+ argc -= retval;
+ argv += retval;
+
+ if (parse_app_args(argc, argv) < 0)
+ rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n");
+
+ if (rte_eth_dev_count() == 0)
+ rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
+
+ rx_ring = rte_ring_lookup(get_rx_queue_name(node_id));
+ if (rx_ring == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get RX ring - "
+ "is distributor process running?\n");
+
+ mp = rte_mempool_lookup(PKTMBUF_POOL_NAME);
+ if (mp == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n");
+
+ mz = rte_memzone_lookup(MZ_SHARED_INFO);
+ if (mz == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get port info structure\n");
+ info = mz->addr;
+ tx_stats = &(info->tx_stats[node_id]);
+ filter_stats = &(info->filter_stats[node_id]);
+
+ configure_output_ports(info);
+
+ h = create_hash_table(info);
+
+ populate_hash_table(h, info);
+
+ RTE_LOG(INFO, APP, "Finished Process Init.\n");
+
+ printf("\nNode process %d handling packets\n", node_id);
+ printf("[Press Ctrl-C to quit ...]\n");
+
+ for (;;) {
+ uint16_t rx_pkts = PKT_READ_SIZE;
+ uint8_t port;
+
+ /*
+ * Try dequeuing max possible packets first, if that fails,
+ * get the most we can. Loop body should only execute once,
+ * maximum
+ */
+ while (rx_pkts > 0 &&
+ unlikely(rte_ring_dequeue_bulk(rx_ring, pkts,
+ rx_pkts) != 0))
+ rx_pkts = (uint16_t)RTE_MIN(rte_ring_count(rx_ring),
+ PKT_READ_SIZE);
+
+ if (unlikely(rx_pkts == 0)) {
+ if (need_flush)
+ for (port = 0; port < info->num_ports; port++) {
+ sent = rte_eth_tx_buffer_flush(
+ info->id[port],
+ node_id,
+ tx_buffer[port]);
+ if (unlikely(sent))
+ tx_stats->tx[port] += sent;
+ }
+ need_flush = 0;
+ continue;
+ }
+
+ handle_packets(h, (struct rte_mbuf **)pkts, rx_pkts);
+
+ need_flush = 1;
+ }
+}
diff --git a/examples/flow_distributor/shared/common.h b/examples/flow_distributor/shared/common.h
new file mode 100644
index 0000000..66c5574
--- /dev/null
+++ b/examples/flow_distributor/shared/common.h
@@ -0,0 +1,99 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * 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 Intel Corporation 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
+ * OWNER 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.
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <rte_hash_crc.h>
+#include <rte_hash.h>
+
+#define MAX_NODES 16
+/*
+ * Shared port info, including statistics information for display by distributor.
+ * Structure will be put in a memzone.
+ * - All port id values share one cache line as this data will be read-only
+ * during operation.
+ * - All rx statistic values share cache lines, as this data is written only
+ * by the distributor process. (rare reads by stats display)
+ * - The tx statistics have values for all ports per cache line, but the stats
+ * themselves are written by the nodes, so we have a distinct set, on different
+ * cache lines for each node to use.
+ */
+struct rx_stats {
+ uint64_t rx[RTE_MAX_ETHPORTS];
+} __rte_cache_aligned;
+
+struct tx_stats {
+ uint64_t tx[RTE_MAX_ETHPORTS];
+ uint64_t tx_drop[RTE_MAX_ETHPORTS];
+} __rte_cache_aligned;
+
+struct filter_stats {
+ uint64_t drop;
+ uint64_t passed;
+} __rte_cache_aligned;
+
+struct shared_info {
+ uint8_t num_nodes;
+ uint8_t num_ports;
+ uint32_t num_flows;
+ uint8_t id[RTE_MAX_ETHPORTS];
+ struct rx_stats rx_stats;
+ struct tx_stats tx_stats[MAX_NODES];
+ struct filter_stats filter_stats[MAX_NODES];
+};
+
+/* define common names for structures shared between distributor and node */
+#define MP_NODE_RXQ_NAME "MProc_Node_%u_RX"
+#define PKTMBUF_POOL_NAME "MProc_pktmbuf_pool"
+#define MZ_SHARED_INFO "MProc_shared_info"
+
+/*
+ * Given the rx queue name template above, get the queue name
+ */
+static inline const char *
+get_rx_queue_name(unsigned int id)
+{
+ /*
+ * Buffer for return value. Size calculated by %u being replaced
+ * by maximum 3 digits (plus an extra byte for safety)
+ */
+ static char buffer[sizeof(MP_NODE_RXQ_NAME) + 2];
+
+ snprintf(buffer, sizeof(buffer) - 1, MP_NODE_RXQ_NAME, id);
+ return buffer;
+}
+
+#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
+
+#endif
--
2.7.4
Pablo de Lara
2017-01-07 01:06:06 UTC
Permalink
Signed-off-by: Sameh Gobriel <***@intel.com>
Signed-off-by: Pablo de Lara <***@intel.com>
---
MAINTAINERS | 1 +
doc/guides/sample_app_ug/flow_distributor.rst | 492 ++++++++++++++++++++++
doc/guides/sample_app_ug/img/flow_distributor.svg | 417 ++++++++++++++++++
doc/guides/sample_app_ug/index.rst | 1 +
4 files changed, 911 insertions(+)
create mode 100644 doc/guides/sample_app_ug/flow_distributor.rst
create mode 100644 doc/guides/sample_app_ug/img/flow_distributor.svg

diff --git a/MAINTAINERS b/MAINTAINERS
index 66e9466..0d3b247 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -535,6 +535,7 @@ F: lib/librte_efd/
F: doc/guides/prog_guide/efd_lib.rst
F: app/test/test_efd*
F: examples/flow_distributor/
+F: doc/guides/sample_app_ug/flow_distributor.rst

Hashes
M: Bruce Richardson <***@intel.com>
diff --git a/doc/guides/sample_app_ug/flow_distributor.rst b/doc/guides/sample_app_ug/flow_distributor.rst
new file mode 100644
index 0000000..39820f0
--- /dev/null
+++ b/doc/guides/sample_app_ug/flow_distributor.rst
@@ -0,0 +1,492 @@
+.. BSD LICENSE
+ Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ 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 Intel Corporation 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
+ OWNER 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.
+
+Flow Distributor Sample Application
+===================================
+
+This sample application demonstrates the use of EFD library as a flow-level
+load balancer, for more information about the EFD Library please refer to the
+DPDK programmer's guide.
+
+This sample application is a variant of the :ref:`client-server sample application <multi_process_app>`
+where a specific target node is specified for every and each flow
+(not in a round-robin fashion as the original load balancing sample application).
+
+Overview
+--------
+
+The architecture of the EFD flow-based load balancer sample application is
+presented in the following figure.
+
+.. _figure_efd_sample_app_overview:
+
+.. figure:: img/flow_distributor.*
+
+ Using EFD as a Flow-Level Load Balancer
+
+As shown in figure, the sample application consists of a front end node
+(distributor) using the EFD library to create a load-balancing table for flows,
+for each flow a target backend worker node is specified. The EFD table does not
+store the flow key (unlike a regular hash table), and hence, it can
+individually load-balance millions of flows (number of targets * maximum number
+of flows fit in a flow table per target) while still fitting in CPU cache.
+
+It should be noted that although they are referred to as nodes, the frontend
+distributor and worker nodes are processes running on the same platform.
+
+Front-end Distributor
+~~~~~~~~~~~~~~~~~~~~~
+
+Upon initializing, the frontend distributor node (process) creates a flow
+distributor table (based on the EFD library) which is populated with flow
+information and its intended target node.
+
+The sample application assigns a specific target node_id (process) for each of
+the IP destination addresses as follows:
+
+.. code-block:: c
+
+ node_id = i % num_nodes; /* Target node id is generated */
+ ip_dst = rte_cpu_to_be_32(i); /* Specific ip destination address is
+ assigned to this target node */
+
+then the pair of <key,target> is inserted into the flow distribution table.
+
+The main loop of the the distributor node receives a burst of packets, then for
+each packet a flow key (IP destination address) is extracted. The flow
+distributor table is looked up and the target node id is returned. Packets are
+then enqueued to the specified target node id.
+
+It should be noted that flow distributor table is not a membership test table.
+I.e. if the key has already been inserted the target node id will be correct,
+but for new keys the flow distributor table will return a value (which can be
+valid).
+
+Backend Worker Nodes
+~~~~~~~~~~~~~~~~~~~~
+
+Upon initializing, the worker node (process) creates a flow table (a regular
+hash table that stores the key default size 1M flows) which is populated with
+only the flow information that are serviced at this node. This flow key is
+essential to point out new keys that have not been inserted before.
+
+The worker node's main loop is simply receiving packets then doing a hash table
+lookup. If a match occurs then statistics are updated for flows serviced by
+this node. If no match is found in the local hash table then this indicates
+that this is a new flows which is dropped.
+
+
+Compiling the Application
+-------------------------
+
+The sequence of steps used to build the application is:
+
+#. Export the required environment variables:
+
+ .. code-block:: console
+
+ export RTE_SDK=/path/to/rte_sdk
+ export RTE_TARGET=x86_64-native-linuxapp-gcc
+
+#. Build the application executable file:
+
+ .. code-block:: console
+
+ cd ${RTE_SDK}/examples/flow_distributor/
+ make
+
+ For more details on how to build the DPDK libraries and sample
+ applications,
+ please refer to the *DPDK Getting Started Guide.*
+
+
+Running the Application
+-----------------------
+
+The application has two binaries to be run: the front-end distributor
+and the back-end node.
+
+The frontend distributor (distributor) has the following command line options::
+
+ ./distributor [EAL options] -- -p PORTMASK -n NUM_NODES -f NUM_FLOWS
+
+Where,
+
+* ``-p PORTMASK:`` Hexadecimal bitmask of ports to configure
+* ``-n NUM_NODES:`` Number of back-end nodes that will be used
+* ``-f NUM_FLOWS:`` Number of flows to be added in the EFD table (1 million, by default)
+
+The back-end node (node) has the following command line options::
+
+ ./node [EAL options] -- -n NODE_ID
+
+Where,
+
+* ``-n NODE_ID:`` Node ID, which cannot be equal or higher than NUM_MODES
+
+
+First, the distributor app must be run, with the number of nodes that will be run.
+Once it has been started, the node instances can be run, with different NODE_ID.
+These instances have to be run as secondary processes, with `--proc-type=secondary`
+in the EAL options, which will attach to the primary process memory, and therefore,
+they can access the queues created by the primary process to distribute packets.
+
+To successfully run the application, the command line used to start the
+application has to be in sync with the traffic flows configured on the traffic
+generator side.
+
+For examples of application command lines and traffic generator flows, please
+refer to the DPDK Test Report. For more details on how to set up and run the
+sample applications provided with DPDK package, please refer to the
+:ref:`DPDK Getting Started Guide for Linux <linux_gsg>` and
+:ref:`DPDK Getting Started Guide for FreeBSD <freebsd_gsg>`.
+
+
+Explanation
+-----------
+
+As described in previous sections, there are two processes in this example.
+
+The first process, the front-end distributor, creates and populates the EFD table,
+which is used to distribute packets to nodes, which the number of flows
+specified in the command line (1 million, by default).
+
+
+.. code-block:: c
+
+ static void
+ create_flow_distributor_table(void)
+ {
+ uint8_t socket_id = rte_socket_id();
+
+ /* create table */
+ efd_table = rte_efd_create("flow table", num_flows * 2, sizeof(uint32_t),
+ 1 << socket_id, socket_id);
+
+ if (efd_table == NULL)
+ rte_exit(EXIT_FAILURE, "Problem creating the flow table\n");
+ }
+
+ static void
+ populate_flow_distributor_table(void)
+ {
+ unsigned int i;
+ int32_t ret;
+ uint32_t ip_dst;
+ uint8_t socket_id = rte_socket_id();
+ uint64_t node_id;
+
+ /* Add flows in table */
+ for (i = 0; i < num_flows; i++) {
+ node_id = i % num_nodes;
+
+ ip_dst = rte_cpu_to_be_32(i);
+ ret = rte_efd_update(efd_table, socket_id,
+ (void *)&ip_dst, (efd_value_t)node_id);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Unable to add entry %u in "
+ "flow distributor table\n", i);
+ }
+
+ printf("EFD table: Adding 0x%x keys\n", num_flows);
+ }
+
+After initialization, packets are received from the enabled ports, and the IPv4
+address from the packets is used as a key to look up in the EFD table,
+which tells the node where the packet has to be distributed.
+
+.. code-block:: c
+
+ static void
+ process_packets(uint32_t port_num __rte_unused, struct rte_mbuf *pkts[],
+ uint16_t rx_count, unsigned int socket_id)
+ {
+ uint16_t i;
+ uint8_t node;
+ efd_value_t data[EFD_BURST_MAX];
+ const void *key_ptrs[EFD_BURST_MAX];
+
+ struct ipv4_hdr *ipv4_hdr;
+ uint32_t ipv4_dst_ip[EFD_BURST_MAX];
+
+ for (i = 0; i < rx_count; i++) {
+ /* Handle IPv4 header.*/
+ ipv4_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct ipv4_hdr *,
+ sizeof(struct ether_hdr));
+ ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
+ key_ptrs[i] = (void *)&ipv4_dst_ip[i];
+ }
+
+ rte_efd_lookup_bulk(efd_table, socket_id, rx_count,
+ (const void **) key_ptrs, data);
+ for (i = 0; i < rx_count; i++) {
+ node = (uint8_t) ((uintptr_t)data[i]);
+
+ if (node >= num_nodes) {
+ /*
+ * Node is out of range, which means that
+ * flow has not been inserted
+ */
+ flow_dist_stats.drop++;
+ rte_pktmbuf_free(pkts[i]);
+ } else {
+ flow_dist_stats.distributed++;
+ enqueue_rx_packet(node, pkts[i]);
+ }
+ }
+
+ for (i = 0; i < num_nodes; i++)
+ flush_rx_queue(i);
+ }
+
+The burst of packets received is enqueued in temporary buffers (per node),
+and enqueued in the shared ring between the distributor and the node.
+After this, a new burst of packets is received and this process is
+repeated infinitely.
+
+.. code-block:: c
+
+ static void
+ flush_rx_queue(uint16_t node)
+ {
+ uint16_t j;
+ struct node *cl;
+
+ if (cl_rx_buf[node].count == 0)
+ return;
+
+ cl = &nodes[node];
+ if (rte_ring_enqueue_bulk(cl->rx_q, (void **)cl_rx_buf[node].buffer,
+ cl_rx_buf[node].count) != 0){
+ for (j = 0; j < cl_rx_buf[node].count; j++)
+ rte_pktmbuf_free(cl_rx_buf[node].buffer[j]);
+ cl->stats.rx_drop += cl_rx_buf[node].count;
+ } else
+ cl->stats.rx += cl_rx_buf[node].count;
+
+ cl_rx_buf[node].count = 0;
+ }
+
+The second process, the back-end node, receives the packets from the shared
+ring with the distributor and send them out, if they belong to the node.
+
+At initialization, it attaches to the distributor process memory, to have
+access to the shared ring, parameters and statistics.
+
+.. code-block:: c
+
+ rx_ring = rte_ring_lookup(get_rx_queue_name(node_id));
+ if (rx_ring == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get RX ring - "
+ "is distributor process running?\n");
+
+ mp = rte_mempool_lookup(PKTMBUF_POOL_NAME);
+ if (mp == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n");
+
+ mz = rte_memzone_lookup(MZ_SHARED_INFO);
+ if (mz == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot get port info structure\n");
+ info = mz->addr;
+ tx_stats = &(info->tx_stats[node_id]);
+ filter_stats = &(info->filter_stats[node_id]);
+
+Then, the hash table that contains the flows that will be handled
+by the node is created and populated.
+
+.. code-block:: c
+
+ static struct rte_hash *
+ create_hash_table(const struct shared_info *info)
+ {
+ uint32_t num_flows_node = info->num_flows / info->num_nodes;
+ char name[RTE_HASH_NAMESIZE];
+ struct rte_hash *h;
+
+ /* create table */
+ struct rte_hash_parameters hash_params = {
+ .entries = num_flows_node * 2, /* table load = 50% */
+ .key_len = sizeof(uint32_t), /* Store IPv4 dest IP address */
+ .socket_id = rte_socket_id(),
+ .hash_func_init_val = 0,
+ };
+
+ snprintf(name, sizeof(name), "hash_table_%d", node_id);
+ hash_params.name = name;
+ h = rte_hash_create(&hash_params);
+
+ if (h == NULL)
+ rte_exit(EXIT_FAILURE,
+ "Problem creating the hash table for node %d\n",
+ node_id);
+ return h;
+ }
+
+ static void
+ populate_hash_table(const struct rte_hash *h, const struct shared_info *info)
+ {
+ unsigned int i;
+ int32_t ret;
+ uint32_t ip_dst;
+ uint32_t num_flows_node = 0;
+ uint64_t target_node;
+
+ /* Add flows in table */
+ for (i = 0; i < info->num_flows; i++) {
+ target_node = i % info->num_nodes;
+ if (target_node != node_id)
+ continue;
+
+ ip_dst = rte_cpu_to_be_32(i);
+
+ ret = rte_hash_add_key(h, (void *) &ip_dst);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Unable to add entry %u "
+ "in hash table\n", i);
+ else
+ num_flows_node++;
+
+ }
+
+ printf("Hash table: Adding 0x%x keys\n", num_flows_node);
+ }
+
+After initialization, packets are dequeued from the shared ring (from the distributor) and,
+like in the distributor process, the IPv4 address from the packets is used as
+a key to look up in the hash table.
+If there is a hit, packet is stored in a buffer, to be eventually transmitted
+in one of the enabled ports. If key is not there, packet is dropped, since the
+flow is not handled by the node.
+
+.. code-block:: c
+
+ static inline void
+ handle_packets(struct rte_hash *h, struct rte_mbuf **bufs, uint16_t num_packets)
+ {
+ struct ipv4_hdr *ipv4_hdr;
+ uint32_t ipv4_dst_ip[PKT_READ_SIZE];
+ const void *key_ptrs[PKT_READ_SIZE];
+ unsigned int i;
+ int32_t positions[PKT_READ_SIZE] = {0};
+
+ for (i = 0; i < num_packets; i++) {
+ /* Handle IPv4 header.*/
+ ipv4_hdr = rte_pktmbuf_mtod_offset(bufs[i], struct ipv4_hdr *,
+ sizeof(struct ether_hdr));
+ ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
+ key_ptrs[i] = &ipv4_dst_ip[i];
+ }
+ /* Check if packets belongs to any flows handled by this node */
+ rte_hash_lookup_bulk(h, key_ptrs, num_packets, positions);
+
+ for (i = 0; i < num_packets; i++) {
+ if (likely(positions[i] >= 0)) {
+ filter_stats->passed++;
+ transmit_packet(bufs[i]);
+ } else {
+ filter_stats->drop++;
+ /* Drop packet, as flow is not handled by this node */
+ rte_pktmbuf_free(bufs[i]);
+ }
+ }
+ }
+
+Finally, note that both processes updates statistics, such as transmitted, received
+and dropped packets, which are shown and refreshed by the distributor app.
+
+.. code-block:: c
+
+ static void
+ do_stats_display(void)
+ {
+ unsigned int i, j;
+ const char clr[] = {27, '[', '2', 'J', '\0'};
+ const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'};
+ uint64_t port_tx[RTE_MAX_ETHPORTS], port_tx_drop[RTE_MAX_ETHPORTS];
+ uint64_t node_tx[MAX_NODES], node_tx_drop[MAX_NODES];
+
+ /* to get TX stats, we need to do some summing calculations */
+ memset(port_tx, 0, sizeof(port_tx));
+ memset(port_tx_drop, 0, sizeof(port_tx_drop));
+ memset(node_tx, 0, sizeof(node_tx));
+ memset(node_tx_drop, 0, sizeof(node_tx_drop));
+
+ for (i = 0; i < num_nodes; i++) {
+ const struct tx_stats *tx = &info->tx_stats[i];
+
+ for (j = 0; j < info->num_ports; j++) {
+ const uint64_t tx_val = tx->tx[info->id[j]];
+ const uint64_t drop_val = tx->tx_drop[info->id[j]];
+
+ port_tx[j] += tx_val;
+ port_tx_drop[j] += drop_val;
+ node_tx[i] += tx_val;
+ node_tx_drop[i] += drop_val;
+ }
+ }
+
+ /* Clear screen and move to top left */
+ printf("%s%s", clr, topLeft);
+
+ printf("PORTS\n");
+ printf("-----\n");
+ for (i = 0; i < info->num_ports; i++)
+ printf("Port %u: '%s'\t", (unsigned int)info->id[i],
+ get_printable_mac_addr(info->id[i]));
+ printf("\n\n");
+ for (i = 0; i < info->num_ports; i++) {
+ printf("Port %u - rx: %9"PRIu64"\t"
+ "tx: %9"PRIu64"\n",
+ (unsigned int)info->id[i], info->rx_stats.rx[i],
+ port_tx[i]);
+ }
+
+ printf("\nFLOW DISTRIBUTOR\n");
+ printf("-----\n");
+ printf("distributed: %9"PRIu64", drop: %9"PRIu64"\n",
+ flow_dist_stats.distributed, flow_dist_stats.drop);
+
+ printf("\nNODES\n");
+ printf("-------\n");
+ for (i = 0; i < num_nodes; i++) {
+ const unsigned long long rx = nodes[i].stats.rx;
+ const unsigned long long rx_drop = nodes[i].stats.rx_drop;
+ const struct filter_stats *filter = &info->filter_stats[i];
+
+ printf("Node %2u - rx: %9llu, rx_drop: %9llu\n"
+ " tx: %9"PRIu64", tx_drop: %9"PRIu64"\n"
+ " filter_passed: %9"PRIu64", "
+ "filter_drop: %9"PRIu64"\n",
+ i, rx, rx_drop, node_tx[i], node_tx_drop[i],
+ filter->passed, filter->drop);
+ }
+
+ printf("\n");
+ }
diff --git a/doc/guides/sample_app_ug/img/flow_distributor.svg b/doc/guides/sample_app_ug/img/flow_distributor.svg
new file mode 100644
index 0000000..b35faad
--- /dev/null
+++ b/doc/guides/sample_app_ug/img/flow_distributor.svg
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export Drawing1.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="7.0721in" height="4.43701in"
+ viewBox="0 0 509.191 319.465" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false">
+ <v:userDefs>
+ <v:ud v:nameU="msvNoAutoConnect" v:val="VT0(1):26"/>
+ </v:userDefs>
+ </v:documentProperties>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(18.375,-18.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="36.75" width="472.441" height="282.715" class="st1"/>
+ <image x="0" y="36.75" width="472.441" height="282.715" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ Dg//f9NW31MZe1iBAAAAAElFTkSuQmCC"/>
+ <rect v:rectContext="foreign" x="0" y="36.75" width="472.441" height="282.715" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 775e2f7..260f6a5 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -57,6 +57,7 @@ Sample Applications User Guides
l3_forward_virtual
link_status_intr
load_balancer
+ flow_distributor
multi_process
qos_metering
qos_scheduler
--
2.7.4
Pablo de Lara
2017-01-07 01:06:05 UTC
Permalink
Signed-off-by: Sameh Gobriel <***@intel.com>
---
MAINTAINERS | 1 +
doc/guides/prog_guide/efd_lib.rst | 413 ++++++++++
doc/guides/prog_guide/img/efd_i1.svg | 78 ++
doc/guides/prog_guide/img/efd_i10.svg | 1272 +++++++++++++++++++++++++++++
doc/guides/prog_guide/img/efd_i11.svg | 413 ++++++++++
doc/guides/prog_guide/img/efd_i12.svg | 590 +++++++++++++
doc/guides/prog_guide/img/efd_i13.svg | 1407 ++++++++++++++++++++++++++++++++
doc/guides/prog_guide/img/efd_i2.svg | 209 +++++
doc/guides/prog_guide/img/efd_i3.svg | 420 ++++++++++
doc/guides/prog_guide/img/efd_i4.svg | 364 +++++++++
doc/guides/prog_guide/img/efd_i5.svg | 578 +++++++++++++
doc/guides/prog_guide/img/efd_i6.svg | 413 ++++++++++
doc/guides/prog_guide/img/efd_i8.svg | 776 ++++++++++++++++++
doc/guides/prog_guide/img/efd_i9.svg | 271 ++++++
doc/guides/prog_guide/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 3 +
16 files changed, 7209 insertions(+)
create mode 100644 doc/guides/prog_guide/efd_lib.rst
create mode 100644 doc/guides/prog_guide/img/efd_i1.svg
create mode 100644 doc/guides/prog_guide/img/efd_i10.svg
create mode 100644 doc/guides/prog_guide/img/efd_i11.svg
create mode 100644 doc/guides/prog_guide/img/efd_i12.svg
create mode 100644 doc/guides/prog_guide/img/efd_i13.svg
create mode 100644 doc/guides/prog_guide/img/efd_i2.svg
create mode 100644 doc/guides/prog_guide/img/efd_i3.svg
create mode 100644 doc/guides/prog_guide/img/efd_i4.svg
create mode 100644 doc/guides/prog_guide/img/efd_i5.svg
create mode 100644 doc/guides/prog_guide/img/efd_i6.svg
create mode 100644 doc/guides/prog_guide/img/efd_i8.svg
create mode 100644 doc/guides/prog_guide/img/efd_i9.svg

diff --git a/MAINTAINERS b/MAINTAINERS
index b124f6e..66e9466 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -532,6 +532,7 @@ EFD
M: Byron Marohn <***@intel.com>
M: Pablo de Lara Guarch <***@intel.com>
F: lib/librte_efd/
+F: doc/guides/prog_guide/efd_lib.rst
F: app/test/test_efd*
F: examples/flow_distributor/

diff --git a/doc/guides/prog_guide/efd_lib.rst b/doc/guides/prog_guide/efd_lib.rst
new file mode 100644
index 0000000..7d0a2d2
--- /dev/null
+++ b/doc/guides/prog_guide/efd_lib.rst
@@ -0,0 +1,413 @@
+.. BSD LICENSE
+ Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ 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 Intel Corporation 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
+ OWNER 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.
+
+.. _Efd_Library:
+
+Elastic Flow Distributor Library
+================================
+
+Introduction
+------------
+
+In Data Centers today clustering and scheduling of distributed workloads
+is a very common task. Many workloads require a deterministic
+partitioning of a flat key space among a cluster of machines. When a
+packet enters the cluster, the ingress node will direct the packet to
+its handling node. For example, datacenters with disaggregated storage
+use storage metadata tables to forward I/O requests to the correct back end
+storage cluster, stateful packet inspection will use match incoming
+flows to signatures in flow tables to send incoming packets to their
+intended deep packet inspection (DPI) devices, and so on.
+
+EFD is a distributor library that uses perfect hashing to determine a
+target/value for a given incoming flow key. It has the following
+advantages: first, because it uses perfect hashing it does not store the
+key itself and hence lookup performance is not dependent on the key
+size. Second, the target/value can be any arbitrary value hence the
+system designer and/or operator can better optimize service rates and
+inter-cluster network traffic locating. Third, since the storage
+requirement is much smaller than a hash-based flow table (i.e. better
+fit for CPU cache), EFD can scale to millions of flow keys. Finally,
+with the current optimized library implementation, performance is fully
+scalable with number of CPU cores.
+
+Flow Based Distribution
+-----------------------
+
+Computation Based Schemes
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Flow distribution and/or load balancing can be simply done using a
+stateless computation, for instance using round-robin or a simple
+computation based on the flow key as an input. For example, a hash
+function can be used to direct a certain flow to the a target based on
+the flow key (e.g. h(key) mod n) where h(key) is the hash value of the
+flow key and n is the number of possible targets.
+
+
+.. figure:: img/efd_i1.*
+
+ Load Balancing Using Front End Node
+
+In this scheme the front end server/distributor/load balancer extracts the
+flow key from the input packet and applies a computation to determine where
+this flow should be directed. Intuitively, this scheme is very simple
+and requires no state to be kept at the front end node, and hence,
+storage requirements are minimum.
+
+
+.. figure:: img/efd_i2.*
+
+ Consistent Hashing
+
+A widely used flow distributor that belongs to the same category of
+computation-based schemes is *consistent hashing*, shown in the above figure.
+Target destinations (shown in red) are hashed into the same space as the flow
+keys (shown in blue), and keys are mapped to the nearest target in a clockwise
+fashion. Dynamically adding and removing targets with consistent hashing
+requires only K/n keys to be remapped on average, where K is the number of
+keys, and n is the number of targets. In contrast, in a traditional hash-based
+scheme, a change in the number of targets causes nearly all keys to be
+remapped.
+
+Although computation-based schemes are simple and need very little
+storage requirement, they suffer from the drawback that the system
+designer/operator can’t fully control the target to assign a specific
+key, as this is dictated by the hash function.
+Deterministically co-locating of keys together (for example, to minimize
+inter-server traffic or to optimize for network traffic conditions,
+target load, etc.) is simply not possible.
+
+Flow-Table Based Schemes
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When using a Flow-Table based scheme to handle flow distribution/load
+balancing, in contrast with computation-based schemes, the system designer
+has the flexibility of assigning a given flow to any given
+target. The flow table (e.g. DPDK RTE Hash Library) will simply store
+both the flow key and the target value.
+
+.. figure:: img/efd_i3.*
+
+ Table Based Flow Distribution
+
+As shown in the above figure when doing a lookup the flow-table is indexed with
+the hash of the flow key and the keys (more than one is possible,
+because of hash collision) stored in this index and corresponding values
+are retrieved. The retrieved key(s) is matched with the input flow key
+and if there is a match the value (target id) is returned.
+
+The drawback of using a hash table for flow distribution/load balancing
+is the storage requirement, since the flow table need to store keys,
+signatures and target values. This doesn’t allow this scheme to scale to
+millions of flow keys. Large tables will usually not fit in
+the CPU cache, and hence, the lookup performance is degraded because of
+the latency to access the main memory.
+
+EFD Based Scheme
+~~~~~~~~~~~~~~~~
+
+EFD combines the advantages of both flow-table based and computation-based
+schemes. It doesn’t require the large storage necessary for
+flow-table based schemes (because EFD doesn’t store the key as explained
+below), and it supports any arbitrary value for any given key.
+
+.. figure:: img/efd_i4.*
+
+ Searching for Perfect Hash Function
+
+The basic idea of EFD is when a given key is to be inserted, a family of
+hash functions is searched until the correct hash function that maps the
+input key to the correct value is found, as shown in the above figure. However,
+rather than explicitly storing all keys and their associated values, EFD
+stores only indices of hash functions that map keys to values, and
+thereby consumes much less space than conventional flow-based tables.
+The lookup operation is very simple, similar to a computational-based
+scheme: given an input key the lookup operation is reduced to hashing
+that key with the correct hash function.
+
+.. figure:: img/efd_i5.*
+
+ Divide and Conquer for Millions of Keys
+
+Intuitively, finding a hash function that maps each of a large number
+(millions) of input keys to the correct output value is effectively
+impossible, as a result EFD, as shown in the above figure, breaks the problem
+into smaller pieces (divide and conquer). EFD divides the entire input
+key set into many small groups. Each group consists of approximately
+20-28 keys (a configurable parameter for the library), then, for each
+small group, a brute force search to find a hash function that produces
+the correct outputs for each key in the group.
+
+It should be mentioned that since in the online lookup table for EFD
+doesn’t store the key itself, the size of the EFD table is independent
+of the key size and hence EFD lookup performance which is almost
+constant irrespective of the length of the key which is a highly
+desirable feature especially for longer keys.
+
+In summary, EFD is a set separation data structure that supports millions of
+keys. It is used to distribute a given key to an intended target. By itself
+EFD is not a FIB data structure with an exact match the input flow key.
+
+.. _Efd_example:
+
+Example of EFD Library Usage
+----------------------------
+
+EFD can be used along the data path of many network functions and middleboxes.
+As previously mentioned, it can used as an index table for
+<key,value> pairs, meta-data for objects, a flow-level load balancer, etc.
+The following figure shows an example of using EFD as a flow-level load
+balancer, where flows are received at a front end server before being forwarded
+to the target back end server for processing. The system designer would
+deterministically co-locate flows together in order to minimize cross-server
+interaction.
+(For example, flows requesting certain webpage objects are co-located
+together, to minimize forwarding of common objects across servers).
+
+.. figure:: img/efd_i6.*
+
+ EFD as a Flow-Level Load Balancer
+
+As shown in the figure the front end server will have an EFD table that
+stores for each group what is the perfect hash index that satisfies the
+correct output. Because the table size is small and fits in cache (since
+keys are not stored) it sustains a large number of flows (N\*X, where N
+is the maximum number of flows served by each back end server of the X
+possible targets).
+
+With an input flow key, the group id is computed (for example, using
+last few bits of CRC hash) and then the EFD table is indexed with the
+group id to retrieve the corresponding hash index to use. Once the index
+is retrieved the key is hashed using this hash function and the result
+will be the intended correct target where this flow is supposed to be
+processed.
+
+It should be noted that as a result of EFD not matching the exact key but
+rather distributing the flows to a target back end node based on the
+perfect hash index, a key that has not been inserted before
+will be distributed to a valid target. Hence, a local table which stores
+the flows served at each node is used and is
+exact matched with the input key to rule out new never seen before
+flows.
+
+.. _Efd_api:
+
+Library API Overview
+--------------------
+
+The EFD library API is created with a very similar semantics of a
+hash-index or a flow table, the application creates an EFD table for a
+given maximum number of flows, a function is called to insert a flow key
+with a specific target value, and another function is used to retrieve
+target values for a given individual flow key or a bulk of keys.
+
+EFD Table Create
+~~~~~~~~~~~~~~~~
+
+The function *rte\_efd\_create("flow table", num\_flows,
+online\_socket\_bitmask, offline\_socket\_bitmask)* is used to create
+and return a pointer to an EFD table that is sized to hold up to
+num\_flows key. The online version of the EFD table (the one that does
+not store the keys and is used for lookups) will be allocated and
+created in the last level cache (LLC) of the socket defined by the
+online\_socket\_bitmask, while the offline EFD table (the one that
+stores the keys and is used for key inserts and for computing the
+perfect hashing) is allocated and created in the LLC of the socket
+defined by offline\_socket\_bitmask. It should be noted, that for
+highest performance the socket id should match that where the thread is
+running, i.e. the online EFD lookup table should be created on the same
+socket as where the lookup thread is running.
+
+EFD Insert and Update
+~~~~~~~~~~~~~~~~~~~~~
+
+The EFD function to insert a key or update a key to a new value is
+*rte\_efd\_update(struct rte\_efd\_table \*table, unsigned socket\_id,
+const efd\_key\_t \*key, efd\_value\_t value).* This function will update an
+existing key to a new value (target) if the key has already been inserted
+before, or will insert the <key,value> pair if this key has not been inserted
+before. It will return *0* upon success. It will return
+*EFD\_UPDATE\_WARN\_GROUP\_FULL (1)* if the operation is insert, and the
+last available space in the key's group was just used. It will return
+*EFD\_UPDATE\_FAILED (2)* when the insertion or update has failed (either it
+failed to find a suitable perfect hash or the group was full). The function
+will return *EFD\_UPDATE\_NO\_CHANGE (3)* if there is no change to the EFD
+table (i.e, same value already exists).
+
+EFD Lookup
+~~~~~~~~~~
+
+To lookup a certain key in an EFD table, the function
+*rte\_efd\_lookup(const struct rte\_efd\_table \*table, unsigned
+socket\_id, const efd\_key\_t \*key)* is used to return the value
+associated with single key. As previously mentioned, if the key has been
+inserted, the correct value inserted is returned, if the key has not been
+inserted before, a ‘random’ value (based on hashing of the key) is
+returned. For better performance and to decrease the overhead of
+function calls per key, it is always recommended to use a bulk lookup
+function (simultaneous lookup of multiple keys) instead of a single key
+lookup function. *rte\_efd\_lookup\_bulk(const struct rte\_efd\_table
+\*table, unsigned socket\_id, int num\_keys, const efd\_key\_t \*const
+\*key\_list, efd\_value\_t \*value\_list)* is the bulk lookup function,
+that looks up num\_keys simultaneously stored in the key\_list and the
+corresponding return values will be returned in the value\_list.
+
+EFD Delete
+~~~~~~~~~~
+
+To delete a certain key in an EFD table, the function
+*rte\_efd\_delete(struct rte\_efd\_table \*table, unsigned socket\_id,
+const efd\_key\_t \*key, efd\_value\_t \*prev\_value)* can be used. The
+function returns zero upon success when the key has been found and
+deleted. Socket\_id is the parameter to use to lookup the existing value, which
+is ideally the caller's socket id. The previous value associated with
+this key will be returned in the prev\_value argument.
+
+.. _Efd_internals:
+
+Library Internals
+-----------------
+
+This section provides the brief high-level idea and an overview
+of the library internals to accompany the RFC. The intent of this
+section is to explain to readers the high-level implementation of
+insert, lookup and group rebalancing in the EFD library.
+
+Insert Function Internals
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As previously mentioned the EFD divides the whole set of keys into
+groups of a manageable size (e.g. 28 keys) and then searches for the
+perfect hash that satisfies the intended target value for each key. EFD
+stores two version of the <key,value> table:
+
+- Offline Version (in memory): Only used for the insertion/update
+ operation, which is less frequent than the lookup operation. In the
+ offline version the exact keys for each group is stored. When a new
+ key is added, the hash function is updated that will satisfy the
+ value for the new key together with the all old keys already inserted
+ in this group.
+
+- Online Version (in cache): Used for the frequent lookup operation. In
+ the online version, as previously mentioned, the keys are not stored
+ but rather only the hash index for each group.
+
+.. figure:: img/efd_i8.*
+
+ Group Assignment
+
+The above figure depicts the group assignment for 7 flow keys as an example.
+Given a flow key, a hash function (in our implementation CRC hash) is
+used to get the group id. As shown in the figure, the groups can be
+unbalanced. (We highlight group rebalancing further below).
+
+.. figure:: img/efd_i9.*
+
+ Perfect Hash Search - Assigned Keys & Target Value
+
+Focusing on one group that has four keys, the above figure depicts the search
+algorithm to find the perfect hash function. Assuming that the target
+value bit for the keys is as shown in the figure, then the online EFD
+table will store a 16 bit hash index and 16 bit lookup table per group
+per value bit.
+
+.. figure:: img/efd_i10.*
+
+ Perfect Hash Search - Satisfy Target Values
+
+For a given keyX, a hash function
+(h(keyX,seed1)+index\*h(keyX,seed2)) is used to point to certain bit
+index in the 16bit lookup\_table value, as shown in the above figure. The
+insert function will brute force search for all possible values for the
+hash index until a non conflicting lookup\_table is found.
+
+
+.. figure:: img/efd_i11.*
+
+ Finding Hash Index for Conflict Free lookup\_table
+
+For example, since both key3 and key7 have a target bit value of 1, it
+is okay if the hash function of both keys point to the same bit in the
+lookup table. A conflict will occur if a hash index is used that maps
+both Key4 and Key7 to the same index in the lookup\_table,
+as shown in the above figure, since their target value bit are not the same.
+Once a hash index is found that produces a lookup\_table with no
+contradictions, this index is stored for this group. This procedure is
+repeated for each bit of target value.
+
+Lookup Function Internals
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The design principle of EFD is that lookups are much more frequent than
+inserts, and hence, EFD's design optimizes for the lookups which are
+faster and much simpler than the slower insert procedure (inserts are
+slow, because of perfect hash search as previously discussed).
+
+.. figure:: img/efd_i12.*
+
+ EFD Lookup Operation
+
+The previous figure depicts the lookup operation for EFD. Given an input key,
+the group id is computed (using CRC hash) and then the hash index for this
+group is retrieved from the EFD table. Using the retrieved hash index,
+the hash function h(key,seed1)+index\*h(key,seed2) is used which will
+result in an index in the lookup\_table, the bit corresponding to this
+index will be the target value bit. This procedure is repeated for each
+bit of the target value.
+
+Group Rebalancing Function Internals
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When discussing EFD inserts and lookups, the discussion is simplified by
+assuming that a group id is simply a result of hash function. However,
+since hashing in general is not perfect and will not always produce a
+uniform output, this simplified assumption will lead to unbalanced
+groups, i.e., some group will have more keys than other groups.
+Typically, and to minimize insert time with an increasing number of keys,
+it is preferable that all groups will have a balanced number of keys, so
+the brute force search for the perfect hash terminates with a valid hash
+index. In order to achieve this target, groups are rebalanced during
+runtime inserts, and keys are moved around from a busy group to a less
+crowded group as the more keys are inserted.
+
+.. figure:: img/efd_i13.*
+
+ Runtime Group Rebalancing
+
+The previous figure depicts the high level idea of group rebalancing, given an
+input key the hash result is split into two parts a chunk id and 8\_bit
+bin id. A chunk contains 64 different groups and 256 bins (i.e. for any
+given bin it can map to 4 distinct groups). When a key is inserted the
+bin id is computed, for example in figure bin\_id=2, and since each bin
+can be mapped to one of four different groups (2 bit storage), the four
+possible mappings are evaluated and the one that will result in a
+balanced key distribution across these four is selected the mapping result
+is stored in these two bits.
diff --git a/doc/guides/prog_guide/img/efd_i1.svg b/doc/guides/prog_guide/img/efd_i1.svg
new file mode 100644
index 0000000..cf70b09
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i1.svg
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i1.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="4.05258in" height="2.27108in"
+ viewBox="0 0 291.786 163.518" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false">
+ <v:userDefs>
+ <v:ud v:nameU="msvNoAutoConnect" v:val="VT0(1):26"/>
+ </v:userDefs>
+ </v:documentProperties>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(18.375,-18.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="36.75" width="255.036" height="126.768" class="st1"/>
+ <image x="0" y="36.75" width="255.036" height="126.768" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ YII="/>
+ <rect v:rectContext="foreign" x="0" y="36.75" width="255.036" height="126.768" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i10.svg b/doc/guides/prog_guide/img/efd_i10.svg
new file mode 100644
index 0000000..36fe064
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i10.svg
@@ -0,0 +1,1272 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i10.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="9.44457in" height="3.10402in"
+ viewBox="0 0 680.009 223.489" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.750001" width="679.259" height="222.739" class="st1"/>
+ <image x="0" y="0.750001" width="679.259" height="222.739" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ Oj7KyStFfuQ9tuuVp21ti0zHmsk6X1qPq/a9LzaVWp96EmW0Iz+Ko3pto1gkl51q6/m4bbcRGeWuV9kxrdKefJxH6zlUErnrOI7qaQNZ
+ 5Oct+dEYykcy5hDpRjL0+3hNRxnl9FHfYZyBDXR74b4+lsrY6jGQ13zAj0jjkNBXvdqMWqWVTPqqI1/Hif+1UfTb1n9bRrEKjb6bWn97
+ Rr7Nf+pbc534D3WlFd/VzmGPKzGgJ+q3hKvc7OhPCuIM+SPmvq/XFv6F6viXWK+VuIhVaHQeGLePTZ5t82dO3U6p69EXf5XRhrI9Y1JG
+ XmPXvvBuxxgkz11jQH9J2Lvoh3/9j222E4nHBL8TTHrpu4Z/9MU/retGF4EGzDbbbB+vBSUSt0JdgAaLz744FZkvTEEqMzu+JGAnCnbG
+ bIEvJD4u4+j/or3/ZaPEYEyQ5djbotvzn3DUFzPEMd9lobXJm46t7v55Koj/+eKTCyPoseh8/Nf/4w8qP8NyXg8xQMuCtuQsx3WpnOHD
+ vIE+j34elJc8uk7lyqvtraH5aR4kzi1410fHokSZtyOZ65SvuahO5K5TH82T/S0Z5dpX3vUao+qL3P27rpDL3ZaksoifyY61J3kux/qS
+ VB75Oq99bzXeyAc0stM4C//CM19S1wf+es15v8sKRWMrP5NFcSL7TqXP8Uc5UB7GMTtQZLcXHGsUR2Xa59jq5/1Ru+AjWSPEiuSzeMyh
+ +oossD1mzXD43YJ/8W157VkXAE+/ZU++yGHr28CArkNGx7Hi1b7NwWrnsOgOfItR+HB90eM1O21Jrh/xxe7k9ZqNfd567ZDLnvOA4jPj
+ 00/z6DqS5Rnaoc9rguT2zmt/JGds11cqstl4KlM52kvC3kN/7Y9+1mY6kXhMaHEY/2ngS8dv/El5/rNOxHv1bHjA1v72X3xRtyl/9JP1
+ jq5EInF54Jsx+KbT73zv7+sP8OK+JCUSt4AvNqMFKFoubsnXvtiD1L/otBhIHHa90O6jxff4dKdJFEd3tGiM8MWJLfNexBRqx6KFYd/B
+ 4oXQxTE0/0UOkEGnc1hkq124ogvjhMcym9cn23BeZRzYLcdqudQYjS92l8n54KPz2AvH1VZIc3CZ6kY8xrs1RvmglePv+lk/sndbldGe
+ c+l+Iz3kPpb6khayyG7gq/2eg8hH9mg1t0in181Ipu0oXtR3HWOrP8jtKBvlokRZj9n6lI9a5WfjLGxMFtlF+ki3mIMiQ58y2GhOrotk
+ kQ3bY3nG8XhbPHPYk0ckG/lXKjzlaPdiFUf6jOdy8lUvMu9H1P0Kz9bjRq3ro776RLEpqxT/tvWdvm0+V7/ViCGxqfffROj4WwVUPX0L
+ 4beOvr3wKL78/erfzNfjaDZTHq2NR0THobbIB6i/waWvvoqq1/G0nfGDuT/MIe0G6zXmbHHC9VoZc7peKPr4PDSbwvM89Dlrfot2S6Y5
+ qx3kHhMU2W/1VR7xaEfjKUW+9Lk07F0Un5fQ+y2RSNwHqBn1+tDFCsOABiztr//x3+b/SJlI3Bn44cUP8OL+JCUS1wYXmbMFKmXecmGr
+ PsL7y0Z9UaBdW+iD1xeOpx00T7EYZ/UdwkZ82Th8i09ygD7KzVrNc/EyxDGKne7ywY6Y/tKDGKscDrIeo4213oXb7IZxJFfaFQrnVfSV
+ SuzVvFqsVc7Q2ZhhzozRcg53IFMv8XT30KLQrO1Ihnhux/mjnrpbI8pBKTq2Bd9a94/4SAY/ktu4nfbdbqRTf48RySJflW3qSh8xIx9Q
+ H1P0lLmPj6H6ka3yjLuILTrK1Hdlr/rAl/aqJ4UxCtGn+gUx1V5l3nedyyJex3Z/lUW+bu/9SKZ9xHcZ+S5rree3yYsfW7UDRX7eguBL
+ onwvRuPPxlPex/V+5K992K70A1u1GcUbyYIY+tsWf/s2+P5u9w9aHgtlpc9iFwut9Nfdqod1wMFefcPYkr/GW+kqNb8i1+NY/LHU/N0u
+ +jSXo+bP/IKYK77Y7ltXDNZrEvPo9Zrp1+ehxDabSipvY1fS4wtlzS+yo4592ng740GMofIqa/0+RumfM941YO+hqBXtueYSicTlgffN
+ XiMC6f15NjRgKwwnEonHAXbwX/7GTyQ2oAvNaPGpMu87z0VuWwTry8bh5UfsaNv63BnTd5swrsRZ6BintHzZOBQnmx/0M77loDtwur/m
+ Rr9C+lK0eHkstMhB/St/iIOXvMWLKf234lis1bxCTj3bRuG8NpvFWDoO+TLWNOdmsx2nUPEJ59pt3Y99tH3cxrOvPpDdGp6D9lUe8dEx
+ eD/S9bkQ/UIuMrRb46h8i9+SuS6SsdXjoDySeQsbkupAkcxJdVu8yhbjNjnH8zknsR/lpWP0uAMb79NnZjOSqW+Ut/LdTuSqZ7/amZy6
+ qK/ySObxZn6kaD40zigm5OrrdmrrPIi+qlMb6Pei5zIZb6ab9cn3fFvfbVTPfCjz+C6rdhbPbTxG8wl/22hPvtjxN2fxh1olxqVflz+N
+ sfgNKvLV77v7OjG+jiXxug146rtsuR5YHCuo8gc//aMqCq5sD7/nHHM5d8Dmt5Ut39Xca760bbJwXdFyZpyu0xiFX6wXNC7a4r86D4Mc
+ QnmNEdhWuflFdh7T+ZmOvLfkPT770ZiUqW3tC4/2GuB7qL6LFsI7av4L80TiNuC/MF/chxevD2nQ0uKjxolE4nGARWL9xATuU96ricS1
+ oYtQLkS3+JlOeH3ZWL7IiB3GL7SyDeKsdqI0f74wrXbA0gYU5VhaffFa7K4N7HUHz2LXUZSDjt34lT9z5VgeJ8ql2KzmCvF9vJbX0LbQ
+ MGe0bcw9OfNlbxVH8y8yjM+XysXxqa3yjNPpEKfTyOfWYJ6jnI7l99hG/UpFxvnZkxf1Lp/Zb8ki30g20vMYRj5+DUZ2U1lrZ2Mor322
+ 8CW5TO32jNWpyMIYout9oVFc8iO99mdjuo3bqg906qM65V3GmCqLdKQorttrP6Lo3Ghc2qks4ke+KkN/LzguKRqTuq3rK5Ip3+OY3m3I
+ RzGiHHpc6bsNyOLO1gGRXS8O+7U68IMNfQ/F4Sc7/a17iiu+W7GVRy5O1aboK7/cEVzXHn4MzQcFUsX/8K//48G2xmsxG6+F1cXvteYw
+ yHc19/RT+9YfnieJ09dr0KFt+uW6o8Vl7NLG50FyqCQxQeQ1107NluQ2PY7FVDs5voNMbY2vbSMfa9SPxhrZYizy1wILUFqMMsL3T69N
+ /+XHP1/xr6W9Bn9se23+3BY7aqPWedo/Fz663xb34sXAoKXFX38SicTj4Q8++4crPgQSiQC66NTF6Iivi+CZ7slGXxLqAp/6IJ6+bCx2
+ 5Yqu70SBP3RNv9iJovG9db7468sUCsVdRzJfFjf7WI0WOfTc1P/wMkj/1S7c0bFQLzareYWO42i+YgvU44M+GovjmH+YM23gU/hVzhpD
+ bQuF8xfZK4+2+a9stE+bW6PnFuTedZC341jxYr+nH/FoORZpZKu8t3v4LZn3I77naDrNXe1dT5uRrffJ0151VRbYer+P1fojO7dXO8ii
+ OCpnnzaui9oZz77GdBvX65hq661SjzHQOT+TcWy2M5+I38odelKUL+2O4V3GluPsRc1J/Ek+LuNWe9ORB8305COZ88xL5ZSpHfvMLbKp
+ smZDWemHv20gxjO7xc5h2oIvxN+lEda/Vx/VHbOOxW8ViT56TBGvbcuLhH9J8+WXh52Yq53D4qd/wAae5kViyhj8jZ0WuJ2P5lT1fZyD
+ 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
+ bMN5pU2JE36PWPKe5txigHbNfyGMQTy9fBa9+nT71mostvSR2Do/7cq+HXpejTS3KMeo7zqXLfSF97mI7Dym9hc5txgjX+N5XQ2v0UqF
+ 95ikLZnH85ak8fvxlH7nC4l+mHen5qsE2cKmkfp6nN4XeYnFXfyL+2Rh34j9aIxIxzguH8zFaucw7Tymy/bwPiYpslHiXIGPYo/GC/nW
+ 1rjWj+xVNpIzzy2fSoXn2OqzF/QF+ThdJ2Ms5CNq9h5PdSTasNXYrlNyWWQ7kxXiPbradTqx099i/ZcyXS7++ju92Lnajh2/eWqv7eo3
+ fpQf5C4L9Pr72u9D2qo9qPiwqL3acStxV7/51EX2ypvvav6Qc7NdjaHXj+ijdRJoc71Q+H4eKJcY4XmgHY9Hj7HHMLnldbBrevBqu/Cz
+ /l67Pf0oD7cjjzaRSCROghaasjicSDw06r2qBeJE4pqYLT7J04YtF660g1zjVH65E4U47Hp58uOLAnDYSSKxLU5/2eBYjbTICduq92OI
+ ePaLPXfbAPVFjXZFp0VN4PBCdNAdclnufgb0OPGiwxc7YrVzuMX64I//fbOQY6FNpXhe67y0YwEN5xXU7OKcD2NMc2aMZqsvaz3nhc3a
+ rs8hSW3bMSzk2lJHoo5+t4bmwHbE+3GNeLXvx1tk7CvRnjztyFNf+8LTp9sWqnxgW+nA8/pb7NpTe4/p41W5yNxuD68y9jkux1jYBDva
+ 1C7y9b62alP7pqdvj/G0Y66P77G0dflMF/kyr0AXflai6TppLOW9332LbDRmZK86l3U70amMfbUnDxuNpzxtZ32XU+Zjr3ToNz4aE7K9
+ iHJRWTTGrFX7SgMdfZw85ky+ZTviaw4b92hg91SARLz5v3ShD4HiZPctNqp/+i08jKlrgO7H3Jo/bRf9EV9a/f3tfywVfW0RD1T6YQ5i
+ M/3NJzGu8zKnijoPzCEaA3LGqnxwbsxmuF5rdqvzAHmj6XlYHI/0vQW5D1oZp9upj/dnfI0RydBv8sifdrR1G8rZJhKJxEnQQlOhRCLx
+ uFjcr2gTiWtitBDFApZy1dHefRa+h76+JOhLW4TZy4zGqeP6mEUWob9wqa359baQF0MjHIqaxV/zqHGW//QzAooyLEKHO4dbrCgPLVgf
+ M6+Hb/tKfM258Fv+w5wZo7XDnDlmsdEXy/pS1+Q9DnPzdkXNT/XkIb81mL8fR6WWK/VRznt4+JIoU7tKpa92SqG9+ETj8FwvZMvrr8rU
+ t8Ys5GN1XRuPFNlqf8RrP7RprYy1yhs0813IJryMsdB52+OKr8YZybTvOh9TeerMRgssh3u0yGFDP41FX9pQ7rbQkdhXvdtS5jrlGS8c
+ Q2SRbySb8aAaV+SRPtQVnnmN8oF8L2iv/pfiNc+qK/LOi523ridFeZJmvgM+fLZwDPZHdjXG0x9hIqCgqDt2gfqbXmJs/X4T1Z7jSe7L
+ PEwX9DWPwzeHmz443kqF1z/sjLBYS2kMi+X8MeuKxRgaq4w3/X1oFKE+i4ru6POgY3g+kUzzoaxSEAvU++oXxHA/6NRWbeinPnt47SNG
+ IpFInAQtNGVxOJF4aNR7VQvEicQ1wcVmX+Q2XhevqqNMW1L3O8j5ksAXCd+pSvSCK+P0MZdxVruJFuOtXwoXxUmN7byMp4UTRY+FsTi+
+ 9htFx4i8GZ859kIrY0kM9IfHUnz05YvzERVnw3kl3+lwXtx/mHPLbzF3Lc4w5+Kj8wK7HmcRw3glHU99VQeC7tbQOem5NV51zNH7Ea++
+ lNe+xVGdEuXaukxtKwU6jVX5p+tvdT9q7BrPZB5vZOt8G/eJNz2JMh+n+Q/zjnxdx35tZWz6eeuk8SpJTMZT3yjeHn0UkzmjLTTdOTz0
+ b7y2lI/0bEf8XrtKYuvjkbzvsi1+pq9jikzlW/nQZi881ozn2Kqrsg1/+pLcTuNGeo9T5SKL7FymfI2x49lSKbDruoM+KjD2ncTiD+B+
+ eIo//iNv/d2CzSLn1rb8DzHEhjxtu83yX+f0+5B27k++0jJ/xWEumr3nBBrGfYp5OM6t9drBZx1rcm5g03MarBckzvw8tFicLx3D+Ujm
+ eo/lvtQrRXYui2xVB762gb/6Uq8xoEskEomToIWmQolE4nGxuF/RJhLXRF98ysITMl2Eui6Se1sJvPSrL/vSMqaPubI3n1VOait24DW2
+ 8tSjJUVxyNNGx9Z+j+1ts41km76tbWPx5asXh6s+8Gn2laqs0Gos5bVtfPU1vfqqPGrhX+y1IFV3SUV5ME/XqU2l0m9xu0xtbw3kwtyZ
+ G2mUo8tGvMpAGnOhK/xiPPPzOJXMhzlHOlLp6/VHH/AO/YOG+ne++EV/1AB6Ychzk/5u32Z/XN7FFzb0Z19Jj0uJ41rL8Rf/HLoRdVr4
+ iI6v54a4NQcZh1T6jKeoxbGiWxWHeWyM03ICjXYqrubY4i7+2TttgtyerpG13YrHeDO98irTPF2nvJ7jla6QxhnlMhoL8r3QWItzHfAg
+ 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
+ F+oLkL0MgfASxJcl9lUOvrbiSxvXRTFo5zxt6asytZ31vY34We7Kb+lcprweC/jebzTyIx8ed+PdRmXKR7JRHmhnOrTQdxvTkaK++nlM
+ kOvQf1R4rqSoz+Mm6TWnduS3Ynu7JVMa+XBM1fV8zVZb5yOZ+oziKc9x3dbtZrz23SaKrX3qI7tRS9L+Fs92NJaSymZ2JB/D5cq7TPOp
+ YwU+nSyG60e5juKypV/0fGFeWzG8VXJZ1O9jiF7t1CYxx+g60TkczbXL2Xe/rlO7Fp96EOMo763qNaZSIvGcoO+bha4NFiPLyKtvzmrh
+ cLRrVms7o6Ljsb6A7xJlAXAU7xI7h2e+tImKtseAx4F4KHgeA+SGY4y+ratF12OOYXb+9VMSo5gcd6R3nJonQPmoOHzKnJ6L3DmcSLxC
+ LO5XtInEvRG+IPHliH2TK+lLGWNQpzGP4WvciV55ta18kVM28oUetBXbecbesmXr42z5KQ8/77tM/fS43U750BfU/CMf5ZnHagzRe2zv
+ q0x1zwGab8gHMp0zlanNLJbbOr/qF17Hcn3Ej/ROp/iqbHYs3h7Lq2yr7/OzmjPzdaKdxtjDa7/LW6vj+zxpDJepbo/fVp8tY7mMpHLl
+ ZzL6qk2k9/iR3mM4ue+WLOqP+MR+cM4WVObSz6Gf8+i+GLW8JpRmcZw8HiiKk0g8J7TaEN87rw0t4nrRjcXbrR2ZLC5q0fYcX+4S5c5h
+ 5AgbkO76VdAGflHRUXfBetGROYxiA/CBzbn/6p0F11N2ufIYfXe07qo99hhm5587v2cxOaejPwAozsnTrwnFOXN6LvKbw4nEK0S9V+V+
+ bXdxInF/8MWIL0T6oqRy1bkdSfsjvvoGuiim87RRncoXNsarzxbvMUgje7TUd1uTq+0WH/moTaVmR1u3U90qF7HtskYz/2gM7VcyG+UX
+ do2eE/wYyOs8jOZMefdzGWlla7G6f+N73/SRL/muN523x/J7ZaQoh718JCPPFvGjedBxaUOZx2BL0n4Um3zU9zGUd9tItsdvltPUx+Ru
+ G+notyXTftc3HW1W/iYnub3qR3wk2+KRByhxPHDuOI9o9ZrQOfa5rnYio73ael/lURxSZK86HxuUSDwn6PtmoWtj9s3Zb37zm1W+9a+9
+ UcSDnRZdz/EFuEtUyW0Ux+wc/uCDD5rkgNGOVAWL3bDFpyhOBcZAHBQyZ7ttWSAdkfseewwotgKz88/52kN7isPAMXn6DumR7945vQZy
+ 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
+ fNPEanaQ3v8yTr9LFDOMdd0yii29F0U2dq7T1tnsocXgOxD2Ht/qImbzHaj+83thawMPOYO0fYTQXmKOdSOXv4en+0O5uqcQXB9d15hb
+ pOXl96zko2YZt5/PyX7t9yetR/46xwi9+ED/D3sc10a+b6i5uUZeJ/Qi2YljrR91sj+vlt+Rtsb2O3Kqu/3z/VQT6/Ka3NjdrIl9htCe
+ 61j8+C6e3sXc4qpQHoTyBh2xRU//94JzkUP5w/dFfNM/9zgOgjnbZzGsRy3INLfo4VffbGRZ1YE+y8c84owxxhhjjDHGEHhoigcmfWDL
+ 5myDXebxYApqA4HzJB7NrtoIaGvwCadoKGxzz02hoJ+CKrJpwrSakYPmRNDfNVvs8dA8PFTzHjO91cRa0ZQ4xVBsSNsTfGg28Im4MabZ
+ Yixr8H3s7xQl2dynltdrFeFr7k0ivo4YUbPsMW0qteuNcdbk2jSGqq/VprrnBtppbW7o1PvI+2/r4jsS9HuNPdXYppNs9gMpsXxP6ncH
+ 9XiEZPV47VYT1xFx9fpWeS1n833UtTm+5Wy+Qy1mff/P97nff47JBHvB2NbntfSzGPbAdWQP2rCEPag1I57XLbL5DjR7fH7pbxfrQmCr
+ a47fO9wP7L/e2yxPx5ASE+uCfl1YX+5ZvzdSH/vpn0/LH/JQs+Yl32PUK+NmT30/xc8S9pYTgvWGfZCf/8zpzdvmRy5/Pn0Nyb3oz6u9
+ 70irz9+Rer+wfsnH3uqeu/3k4zX5s+d7WPeLPNnzyT6ezN1+XpTH+axzbKm3+a1rfJI7fF9Qq46TP/f6ekWy/YW0/D6f7SHLVz1qYc1Z
+ HAvsWZ3Mz3FVEnvkGmOMMcYYY4wh8JClD1BVypwf5jiGY9VW4rl5G2gjocaWcWgOkw8PxoHmbh7myYfTVlG324twTqCNj6F50HLqXqp+
+ 2ivbI394EG8x2Hetg/rFx80N/lf4p2OpxSfe+nXGPihme5+KvcXxZzDkt9xhvTaiIXJu4DV/kc01t5yNnfcodYfTlS1u2tQpIz5PUP3h
+ q1JqRywEa1Je/x60mPR7gHoRE6PsPb0+jitzfL79voWv2D/88MNqf/8Hn5xiW97X/+S/Vjvo+yi+4TtE6+AeBvqbmJ4YlNy4/5l/M4ZE
+ HNtirmu1PaT3CPmtxuYe0ecy/Q6UvO/85BfNc6Kv23Lz38ApF7WHPRXBNfTfabHxb7TG47pZ2Nb0ze+UY0rd9N4gpo1YW38fuC+n73Gr
+ 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
+ asyuETpGY4wxxhhjjDEEHpbwEMUPUOxjfzpvD2BcYzUP0XpsY1/kzXz6kKwxWFfX1pqsa+5szg/jWR3Es01jMmGf1taHb6zBcZkty2Gb
+ xqx05LJo7SwXvkw4rkrRww5bVq9Li81qbWLFlumX2jJfNr9ob+SDTfO7lDlfO2SIazE6n9XkNSEck/mzPc9GxGrdISak6LV24pvp2A9s
+ WT2NYR/ms/pcI+aznCP1ZmOVokc+bLzm6jrSWjTXnNnIesTvxaiOHLVrjcyHPcZ1Ys76qt5KV5uOqzU5jnXO7X7JS/fOMRKvtbM1VIfA
+ xnms63hXPfbO64doTGZDHtsxZx/7D0nL1RxewxhjjDHGGGMMwQ9NrM/GTI+HrSav/863X4Bf+f3v5jmIr/MD9dWGOa07xPTa57gf//wf
+ znvKarIe0utSzWxebS0nq3epLfNVKfpsPY1TW6bH2GtJTrEP9wt+jtGx7W3z+cO/yo2R99Jqdal2iud5Fos4zmU79Jaz+52d1Wn5470i
+ v66ntpmv1d3YeA49i4W9xiUx2bzGtrnqbONc/t5oTcRnMovj+aom69Wf5LGN7Vm97B7BpzriNBa+Gktxkrf5rhRb+pvhfNSQWoNd49TW
+ cg79Pjmnzpsd/m5nfRE/W6PGT3yhhz+TWY7OMx11q73ZMOc1VLiG6jrXnKEOrZmJ1mKBP2SIafpqT7Oas5ijtXTPOs5snKfXFXOty/pq
+ 5NwsJiT8xhhjjDHGGGMIPEjFyA9QLGzf0b/4e3/ZWg+t+cAPa4jHCJ/6VVcb4tmW5VL80JTJ8lmnvC5q01iIzo/YVjV4D7xu6DyyXW1V
+ ig672jin6Zv7xTEQrt/09PPX2FRkL4jveW1kH+et4jh+yD3NL/rOaq0Sl363NJ9lVutSf5WiY62Qrjc7ZMgpspqzjnqwYeTaNbbYea7x
+ WT7P+XODPvhF1+vTPNiGnCI851yNXeV1XWJ0T1qj2LLf1eb7h3jN79LWwRxx2R7Zlq2FOlluy+nCPh05Louf6T2W5lmcxs/iEMP1Br3F
+ cD1dYzbOdNQ9khexqzWz+7CJaYI5arKNYzOdbbPvk+q8J/ZxLsuwhtjUt5oPvqLrta70kOzeGGOMMcYYY4wh+KEJwg9ReLCqI8VxTn84
+ PDXahgYI15LYwc71Mn3Ppj7ed5EffvLzuqdf/YO/GuP29FqHbDpHHI/X2GZ6loN52Uvc4+D7H//9iy/85vuD7xTbdAj71Ua+6f3SUfTN
+ 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
+ WlgD1HuFtbCfKshtOvxhg7At9DpSDa6nOnLYhzGrrzYeVzrmWT77eA6dc+h+97iqt3j42F/zmgxzqtVzyK97YBvWzfIgnJ/VYvvGL/U0
+ blgbccWHeYzGGGOMMcYYYwh+gOKHK7Wpnj0olnF7crT4ol4RNOr66TEI1YjGAZqLp9Odp3x+hcGluSHasEQTKeinSHEdJX56Hclap0bJ
+ yR92NEr4dCr2gXw0Y+rpZVpX46p0neKabdMMQ0yLG6+75Tbha+y5xc7XwO8WHfZUYodraOtu7hvWK7k4aVwbUHwtIW3tXr/lVF3HnnNe
+ D9cf++b68IcNOu836vD19vvU1lre3yLb3OLnvRc9rcExyXVdVbf5shPdwzpljPjNbyV8EIrF57z67dV50+/yW91ed8mhvBhn1x357BvW
+ DilxvG7/flLtmG/8JPgORUxdu9k396jV4trYW8Brb6655SzvOwvWKD6sMeyj+TCC0/097XPzmSGP6vM+h+/MpGaXkj/9zCDDmqd8NInj
+ PvSaiJ0J5W/WwLzH6pxiIDpn2zS2jagZI8fOdJ0jv0qxZ/vECF+I1mSbjjNda7FdYzmfZVaL7w/nruqpT3MhGsfxnGOMMcYYY4wxhogH
+ Jn2I4jl02GcPqU2ieTI0OhBbhE/dRTOi2of882nUgJsvd8kNyRpOaL4EbMf1Do2QqAO/rNVP0cla0Wip+0DNFsPX0hvI8PM1tX0gb/C3
+ tWLfoJ+GJRmuG/VC5BrqKchqP9VGXoz9XtK66TWUmvz5R0Oo5xWJnKHxFvZhTzQvtZC3kSHmndrsDWIfwXAStsRhP9HoDvrniRoUU/dM
+ 60zvb1K/XhN8VIMbdsO9VIl6GKmu3seTntRtfr7P9beCmsgvsvmthB1rIDbmRfge1Hph53oSz9+NIT7GmpP8VlGnxAz3U+uXMb3ulst7
+ rd9p8qHGcF+5dpN0/Zo/+82Mjd/88/rWcCJ2iCnjZk2pubnvOtZaY85w/Rh1rcgrkn5mkMidfWbhL3WzmpyPffXmcK153lPU7/VaDv58
+ rr9nsg/XoyPHZTEaxzV73iRHbZk9q4vYqMtrHF1Pa2Fc5WNeY8Te81qM6uHP8jiGYzPfbA3Y2ZbN2YYRubo3jcuEfZFvjDHGGGOMMYaI
+ B6XNA1sb9SEMsSH8sMV5xQeGxmfL4YYsNxXDjxOPAZ/GvVNuyYtmxKZ50fzcsKnNv34tY/O4NjQiT9YK+nolh9cKxsbdeLJ6c7ITQnsY
+ 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"/>
+ <rect v:rectContext="foreign" x="0" y="0.750001" width="679.259" height="222.739" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i11.svg b/doc/guides/prog_guide/img/efd_i11.svg
new file mode 100644
index 0000000..2f245de
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i11.svg
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i11.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="9.4379in" height="2.35729in"
+ viewBox="0 0 679.529 169.725" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.750008" width="678.779" height="168.975" class="st1"/>
+ <image x="0" y="0.750008" width="678.779" height="168.975" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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"/>
+ <rect v:rectContext="foreign" x="0" y="0.750008" width="678.779" height="168.975" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i12.svg b/doc/guides/prog_guide/img/efd_i12.svg
new file mode 100644
index 0000000..1b7518c
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i12.svg
@@ -0,0 +1,590 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i12.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="9.40456in" height="4.44413in"
+ viewBox="0 0 677.129 319.978" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.750009" width="676.379" height="319.228" class="st1"/>
+ <image x="0" y="0.750009" width="676.379" height="319.228" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ 8JdULZcuXSofbffiiy/WnndwcFA+0m6V5/VZz9SZrvc/+cps76vnarn0R98oH2021Pae9eu7ieMpdVav76rbOtR2NlECA+yAXDl7J+f3
+ cgXtnS9aO13QXjh6s0i+xJC76VoCx6MrF5WauXlVpV2QG2HatWSL5xO0rXfXEnbZ9W2bb5V4f6WFXt991ZRV92Fa6qcjaXPrsK5t6LNv
+ q5/n1ifeN4seX2cJvK79dqYBYEckZUof6yyB33777dkDDzxQK6PiPPbYY7Nbt26VU9elJVaVRWXWKs/rs56pM13vP/vj2QP/2b98qgCu
+ 8tiVi7Nbt39UTv2Jobb3rF/fTRxPqbN6fVfd1qG2cxElMMCGXTh8PFPOPrF3/urTe7mC9sLRC0VOF7T7R9eKP/MFg5xpupbA1XRBWk7F
+ BVnbr7O3FXyrFJhtRWFI0/L6rm/brQiqNO3XIfZVU4bch3FZmc5rndvQZ98uSlsxH29Tbn277tu2Enid++1MA8COSMqUPtZVAp+cnMwe
+ euihUyXU7du3Z0899dTdn587d27+80pTiVWlqcxa9XmrrmfqzNf7wx/PHvrP/9Ldwvfg+p3Robc/+nD21LW/fvfn517/d+c/rwy1vWf9
+ +p718lJn+fqusq1DbWdXSmCAFvtXH80WtPtXv1BcuJ8uaC9efb7483RBeyf5i3+ZXLoUaotKw0WjH6tUBV9uWasUmItGSjaVaX3XNy4T
+ c+vati1D7KumDLkP43kNvf/a0mffdkm17elz27Y3fbxtuW37Zp377UwDwI5IypQ+1lUCx7/GnhZzackV/3p7+tg999wz+/N//s/f/f+m
+ MmvV5626nqkzX+/oFhCnit6kII5vDTHU9p7163vWy0utOp9VnrfKtg61nV0pgYGtdfHokWxBe+Ho80VOF7QXvvlc8WeunA3JX5iLrJB4
+ hO8iTSMTu47MjEuwttHEXQrMtpGUVZpK4CHWt5pHbj26PK/Pspsy9D5c5/5ry6r7tks2WQKve7+dWQDYEUmZ0sc6SuCmoirWVnSFUY3V
+ r7unox/byqxln9d3PVNntt4tJW8lVxIPtb1n/fpu6nhKncXr22dbh9rOLpTAwFrsX3s4W9DuH50rLniXK2j3j06KP/MXziIjTFVMtWkr
+ vUK6zCOVllvLFphNhXScRSXmMtL1bSvq2krMIZbdlKH34Tr3X1tW3bdV4v3QZJMl8DKW2W9nFgB2RFKm9LGOEji+n2kYkfjGG2+Uj3wi
+ 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
+ AABsv729/z9i8B8owrMbcAAAAABJRU5ErkJggg=="/>
+ <rect v:rectContext="foreign" x="0" y="0.750009" width="676.379" height="319.228" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i13.svg b/doc/guides/prog_guide/img/efd_i13.svg
new file mode 100644
index 0000000..6720042
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i13.svg
@@ -0,0 +1,1407 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i13.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="9.79126in" height="4.79083in"
+ viewBox="0 0 704.971 344.94" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.749985" width="704.221" height="344.19" class="st1"/>
+ <image x="0" y="0.749985" width="704.221" height="344.19" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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"/>
+ <rect v:rectContext="foreign" x="0" y="0.749985" width="704.221" height="344.19" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i2.svg b/doc/guides/prog_guide/img/efd_i2.svg
new file mode 100644
index 0000000..9728084
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i2.svg
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i2.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="2.46396in" height="2.14393in"
+ viewBox="0 0 177.405 154.363" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.749998" width="176.655" height="153.613" class="st1"/>
+ <image x="0" y="0.749998" width="176.655" height="153.613" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ bd6by2Ty/wFz3+YoxW5tWwAAAABJRU5ErkJggg=="/>
+ <rect v:rectContext="foreign" x="0" y="0.749998" width="176.655" height="153.613" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i3.svg b/doc/guides/prog_guide/img/efd_i3.svg
new file mode 100644
index 0000000..7e04ba6
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i3.svg
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i3.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.06334in" height="4.95902in"
+ viewBox="0 0 436.561 357.05" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.750013" width="435.811" height="356.3" class="st1"/>
+ <image x="0" y="0.750013" width="435.811" height="356.3" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ VuDR+vaV0QU6ROM8+9Tzg//jp7+bXtpaXNte9we2A6SmC7UTClUqVd7FWk2vH/7LzVU0utHLoSTfS1CuF/LMjSpXKmOT99+8MfPK4Kx7
+ /DL1zy/5fnzR9++fP/fp715mPPvTp0+fePvejy76fva72Zcu+aSlXOI3rs/em5jO5fO6I8ev/Gbi2XMPpESGRj/x1n3YMfhegnK9kGeu
+ EyTcSrWWSmc/GZ/90huL0t9odtL0j1Ozz//hZyN/8sxZgNlnvnftj59+j/5Z6vpcF/r6yGwkmiCvM9a7VwV4BkM0PoFCKbo0HUSeeUjI
+ M9epVquVK+Rmws3g/vtDPikvO+06sf74qdOf/f51oNp/+NkwK/mCtoJ7/NsP5xbXthK5cq5IXpfc+PMe8gylK+SZt4Q8c50Iz6q1bJHc
+ HO9b2nj58gMpOztpMkRjnxc/94Obf/rM2T968p0vvLbwxTegZKlezU1+/vz8hG9pN1GMZctZ9iyB8zwrDA48POnnE010f4htxdpgnJeg
+ ZPmDj70evM8nLBbyzFtCnrlO5Hpj7QjGZ4lcZS+eH51+8I335sUE7bQXvwj/vwZe+H/+6S2gGivk/9eB5wo//vbC8KRv+yC7lyiS8Rl7
+ loD3dF2t84wAZkhzg0BjSQtqjWfxyInukoyE0X7wurKwqTaFPEMpQp65UZBxSxUyRDtMl7YjqY/HZr/6pms4QX4qA0M8i3/xiwllcMZL
+ 6tVc4C+9sTg0NrsWiu/ECtEM+dvWdHDGO1mUS3nWhUytjbaXedbR9yILeeYtIc/cKMi51dpRsVxLFyqRVGlj5/Da8KyUrJ02HaVJdtng
+ 7Oxt38L6TjBWiKSKqXylyP42G+9jjdzLs4HILp+wRpZkeXcJeYZShDxzqchVR/pK+2SuvJ8s+pa3fvvhnJSvHTYfqKl2F8xevvxgenF9
+ O1oIJ0vsD2dXjP+KjXU8o8MUHoOQZEnOVcoJohjPkid5oc5FRdKsughpX4vAehJv0pQQjNICn+QlrQXfbBV11ZuSN1YUa4pPaFCkv5RB
+ SORKLCtcG/QJjXDpbKnx1jUT8sxbQp65VzXlrYmQjveSxXHf0vPn3fNDmkov9sFdv5x94735kakHfvqzWZy/gov0J+/ZBrXHs4bViRlT
+ Tdb1/K7zMxjLrbyQ1NQdh0GK12Z2I57pNUXLFVZBOVu2HhWVMCnXF5J+S9Hypo75zc9gK/SX0oS061vT2zRGWR0+abe0ydY1E/LMW0Ke
+ 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
+ YXt5AAAAAElFTkSuQmCC"/>
+ <rect v:rectContext="foreign" x="0" y="0.750013" width="435.811" height="356.3" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i4.svg b/doc/guides/prog_guide/img/efd_i4.svg
new file mode 100644
index 0000000..f69c899
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i4.svg
@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i4.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="3.79074in" height="2.71065in"
+ viewBox="0 0 272.934 195.167" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.749993" width="272.184" height="194.417" class="st1"/>
+ <image x="0" y="0.749993" width="272.184" height="194.417" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ EJSrHObmAtapLHkcvNHNjRxUDn6BnaCZh6hZqsv42XIxPHXe1y6hSTtrPPfzksT1nRtu9twGNY7+0fldz2vpl+uSqgxN2R2mU8747JHz
+ adm6DY1et++ocJmUr3ig5qe61i2UueahgjU3MzhxzUmDlm6iY9u2O1Lh0ulKrrxecdjq7DBImcJCDadb7/tr0nVz6nf/eNJzn0JRpjI0
+ 2aODGMUdhDtcJuUrHqh5qT51C2Wueahgzc30g9RsNPCj7I2NrSuvv9kzrjfGJY/8pAoHNawyXdPH3xnkuV8hKJsyNGlXmE52dRAj1+47
+ Klwm5SseqPmovnULZa55qGDNzTROXHPQ5L06ffO6nxypaLnoP1yJ3fG97uqYvs0dkzsM1PByX4dzv3oJjd9R4xm20JRNGZrg0UEM5w7C
+ HQ6C8q361i2U3eahgjU3UzlxzUH9Pb6F/ObRJ7MKJ52OO1wnj47JHQZqePn5OmST9vEpOgh3OAjKt+pbt1B2m4cK1txMPkDNQn2XbKJj
+ HKblC/wtZOz2Gs+wr76fXKmdYf/2uvfkOqd+zabJHafo/Z3Jld2WVPqhXOm99hG50/4tbmTc60rKyqjz5AVJ+03Yo9MVPzp6tEr2d4ar
+ qwavI/r2g0RfvzeuX3eKrx+3h+jqRz9dL3r0vfT7eoVJp2yuQ6rzbOzr4FYuZcidVmcaf+GaD5Hu2OnicSpVmUm3Ty7yynu7frmP7T5e
+ ffK/rtc823zLFM693T5nd/q99q2P6nLe9albTmXKE6+ylipdubRl7rDp6kU2YVMdW5TPa+VXFay5mcSJaw7q49GI/OudQZ5h0+mvWVT8
+ X3HH5NxnbIoGxi1p8MZwg+fcV+RO+6U/+NFR8UklG8KVzN4nm3TW5fyd6rY42Zz8nc2Je51Tsn38XqI7X/XeLpIwXsdyK5vzk4bPuU9T
+ XAcv5VKG3GmW+F+fNP+osuyU+7xTxeNOZzbpEnnFn40yxf/oW32TOhF3GuuS//W95tnkWzbh3NvleDf89o9Hlr3kbkdyUX3Ouy51y0uZ
+ 8sR9HDEWb7CxcMbhFc5L7rbMvU+qts5dptznlc2xRXWtE8WggjU3EzhxzUGj01R2qXSDudJ57efWw1kU9ju5UbLDpzuul7zS0svDmLnl
+ PGZH18hTOv2TK73zWLno2YnJxuSP7yQvu/WNDkQ/ecp7m60r7icattX7eE5lcx2+yQ2OHb4prkMq5VKGck23Lfd1dcfjPr9cyowo13KT
+ zTm75U5jrvmfj2ueKd+yDVfX65hNeXKrvueda91KpXR54nUtvcpUXdsyd/yp0us+V2ccDV0nikUFa27G7admowezbGD/7+9Peu7v1Euu
+ gi+VxyvczzocfevgtUkLjmzv6VHJz+FvUyO21aQN447H1sgdYWrvaFAyHU8anIFr9iXFka0e6ONtToZsiW/v73HrKVMYMUDdPko+TjoV
+ 6nXIRtmk3X09vcJ6hXHH5Q7jvu7O/PE6J3fdcedNOnmlz7n/mN06Xe4x7O9OY675n49rninfsg3nlQeiTPlQl/qZj/MWZVu3UilVnnjl
+ xT+6D8q4f6bzcOaVOy+98jFTmIasE8WkgjU37++jZqWbXRU/naSwDt9a4xnPS2OTK/4VP745YxipPANW7zsq3IjtR1f2R7sNOrL93cVH
+ N0ZiwJxx2HqwU3KFc8Zjy52uVHGl0+jdRHe4bi+JaXlvc/3CiLnpuuTT7ZlUqNchG2WTdq80ZXOO7rLrjseZB6N36XSZo5H3Kvd2mFR5
+ l07uMpkufmc497Fyyf98XfN0+eZUpnBex8k2H3IpY/k6b1E25TOdUuWJuw1uqLYs0/7u8uQ8v4auE8WkgjU3YzhxzU0vuCpEOolj7zhx
+ QcY4pGK4w7gr8R1c8dxhbP3FVRGd8b3jqoSp0jTSVSGl0vXjSucON8zV6HilPZOG7yL6gWvS8HNTM4f56+D0YcT8DGLz4wyTToV4HbJV
+ Nml3XyvR37mRdodzp8197d3xOLe7y40tadCHcoNux1FXufPfK/0id364zyGX/M/XNU+Xb05lCpftdRS58yGX65Cv8xZlUz7TyStP/tVr
+ eFZx5qMtc5cX97Hc5++8Hg1dJ4pJBWtuRnPimquGejQ4XpICPYQLtHPf5z0qvnP7CK4c33BUDrshdoZxqrurIjqP6d4mFb0vV3R3HNme
+ j1te55dJvdcm304SUzKQTUl9w9z4FDdYO5PDpFMhXodslSntIvc1TZV+dzh32jJtf8DV0HvJK32ZlEv+Z0pjtvmfz2ueKU226pv/TqVL
+ Tzrl87xF2ZTPdHKfs5dSxZnNvl5ynoM7P5x5nm6brYaqE8WmgjU3I/eyS4Us/fm11IX5b+zqnWGfG5Nc8S/nQu7cPmQbV87PJDdmfVbt
+ SwrjVLrwXRcd3ah7xeWOI1tlSpuX3lj4qSER/d9rmcPcwMZlyI70YbziSadCvA7ZKlPaRdmmP1O4TNuH7eTG/tpPG/t0+jx3IIO31BzZ
+ N51yyf9MYetaD9IdU5QufLZxZQqXS5pyTb+tXPfLFD6b8plO7vi9VFJaRi+xAavLvl7KdA52O+4uS17n1lB1othUsOZmOCcOStZgrlgn
+ uSrWrY88mRTmWVeluYwrh3O7O44WXOl6caVzhnEqXfi3XRUxVVxe6c5GmdLmpSfGJ5uSBwcdHaZD78xhsoknnQrxOmSrTGkXZZv+TOGy
+ jef+NAbfqWzPPZf8zxS2rvUgU1rThc82rkzhcklTrum3let+mcJnUz7TyR1/KmVT7rNVpny3j+Uu5w+z6bH3cSvfdaLYVLDmZhgnrtg1
+ yFXA5dvCC/xtwSusLa+Kncv299j1X+pw/ZmO+RY33G0cDbd8ExjA3wQybXPKfZ5S2XpyZXOHy4fcxuXpqcnb39tFdNsr6cOIMsWTSYV4
+ HbJVprSLsr2mmcLVpWz85E/J8zfckg7Baz+ncsn/TGnMNv/zec3daUoVlzuOTPmfLk11LWf5PG9RNuUzndznLJI0/e/9uUnpFLnLUl3K
+ ayo5y7HE0/3jnUnHzyXufNSJYlPBmpshe6joNWiHTl93VaZvcEX1Cmurg8utu8M/PTq54nvFd6OrItzyyJNHhbGV7nhdFnIjdPynjdDZ
+ F15C/TbXJO0vcp+nNCTPTVhwVLj6auAOou///VND8o0/EXVa3DBhMqkQr0O2yibtA7Ye3cj3WLkv53DZxpNK7v1F6fLRKXf+P9h1kGc4
+ d36405hL/ufrmrvPO1WdcqctU/6Lss0Hr3KRSvk6b1F90iFKd87uuN3XMp9tmftYt/3jmaRrlet52apPnSgmFay5GcyJaw76o6sii6RC
+ 9eEK5Q57g6uBEP2FK6UzzFMeFd+53SuMNHjducFzh+vnUUmcx3vDo1H3SrfIfZ6/5MrmFa4+6rqa6Ft/+dSUXH4/Uc+NDRMmkwr1OmSj
+ bNLuTlO2aXeHS7c92/xxh8u2bLnLpFe+DfD4AuJORy75n69r7pUud1sgcrcZmfJflG0+5FKH83XeomzKZzqlK3PZ5Gu+2jKvc3XK63o2
+ dJ0oJhWsuRm0m11yM1DfLekLeDpJwe62Yl9SfO5CLQ1V7001SWH6b9fpElcFlm8gz45fcCTM6wuSG2zRpdfdnBSPO4zXsVKFFf3ib08m
+ hbnhj/GG2H2cbNVxwaeGRHTbqw0XJpPc18HrnJriOmSjbMqQu9x6lcVswqXb7pU/7rR41Z8H3h50ZHs6ee3rjN/r+CL3OeSS//m65iK7
+ vthyp8u93SuMVx6I3OeQ6ViZlM/zzqZupVOmMpmp/Huls65tmdc1EqUqQw1dJ4pJBWtuBnDimouecFWmbPVnLrDuuDp5VDxbUtHscL25
+ Apzo0ailkjQAb3MDkO5YZ3El68WVzBnGqXtfPXqUKp1+zg2GVzyp9K9xyabk/oENFyaT3NfUmfdONcV1yKRsypA73V7pyiZcpu251o1c
+ zz3XMilypzHX/M/HNRfVpd3IlP/ZyqvtyaSGOu9UdSuVMpW5vh4Gwn2++WrLUl3DdG1fQ9eJYlHBmpt+u6hZ6dX5qTsUt+Qbz1PjFnjG
+ 03ubThdfc/S3TdHXuRFwhu25ObvGRirHuxtrkvYVudOcKpxT92TZKPyMK7fX/un0h17JpuQ/kxsuTCY9Piq5AXLnvVNNcR3SKZsy5E6z
+ dBBvLd93VFyZwmUTjzsvU6mu552uTEpde2zEzLRprEv+1/ea2/pxim/+tuR6OcNkk/9PvT8/bVtUl7ppKx/nnUvd8lJdypxXmHy0ZV51
+ LV37bquh60QxqGDNTW9OXHPUy2lMjhT6J7jQe+3n1nUejd4l3Ah4hX0nRYMjFbozV2ivfUTutH6OK1J3rkheYZ16lyv0RSk6z1RpzKR3
+ txP9ouOnhkQmAb+wMPcwPbYRfc81mdgdJhv929X4ZHNejX0dMildGXKnNVUaM4XLNh7R3Sk6k1zqRSp51btsz7U++V/Xa+6UV9qd+zuv
+ Y7b571VHc0lTJtXnvOtSt5zKpsx5nf/NbFKcYVKFs5VtutzlOpfy05B1wu8qWHPTcyc7bAiCoCZWt03JnaF0Pl031HiG9Zvc5yYd/euf
+ 7PMMCzWMfv9KskH56V+f9AwH5aaCNTc9OHEQBEENpd8lOhUxK2+xWfEKI3rhw03U2jEycjF/I/cK50e9zebmBJe5eY3NjVdYKP9y57+M
+ uDw2boFnWCg3Fay56c6JgyAIaig9OvLoeQt/eGtQUpg3XZ2PVxg/y31+Ym5eYXPjFRbKv665N/nW72fZaHdho+0VFspNBWtu3t7BrhaC
+ IKiB9OYWnb6aYr5EKknn//LH+zzj86Pe2Hi0uSmm8ytE/dBlaJy6+81BnvtAuatgzc2bnDgIgqCGVCdX555OZdzxv8gdv1c8fpX7/Ivx
+ HAtNV6cwN1+77mbP8FDdVHjmZtiBqCTo1a0mdd5OEARBDa6HRqR+tDZUWkaPjF3guZ/f9eqGMLVzmZvnl+3zDAvlR3d2PPoJp9+9Ocgz
+ LFR3lY48XBDmpg3rFNb5Wt/NKyRBD6zU6XVOIARBEARBULZ6YYsZNzYyWCK+ogDMzXla50WDJVE3L4rQa9sIgiAIgiAoaz20So+bGxks
+ iZsb8RfiM5rE3JzMOld7ctTTkqgLplZTR04kBEEQBEFQtrp+QThubmSwRAZN4v6iUc1NgFXCas1qzzpHu+7un2hDD8QkYX9codNLWwmC
+ IAiCICij/rVeUcuRh0zL3Pz7vcfYV5zLahJzE2K1Yp3AOot1sfbS9N6SsHZjK+jZzSa9wAmGIAiCIAhKp89ProqP2vRav4z9xKWsc1gn
+ sWQQRQZTxHc0OLa5aclqyzqTdaF24ulXa302bZQEnjmxih5ea9BznGgIgiAIgiC3/rVB0XlTq+PG5r191dpVt97OfuIi1udYMngiPkP8
+ RqOZGxkiKmMdy5IZzTL553Ltmt/erfXbskMSWjLikPn9D8N013KdntlCEARBEARBdO9KnW5aFPn0VpQYm3te/A/7iG+xvsT6DOt4VgtW
+ o5kbwZ5ULENGJ7Lk1tTXWN/Vjj/5Zu1/k0dYCXaoxH5+HYIgCIKgZidPH/DuurXaN2+6i/3D91mXsOSWlMy3cT4G3mjmxr41Ja7qONZp
+ LJndLPfKJIE3aLf96wntlVmTtW4rVx11MhAEQRAENU/1Xr9Fe23ODO2RPt3YL/yEdTXrctYXWWew2rHklpTMt2mUycQ29q0pe/RG7o3J
+ 3BtJ2DdY32Ndx/op6xesW1i3seR+mq07IAiCIAgqajn7ffEBt7LEF9zM+jFLBkTE2HyZJXNtZCKxPCUlU18addTGxh69kQTI8JEkSAyO
+ vDZZhpa+zfoB60esG1g3sm5iieGBIAiCIKj5SPp/GaURPyCDHzJacyVL7vjIPBuZ3iKvl5G5vPZcm0YdtXEiB7ZvT4nBkfk3MhHoCyxx
+ YWJyrmCJ0fkuS0Z0xKVBEARBENR8JP2/+AAxNOILvs66kCXvtJGBEdvYOG9HNfqojY19e8oewZGhJHk8XCYDSWI/z5InqcSVyUnIpGN5
+ zMvWxRAEQRAEFaWc/b30/+IDZOBD7vDIxOHPsuSJa5ljIwMkMlDS5MbGxmlwZA6OvNxP3JeYHLlVJQmX0RwxO3Iick9Nhp8gCIIgCCp+
+ Sb8v/b/4APED4gtkpEZMjfgF8Q0yQGLfimpyY2MjCbFNjrguSaQMLclkY0m4PFElZkdOxJZMQoYgCIIgqLhl9/viA8QPiC+QOz3iE8Qv
+ iG8oOGPjxDY4zpEckSRehpvkRCAIgiAIap4SLyCeQLyBbWgK1tS4cY7kOM0OBEEQBEHNW05D4wtTkwr7BCAIgiAIggAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaHE37f54Xc7rV7FZxAAAAAElFTkSuQmCC"/>
+ <rect v:rectContext="foreign" x="0" y="0.749993" width="272.184" height="194.417" class="st1"/>
+ </g>
+ </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/efd_i5.svg b/doc/guides/prog_guide/img/efd_i5.svg
new file mode 100644
index 0000000..d627da0
--- /dev/null
+++ b/doc/guides/prog_guide/img/efd_i5.svg
@@ -0,0 +1,578 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export efd_i5.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.26421in" height="3.07735in"
+ viewBox="0 0 379.023 221.569" xml:space="preserve" color-interpolation-filters="sRGB" class="st2">
+ <v:documentProperties v:langID="1033" v:viewMarkup="false"/>
+
+ <style type="text/css">
+ <![CDATA[
+ .st1 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
+ .st2 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+ ]]>
+ </style>
+
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title>Page-1</title>
+ <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.375,-0.375)">
+ <title>Sheet.1</title>
+ <rect v:rectContext="foreign" x="0" y="0.749997" width="378.273" height="220.819" class="st1"/>
+ <image x="0" y="0.749997" width="378.273" height="220.819" preserveAspectRatio="none" xlink:href="data:image/png;base64,
+ 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
+ Dl5S0XC+K6klGqVxb9dz30177mwNXn6RSWX+pvZ+iJp5ZzeTOTrtNtRLOrVaXL/SXjq97iX57ew/ymYTdtdkoo90QjD0zM6y9aN7yqmv
+ XCzz0h9j4fZcL1U/Qo+3eXAaQqoWtXO8d0U0mHlfE4HF+N113XmpTOYi9ZkrXNf7SH8uxN8n1U2W7716kCYRu4gzdWfp+rz+nNBbtn9s
+ b7n53Tul0W9hBCN88/S43wpOQUhNwg5eUvFwviupFVLiXoAKOYX3R3iunzZrMDRVk4m/qk0PTbvePP25UqtxGbpiuHz55Z9oMLSzdJrS
+ V7qqnGd7yy6j/kcGf/igbpHNunX7ORoMfTM4BSFVjdr6pmrzE1Ufor0Q8R+MJg2em/ZS3jptRz5ZJ2tWX//pndLzlT3FebmPdJn4Xek8
+ 6WviPL2NfHvUz+TBxcNlrazQxiZ4mprrZTLpzC+DUxBSk7CDl1QEaoec70pqHrXZvdKet0Qr7XmooDOyDj80wZDVXoOXUfP/YFFqYfqM
+ 9y+WjV7ZTe1+Z+k24XviTNpdnCd6yf8+eZCMWv60rJdV0WBIo6HMT4NTEFL1aFtxq/rKW16D+4pGMsiqJe01fK5/W/qJ+sap7/9Hur2w
+ U3at0Us7ijNe25GRu8gvpv9R5qjrNXp16YwXjE6kvbUaDP1R971W/9krOAUhNQk7eEli0Qqa810JieClXUzJmOCl3AWSSSMjENdLfap/
+ W/t64zz51cw/izNVE+jXtpBO03bWRFqDocf6yR/eOFMWyWJJeevSGXc9YiEEQ6vcxszRuu/1qzOZrYNTEFK1aL2/nZf64jPPc2eucb3X
+ Mxig8PPytExKT5d9Zh4jzitfVd/pJd2f7SXOxO3EebKnnPDqGbI4tWyF+so03fcj339cb4H6z5H1nvcQ/p3KuGcEpyGkalFTZwcvqTzU
+ yDjflZAATQSO8Fx3XZ3nPlef8hb5Ju3P2Fgv96waITu9eoAGQ7tK5yk9pftz22ow1Eu6PLGdXPjOZbLaW7tQbX+a56b9xdoaDM1NN2R+
+ l/K8R/Fv9anTg9MQUrVo3b+j533hZ9RYOurhPxmRicufka9P+7G2H1to0LOtdJn0bXGe3U16jO4t/d+9QN1sFdoOJBS3qR5X3eW6mWNd
+ zxuNYwFX5PfBaQipOtTE2cFLKhc1Ms53JSQgk6k71TdixZ+WqsGQJ2kZNO826fnC1zWZ2Ew6vbCTBkP7iDOur/R6Yhe5Y95Af0Mv7X2s
+ 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
+ 1X8w7Q8J9gPavjyifqRty9FP/j3jeu5c9YkX9Rgv4Vij3n1ANrpxO91G25+H9OdDO0mXITtrMtFXNr6+jwx843q0QfC/lZrAjHC9hika
+ DY0IikZqm9CeQyGOKkShhCI6OjdbFfWXqPJ1doFm7VjKdddqnc8OXpIo4sx99eF8V5JgzMDGpnzJQinzW6PbNtOP99vvc7XtD8KpG/0n
+ XC3OmZtLZ7XpTvCDh7SSf0B/aqLsPLCNfGPIL+Wj+nl4Cd0crY9HIRNZuPZD+fZd31Of2Uq3U9t/eAfpcp8mFAiGBvWWHw75qXyangsf
+ WKfnQs/sf9NeQ0r9YR8tAyFtgRnQ2JSv/cjrX5lMdg0R8DKePw0jxH9Wvou/ZOStFe9J73P3lM4D+2pyrYHRvVtJ53t7S5fBGO3bWTa/
+ bQ+Z8YU/YofHLq9Y0LBYvnHnvuIM3kz9R9uQYLtOmPZ0y5byy3t/m1mf9ueUP6jt0KX68xqNgz5RHzo8KBqpbdBxGxUShkIgaTD3CR+C
+ EE0ooGjiYPqVLXEx2zZ/f3bwkqRhndeaDxiaVr6c70qSTL6Av1APU6nzW7sedNCvc47fvXt3wcvugO8WWGGRcWVp42fyrUv/T5zL+0h3
+ 9Kreu6V0und76XLPjhrcqH3ftINc9/bNWiGrRae9xXCIvz1znjgDN1bb12TiXm0M7tUE3f+5tWx+bV8Z+cEoBEJLXDeD+bN4PvjDGgzh
+ 2eOstElbE50eG6rYdI28/gVXMVFfWK4B0qQGr85vH0LOHXmZOGerDwzeQbrevbl0vau39LjtS+Lco35021ZyxnN/D7YUuWT85eLcoO3G
+ /VtIp7t7Sdc7d9btNakYvLVscsO2MvzDUehPfdVtkOfX+j2yGBjxPtTm5YKgaISUCzOhMBPvQrNEoh2+UFNCzg5ekjSs81rz4Rse57sS
+ kicQ8lYgEKr31vsvlgu5c/pQ6fTXbWWLu3aUbvdsLl3u3lZ6DOonXe7sJ87d28h3HvyxrMqup5MX506RTa7ZXZz7ttLPtpQu2OfOvtJp
+ sPrPzRvLEY//Seq8ujnqdzMaXHdKWtMXDcAWqz++oRX6l4PiEVIR4HGVbsY9IwO5/s+T1I639j/z36zrzVL79qdNvLdsrvQ9Yy/pdnVv
+ 6Xa3Bkp3bKe+oUnDENXdO8iX7/iRfNz4qbz+2cvS898aPN2kfnO3Ju53bantUU/peq8GQ9duLyfef7LmDY2S9tJztO0ap367XNuiq4PO
+ MgR3hJQTcxQibkJhJhM5MRp8IrBZdvCSDifvvNZ8cL4rIVksgRCelLEdPtNK/ma10w9Ufs/RisY18v2L9pfOF/eS7vf00UBoe+l+57aa
+ JGyjicMOstHA3eXhD0dJg9TJT2/9qTiXbi2d79Ek/K6tpevdW8hG9+q2d/WWXS/fS174dDISFzz4bxymVrmuvKbNxwVanov0VJ38whFS
+ Rai9+wkFOO2Bc8X5+6bS7Y6dpbP6UWcNipx7kHz3ka5X9JNrXh0kh99xhLY/3WXTm76s2+3ij+x1Hry5OLdtLdtd/XWZ/umL2lSlEUZp
+ e+b70iL1XX+qh/r0hcFpCSknhaaW26YEmtOcmk0nhL2yg5ckhbzzWvPB+a6ExEft1H8CBxg46U5xTt1Mut6mFfsdO0iXOzSZuHtLtXm1
+ 8Wv6yNGj/ybXTL5OnL92lU1u2EV63LabdLpHP7tXE/O7tFIfsI3846l/axhUr0l7StIp39mQXFytyfkkVZ3+s29wakIqHq3f/0cT9Yv9
+ CEfbGzBp4Yuy2WnaRqjPOHdqgHR7L3Hu2FI6DeopG93UT3a8Yk/pesom0uW6PrLFwF2l2w29xblLE477thXn8m3kuMf/pu1W0I55fuQE
+ HxrreY3jsr+nHgpOT0g5yTe9PN/oRXRqoXX2CDt4SZIodd4457sSEgNplL01GDrdc9Nan2fdYm79p7Lrud8U5z/bSKc71QcGaSWN3tVB
+ W0i3W/vI9tftKVucrkHPxVvKZjfvJptcp/Z/29b+Y/6cW7aTPlfvKa+twjKJAE0nPNdbq35wQ9pL+S/D03PyKU+kalD7nuXbOiIjxU2n
+ 61d7axsOu+kP4vxD/eL2XcS5VZPum7eUzrf1lK639pYuSDSu2EY637KTbH6dBj83IPHAFI3tZbsrvinTPnvZP5b65kf+L4qeZwlCL/93
+ Lz0kOD0h5Sbf+r5QYcdunAcgaH3PDl5SwXC+KyHFgZ3CB0LcVFoz4HTdv0ZdIs5fttREoZ8GQjto5byVdLp1K+lyq/rGjTuL899tNDjq
+ Iz1u6KvB0E7S6TZNMO7RBuCKHeTsMZjRlMHCuwUaAK3Acf1ne3ipz9F8APWHbwdFIKTiQcCiesi39bS7Rv1qvv57wciZo6XTCeo7N/bT
+ JELbjRt7SuebNFG/UduWW9Sv7thRf/aRbtfvJF0H6r/Vv5zLeslpT16IDrBleozb1Ydm6M8pGTdznv58wncgBZ8FpyekLbAlC2anbqyE
+ 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
+ ZlGd9Ti3jm3e0BXbBg3HEx8ua7bdc0uaV87/uWdY0+ePzGze0B2vDUT0GKHMxih6nFBmufIdK59s5Y1z/bb7OWlZWn5wwEF+o3uHNrrR
+ z8zrjt6/cL84xy7lvrf0Ogopjq2YZYlbZnO7cl2TaUe2Y4TfT76yluO6zWOU8l1Gbb9c96WQOuq7yVdGs64zy1OuusI8zg/2/02Ob0K2
+ Y8dRHBsql42UUs8WUjnua0vrRai1vtsevlIuMaEgpLZIVEIBmRVhIdkqdNsxbBWu2aAXapwKNQJmA5KvTGaQHbdhtZW9kIo1zKGKNXzF
+ ZJ4nur95raFaEwBCbXEdcWyl0LWWsl05rsm8t/nsrZjKcd3l8qH2+K7b47uBzHtiOwZk3v9C33G+6zTLbPsO8/liqFLrl6iSWM8WUnvU
+ wYXsrBy+Wy47bQ8xoSCktsibUDyvFUJH6llLxWkTgtTxGqRG973FaOj+VxuE6OcTLRX77VqxR7eJaphROUfPaX6GivtxrbjNY8S9HlO2
+ 6ysk8zz5rs3cLl+5bTKDBNv+5xnBgU3m9xJVe1wHVMxWoLjnKLZdOa6ptdcbqrXXXU4fKsd9KaZi+5ajDKXck0LHMT+Lq3x1hXnvQ5Vy
+ /2xKYj1bSOW+r6aK1YuFvvO4Mo/RFr5SLjGhIKS2yJtQTNYKIUkqFKBefM+wnG1vtjR00c+f0cp2O6OyHa2VbXSbqAptP9TS0NmOZR4j
+ roqVzVTca4u73QQjKMgnc/+4+0G7Bw129Lzlvo58KmYrULnKYn7eNQgGosewbRc9TmuvN1Rrr7vUcpRyrJbcl2Iqtm85ylBK+Uo5TlwV
+ Op+t/jTrzVKVxHq2kMp5X1tSL5Z6P2yKe4xynKu1YkJBSG2RN6GYtEISqfGLmzcKx513Sc42N40xGrpfHZLzuXkMVLajPliWs01UhbZ/
+ +I3mDZ3tWLZyx1GxspmKe23Ftnvus7TsGzMhgPKd5583Fx+pgMz9y3UdxVTMVqBylaUcx2nt9YZq7XWXWo5yHKs1115s33KUoZTylXKc
+ uMp3vny+vPte+8i4hXXNto+rJNazhVSO+9qaerHU+2FT3GOU41ytFRMKQmqLDk8ozIoPPYODnpth3TZUsYas2Odmo1DsnGZjFm2IC30W
+ VXtV8OVqcPIlAuH1teR6fm+ZEhDVRXcPa9q2XNdRTC0JrPPZS7GgpxzXFLcsxdTahKKcPlSO+1JMxfYtRxlKuSeFjtOa67SpUFJvdsaU
+ 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