* Re: Best Practices for PMD Verification before Upstream Requests
From: Remy Horton @ 2016-11-04 5:41 UTC (permalink / raw)
To: Shepard Siegel, Thomas Monjalon; +Cc: dev
In-Reply-To: <CAMMLSKAr+drh0NDimAoZN=9oT2zmnVsthnwhD5tEMY2kE6iMGw@mail.gmail.com>
On 02/11/2016 20:21, Shepard Siegel wrote:
[..]
> Almost a year into our DPDK development, we have shipped an alpha version
> of our "Arkville" product. We've thankful for all the support from this
> Most everyone has suggested "get your code upstream ASAP"; but our
> team is cut from the "if it isn't tested, it doesn't work" cloth. We now
> have some solid miles on our Arkville PMD driver "ark" with 16.07. Mostly
> testpmd and a suite of user apps; dts not so much, only because our use
> case is a little different.
To me that sounds good enough for a v1 patch.
> One question that
> came up is "Should we do a thorough port and regression against 16.11 as a
> precursor to up streaming at 17.02?". Constructive feedback always welcome!
It is helpful, although bear in mind there is only so much you'll be
able to test. Patches sent to the mailing list are picked up by
patchwork for automated testing, so you'll find out quite quickly if
you've broken something.
And avoid top-posting.. :)
..Remy
^ permalink raw reply
* Re: [PATCH v9] app/testpmd: fix DCB configuration
From: Wu, Jingjing @ 2016-11-04 5:40 UTC (permalink / raw)
To: Iremonger, Bernard, dev@dpdk.org, Shah, Rahul R, Lu, Wenzhuo
In-Reply-To: <1478194538-19337-1-git-send-email-bernard.iremonger@intel.com>
> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Friday, November 4, 2016 1:36 AM
> To: dev@dpdk.org; Shah, Rahul R <rahul.r.shah@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> Subject: [PATCH v9] app/testpmd: fix DCB configuration
>
> Data Centre Bridge (DCB) configuration fails when SRIOV is enabled if nb_rxq
> or nb_txq are greater than nb_q_per_pool.
>
> The failure occurs during configuration of the ixgbe PMD when it is started, in
> the ixgbe_check_mq_mode function.
>
> Fixes: 2a977b891f99 ("app/testpmd: fix DCB configuration")
>
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
Thanks
Jingjing
^ permalink raw reply
* Re: HOW to forward vlan pkt using DPDK loadbalancer and L2FD, with intel 82599ES
From: Lu, Wenzhuo @ 2016-11-04 5:19 UTC (permalink / raw)
To: Caianning, users@dpdk.org, dev@dpdk.org
In-Reply-To: <F994AE62EFA2864BAC5A2B81D86C27C13E2D85E9@nkgeml514-mbx.china.huawei.com>
Hi Anning,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Caianning
> Sent: Friday, November 4, 2016 10:51 AM
> To: users@dpdk.org; dev@dpdk.org
> Subject: [dpdk-dev] HOW to forward vlan pkt using DPDK loadbalancer and L2FD,
> with intel 82599ES
>
> HI,
>
> I am using DPDK 16.07 example loadbalancer to as LB to forward vlan pkt
> to applications. LB and applications are using VFs bound with DPDK igb_uio
> driver.
> But I found the packet can not be send from LB to application. Pkt input to LB
> with vlan, after LB processing it is sent out to application using another VF.
>
> As 82599 need vlan filters if we use VF to process vlan pkts, in the LB we called
> rte api to add a vlan filter and enable vlan flilter. And set port_conf with vlan
> strip off.
> And for the application(L2FWD) we use the cmd: ip link set PFxxx VF yy vlan
> VLANID.
>
> In the LB ,we can receive pkts with vlan, after processing(cut the head and add
> another L2 head with same vlan tag, set destination MAC to application VF), it is
> send out to the application VF.
> the result is: LB can still processing ,but all the pkt post.
>
> We also did an experiment using testPMD to forward vlan pkt to application on
> the same VF used by LB, and it is OK.
> We tried kinds of different set of vlan filter, vlan strip, ip link set, but found no
> solution.
>
> Does anyone meet the similar problem? And what factor casued the difference?
>
> Thx.
I saw you mentioned testpmd is fine. Testpmd is a very simple example, normally it forwards packets blindly. It means there's no route rule. It just forwards packets from one port to another.
I guess the difference is the APP you use has some rules for routing/swithing.
^ permalink raw reply
* [PATCH v3 3/3] app/test-pmd: add support for bitrate statistics
From: Remy Horton @ 2016-11-04 3:36 UTC (permalink / raw)
To: dev
In-Reply-To: <1478230579-4689-1-git-send-email-remy.horton@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
---
app/test-pmd/testpmd.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 6185be6..3cf4795 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -78,6 +78,8 @@
#ifdef RTE_LIBRTE_PDUMP
#include <rte_pdump.h>
#endif
+#include <rte_metrics.h>
+#include <rte_bitrate.h>
#include "testpmd.h"
@@ -322,6 +324,9 @@ uint16_t nb_rx_queue_stats_mappings = 0;
unsigned max_socket = 0;
+/* Bitrate statistics */
+struct rte_stats_bitrates_s *bitrate_data;
+
/* Forward function declarations */
static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
static void check_all_ports_link_status(uint32_t port_mask);
@@ -921,12 +926,26 @@ run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
struct fwd_stream **fsm;
streamid_t nb_fs;
streamid_t sm_id;
-
+ uint64_t tics_per_1sec;
+ uint64_t tics_datum;
+ uint64_t tics_current;
+ uint8_t idx_port, cnt_ports;
+
+ cnt_ports = rte_eth_dev_count();
+ tics_datum = rte_rdtsc();
+ tics_per_1sec = rte_get_timer_hz();
fsm = &fwd_streams[fc->stream_idx];
nb_fs = fc->stream_nb;
do {
for (sm_id = 0; sm_id < nb_fs; sm_id++)
(*pkt_fwd)(fsm[sm_id]);
+ tics_current = rte_rdtsc();
+ if (tics_current - tics_datum >= tics_per_1sec) {
+ /* Periodic bitrate calculation */
+ for (idx_port = 0; idx_port < cnt_ports; idx_port++)
+ rte_stats_bitrate_calc(bitrate_data, idx_port);
+ tics_datum = tics_current;
+ }
} while (! fc->stopped);
}
@@ -2128,6 +2147,13 @@ main(int argc, char** argv)
FOREACH_PORT(port_id, ports)
rte_eth_promiscuous_enable(port_id);
+ /* Setup bitrate stats */
+ bitrate_data = rte_stats_bitrate_create();
+ if (bitrate_data == NULL)
+ rte_exit(EXIT_FAILURE, "Could not allocate bitrate data.\n");
+ rte_stats_bitrate_reg(bitrate_data);
+
+
#ifdef RTE_LIBRTE_CMDLINE
if (interactive == 1) {
if (auto_start) {
--
2.5.5
^ permalink raw reply related
* [PATCH v3 1/3] lib: add information metrics library
From: Remy Horton @ 2016-11-04 3:36 UTC (permalink / raw)
To: dev
In-Reply-To: <1478230579-4689-1-git-send-email-remy.horton@intel.com>
This patch adds a new information metric library that allows other
modules to register named metrics and update their values. It is
intended to be independent of ethdev, rather than mixing ethdev
and non-ethdev information in xstats.
Signed-off-by: Remy Horton <remy.horton@intel.com>
---
config/common_base | 5 +
doc/api/doxy-api-index.md | 1 +
doc/api/doxy-api.conf | 1 +
doc/guides/rel_notes/release_16_11.rst | 6 +
lib/Makefile | 1 +
lib/librte_metrics/Makefile | 51 +++++
lib/librte_metrics/rte_metrics.c | 300 +++++++++++++++++++++++++++++
lib/librte_metrics/rte_metrics.h | 204 ++++++++++++++++++++
lib/librte_metrics/rte_metrics_version.map | 13 ++
mk/rte.app.mk | 2 +
10 files changed, 584 insertions(+)
create mode 100644 lib/librte_metrics/Makefile
create mode 100644 lib/librte_metrics/rte_metrics.c
create mode 100644 lib/librte_metrics/rte_metrics.h
create mode 100644 lib/librte_metrics/rte_metrics_version.map
diff --git a/config/common_base b/config/common_base
index 21d18f8..2277727 100644
--- a/config/common_base
+++ b/config/common_base
@@ -589,3 +589,8 @@ CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
CONFIG_RTE_TEST_PMD=y
CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+
+#
+# Compile the device metrics library
+#
+CONFIG_RTE_LIBRTE_METRICS=y
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 6675f96..ca50fa6 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -147,4 +147,5 @@ There are many libraries, so their headers may be grouped by topics:
[common] (@ref rte_common.h),
[ABI compat] (@ref rte_compat.h),
[keepalive] (@ref rte_keepalive.h),
+ [Device Metrics] (@ref rte_metrics.h),
[version] (@ref rte_version.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 9dc7ae5..fe830eb 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -57,6 +57,7 @@ INPUT = doc/api/doxy-api-index.md \
lib/librte_reorder \
lib/librte_ring \
lib/librte_sched \
+ lib/librte_metrics \
lib/librte_table \
lib/librte_timer \
lib/librte_vhost
diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index aa0c09a..507f715 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -131,6 +131,12 @@ New Features
The GCC 4.9 ``-march`` option supports the Intel processor code names.
The config option ``RTE_MACHINE`` can be used to pass code names to the compiler as ``-march`` flag.
+* **Added information metric library.**
+
+ A library that allows information metrics to be added and update. It is
+ intended to provide a reporting mechanism that is independent of the
+ ethdev library.
+
Resolved Issues
---------------
diff --git a/lib/Makefile b/lib/Makefile
index 990f23a..5d85dcf 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -58,6 +58,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TABLE) += librte_table
DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += librte_pipeline
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
+DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics
ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_metrics/Makefile b/lib/librte_metrics/Makefile
new file mode 100644
index 0000000..8d6e23a
--- /dev/null
+++ b/lib/librte_metrics/Makefile
@@ -0,0 +1,51 @@
+# 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_metrics.a
+
+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
+
+EXPORT_MAP := rte_metrics_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_METRICS) := rte_metrics.c
+
+# Install header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_METRICS)-include += rte_metrics.h
+
+DEPDIRS-$(CONFIG_RTE_LIBRTE_METRICS) += lib/librte_eal
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_metrics/rte_metrics.c b/lib/librte_metrics/rte_metrics.c
new file mode 100644
index 0000000..220c2ac
--- /dev/null
+++ b/lib/librte_metrics/rte_metrics.c
@@ -0,0 +1,300 @@
+/*-
+ * 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 <string.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_metrics.h>
+#include <rte_lcore.h>
+#include <rte_memzone.h>
+#include <rte_spinlock.h>
+
+#define RTE_METRICS_MAX_METRICS 256
+#define RTE_METRICS_MEMZONE_NAME "RTE_METRICS"
+
+/**
+ * Internal stats metadata and value entry.
+ *
+ * @internal
+ * @param name
+ * Name of metric
+ * @param value
+ * Current value for metric
+ * @param idx_next_set
+ * Index of next root element (zero for none)
+ * @param idx_next_metric
+ * Index of next metric in set (zero for none)
+ *
+ * Only the root of each set needs idx_next_set but since it has to be
+ * assumed that number of sets could equal total number of metrics,
+ * having a separate set metadata table doesn't save any memory.
+ */
+struct rte_metrics_meta_s {
+ char name[RTE_METRICS_MAX_NAME_LEN];
+ uint64_t value[RTE_MAX_ETHPORTS];
+ uint64_t nonport_value;
+ uint16_t idx_next_set;
+ uint16_t idx_next_stat;
+};
+
+/**
+ * Internal stats info structure.
+ *
+ * @internal
+ * @param idx_last_set
+ * Index of last metadata entry with valid data. This value is
+ * not valid if cnt_stats is zero.
+ * @param cnt_stats
+ * Number of metrics.
+ * @param metadata
+ * Stat data memory block.
+ *
+ * Offsets into metadata are used instead of pointers because ASLR
+ * means that having the same physical addresses in different
+ * processes is not guaranteed.
+ */
+struct rte_metrics_data_s {
+ uint16_t idx_last_set;
+ uint16_t cnt_stats;
+ struct rte_metrics_meta_s metadata[RTE_METRICS_MAX_METRICS];
+ rte_spinlock_t lock;
+};
+
+
+void
+rte_metrics_init(void)
+{
+ struct rte_metrics_data_s *stats;
+ const struct rte_memzone *memzone;
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return;
+
+ memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
+ if (memzone != NULL)
+ return;
+ memzone = rte_memzone_reserve(RTE_METRICS_MEMZONE_NAME,
+ sizeof(struct rte_metrics_data_s), rte_socket_id(), 0);
+ if (memzone == NULL)
+ rte_exit(EXIT_FAILURE, "Unable to allocate stats memzone\n");
+ stats = memzone->addr;
+ memset(stats, 0, sizeof(struct rte_metrics_data_s));
+ rte_spinlock_init(&stats->lock);
+}
+
+
+int
+rte_metrics_reg_metric(const char *name)
+{
+ const char *list_names[] = {name};
+
+ return rte_metrics_reg_metrics(list_names, 1);
+}
+
+
+int
+rte_metrics_reg_metrics(const char **names, uint16_t cnt_names)
+{
+ struct rte_metrics_meta_s *entry;
+ struct rte_metrics_data_s *stats;
+ const struct rte_memzone *memzone;
+ uint16_t idx_name;
+ uint16_t idx_base;
+
+ /* Some sanity checks */
+ if (cnt_names < 1 || names == NULL)
+ return -EINVAL;
+
+ rte_metrics_init();
+ memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
+ if (memzone == NULL)
+ return -EIO;
+ stats = memzone->addr;
+
+ if (stats->cnt_stats + cnt_names >= RTE_METRICS_MAX_METRICS)
+ return -ENOMEM;
+
+ rte_spinlock_lock(&stats->lock);
+
+ /* Overwritten later if this is actually first set.. */
+ stats->metadata[stats->idx_last_set].idx_next_set = stats->cnt_stats;
+
+ stats->idx_last_set = idx_base = stats->cnt_stats;
+
+ for (idx_name = 0; idx_name < cnt_names; idx_name++) {
+ entry = &stats->metadata[idx_name + stats->cnt_stats];
+ strncpy(entry->name, names[idx_name],
+ RTE_METRICS_MAX_NAME_LEN);
+ memset(entry->value, 0, sizeof(entry->value));
+ entry->idx_next_stat = idx_name + stats->cnt_stats + 1;
+ }
+ entry->idx_next_stat = 0;
+ entry->idx_next_set = 0;
+ stats->cnt_stats += cnt_names;
+
+ rte_spinlock_unlock(&stats->lock);
+
+ return idx_base;
+}
+
+
+int
+rte_metrics_update_metric(int port_id, uint16_t key, const uint64_t value)
+{
+ return rte_metrics_update_metrics(port_id, key, &value, 1);
+}
+
+
+int
+rte_metrics_update_metrics(int port_id,
+ uint16_t key,
+ const uint64_t *values,
+ uint32_t count)
+{
+ struct rte_metrics_meta_s *entry;
+ struct rte_metrics_data_s *stats;
+ const struct rte_memzone *memzone;
+ uint16_t idx_metric;
+ uint16_t idx_value;
+ uint16_t cnt_setsize;
+
+ if (port_id != RTE_METRICS_NONPORT &&
+ (port_id < 0 || port_id > RTE_MAX_ETHPORTS))
+ return -EINVAL;
+
+ rte_metrics_init();
+ memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
+ if (memzone == NULL)
+ return -EIO;
+ stats = memzone->addr;
+
+ rte_spinlock_lock(&stats->lock);
+ idx_metric = key;
+ cnt_setsize = 1;
+ while (idx_metric < stats->cnt_stats) {
+ entry = &stats->metadata[idx_metric];
+ if (entry->idx_next_stat == 0)
+ break;
+ cnt_setsize++;
+ idx_metric++;
+ }
+ /* Check update does not cross set border */
+ if (count > cnt_setsize) {
+ rte_spinlock_unlock(&stats->lock);
+ return -ERANGE;
+ }
+
+ if (port_id == RTE_METRICS_NONPORT)
+ for (idx_value = 0; idx_value < count; idx_value++) {
+ idx_metric = key + idx_value;
+ stats->metadata[idx_metric].nonport_value =
+ values[idx_value];
+ }
+ else
+ for (idx_value = 0; idx_value < count; idx_value++) {
+ idx_metric = key + idx_value;
+ stats->metadata[idx_metric].value[port_id] =
+ values[idx_value];
+ }
+ rte_spinlock_unlock(&stats->lock);
+ return 0;
+}
+
+
+int
+rte_metrics_get_names(struct rte_metric_name *names,
+ uint16_t capacity)
+{
+ struct rte_metrics_data_s *stats;
+ const struct rte_memzone *memzone;
+ uint16_t idx_name;
+ int return_value;
+
+ memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
+ /* If not allocated, fail silently */
+ if (memzone == NULL)
+ return 0;
+
+ stats = memzone->addr;
+ rte_spinlock_lock(&stats->lock);
+ if (names != NULL) {
+ if (capacity < stats->cnt_stats) {
+ rte_spinlock_unlock(&stats->lock);
+ return -ERANGE;
+ }
+ for (idx_name = 0; idx_name < stats->cnt_stats; idx_name++)
+ strncpy(names[idx_name].name,
+ stats->metadata[idx_name].name,
+ RTE_METRICS_MAX_NAME_LEN);
+ }
+ return_value = stats->cnt_stats;
+ rte_spinlock_unlock(&stats->lock);
+ return return_value;
+}
+
+
+int
+rte_metrics_get_values(int port_id,
+ struct rte_stat_value *values,
+ uint16_t capacity)
+{
+ struct rte_metrics_meta_s *entry;
+ struct rte_metrics_data_s *stats;
+ const struct rte_memzone *memzone;
+ uint16_t idx_name;
+ int return_value;
+
+ memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
+ /* If not allocated, fail silently */
+ if (memzone == NULL)
+ return 0;
+ stats = memzone->addr;
+ rte_spinlock_lock(&stats->lock);
+
+ if (values != NULL) {
+ if (capacity < stats->cnt_stats) {
+ rte_spinlock_unlock(&stats->lock);
+ return -ERANGE;
+ }
+ for (idx_name = 0; idx_name < stats->cnt_stats; idx_name++) {
+ entry = &stats->metadata[idx_name];
+ values[idx_name].key = idx_name;
+ values[idx_name].value = entry->value[port_id];
+ }
+ }
+ return_value = stats->cnt_stats;
+ rte_spinlock_unlock(&stats->lock);
+ return return_value;
+}
diff --git a/lib/librte_metrics/rte_metrics.h b/lib/librte_metrics/rte_metrics.h
new file mode 100644
index 0000000..6b75404
--- /dev/null
+++ b/lib/librte_metrics/rte_metrics.h
@@ -0,0 +1,204 @@
+/*-
+ * 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.
+ */
+
+/**
+ * @file
+ *
+ * RTE Statistics module
+ *
+ * Statistic information is populated using callbacks, each of which
+ * is associated with one or more metric names. When queried, the
+ * callback is used to update all metric in the set at once. Currently
+ * only bulk querying of all metric is supported.
+ *
+ */
+
+#ifndef _RTE_METRICS_H_
+#define _RTE_METRICS_H_
+
+/** Maximum length of statistic name (including null-terminator) */
+#define RTE_METRICS_MAX_NAME_LEN 64
+
+/** Used to indicate port-independent information */
+#define RTE_METRICS_NONPORT -1
+
+
+/**
+ * Statistic name
+ */
+struct rte_metric_name {
+ /** String describing statistic */
+ char name[RTE_METRICS_MAX_NAME_LEN];
+};
+
+
+/**
+ * Statistic name.
+ */
+struct rte_stat_value {
+ /** Numeric identifier of statistic */
+ uint16_t key;
+ /** Value for statistic */
+ uint64_t value;
+};
+
+
+/**
+ * Initialises statistic module. This only has to be explicitly called if you
+ * intend to use rte_metrics_reg_metric() or rte_metrics_reg_metrics() from a
+ * secondary process.
+ */
+void rte_metrics_init(void);
+
+
+/**
+ * Register a statistic and its associated callback.
+ *
+ * @param name
+ * Statistic name
+ *
+ * @param callback
+ * Callback to use when fetching statistic
+ *
+ * @param data
+ * Data pointer to pass to callback
+ *
+ * @return
+ * - Zero or positive: Success
+ * - Negative: Failure
+ */
+int rte_metrics_reg_metric(const char *name);
+
+/**
+ * Register a set of statistic and their associated callback.
+ *
+ * @param names
+ * List of statistic names
+ *
+ * @param cnt_names
+ * Number of statistics in set
+ *
+ * @param callback
+ * Callback to use when fetching statsitics
+ *
+ * @param data
+ * Data pointer to pass to callback
+ *
+ * @return
+ * - Zero or positive: Success
+ * - Negative: Failure
+ */
+int rte_metrics_reg_metrics(const char **names, uint16_t cnt_names);
+
+/**
+ * Get statistic name-key lookup table.
+ *
+ * @param names
+ * Array of names to receive key names
+ *
+ * @param capacity
+ * Space available in names
+ *
+ * @return
+ * - Non-negative: Success (number of names)
+ * - Negative: Failure
+ */
+int rte_metrics_get_names(
+ struct rte_metric_name *names,
+ uint16_t capacity);
+
+/**
+ * Fetch statistics.
+ *
+ * @param port_id
+ * Port id to query
+ *
+ * @param values
+ * Array to receive values and their keys
+ *
+ * @param capacity
+ * Space available in values
+ *
+ * @return
+ * - Non-negative: Success (number of names)
+ * - Negative: Failure
+ */
+int rte_metrics_get_values(
+ int port_id,
+ struct rte_stat_value *values,
+ uint16_t capacity);
+
+/**
+ * Updates a statistic metric
+ *
+ * @param port_id
+ * Port to update statistics for
+ * @param key
+ * Id of statistic metric to update
+ * @param value
+ * New value
+ *
+ * @return
+ * - -EIO if unable to access shared statistics memory
+ * - Zero on success
+ */
+int rte_metrics_update_metric(
+ int port_id,
+ uint16_t key,
+ const uint64_t value);
+
+/**
+ * Updates a statistic metric set. Note that it is an error to try to
+ * update across a set boundary.
+ *
+ * @param port_id
+ * Port to update statistics for
+ * @param key
+ * Base id of statistics set to update
+ * @param values
+ * Set of new values
+ * @param count
+ * Number of new values
+ *
+ * @return
+ * - -ERANGE if count exceeds statistic set size
+ * - -EIO if upable to access shared statistics memory
+ * - Zero on success
+ */
+int rte_metrics_update_metrics(
+ int port_id,
+ uint16_t key,
+ const uint64_t *values,
+ uint32_t count);
+
+#endif
diff --git a/lib/librte_metrics/rte_metrics_version.map b/lib/librte_metrics/rte_metrics_version.map
new file mode 100644
index 0000000..a31a80a
--- /dev/null
+++ b/lib/librte_metrics/rte_metrics_version.map
@@ -0,0 +1,13 @@
+DPDK_16.11 {
+ global:
+
+ rte_metrics_get_names;
+ rte_metrics_get_values;
+ rte_metrics_init;
+ rte_metrics_reg_metric;
+ rte_metrics_reg_metrics;
+ rte_metrics_update_metric;
+ rte_metrics_update_metrics;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 51bc3b0..2db5427 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -98,6 +98,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring
_LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal
_LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline
_LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
+_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics
+
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt -lxenstore
--
2.5.5
^ permalink raw reply related
* [PATCH v3 2/3] lib: add bitrate statistics library
From: Remy Horton @ 2016-11-04 3:36 UTC (permalink / raw)
To: dev
In-Reply-To: <1478230579-4689-1-git-send-email-remy.horton@intel.com>
This patch adds a library that calculates peak and average data-rate
statistics. For ethernet devices. These statistics are reported using
the metrics library.
Signed-off-by: Remy Horton <remy.horton@intel.com>
---
config/common_base | 5 +
doc/api/doxy-api-index.md | 1 +
doc/api/doxy-api.conf | 1 +
doc/guides/rel_notes/release_16_11.rst | 5 +
lib/Makefile | 1 +
lib/librte_bitratestats/Makefile | 53 +++++++++
lib/librte_bitratestats/rte_bitrate.c | 128 +++++++++++++++++++++
lib/librte_bitratestats/rte_bitrate.h | 80 +++++++++++++
.../rte_bitratestats_version.map | 9 ++
mk/rte.app.mk | 1 +
10 files changed, 284 insertions(+)
create mode 100644 lib/librte_bitratestats/Makefile
create mode 100644 lib/librte_bitratestats/rte_bitrate.c
create mode 100644 lib/librte_bitratestats/rte_bitrate.h
create mode 100644 lib/librte_bitratestats/rte_bitratestats_version.map
diff --git a/config/common_base b/config/common_base
index 2277727..25c3911 100644
--- a/config/common_base
+++ b/config/common_base
@@ -594,3 +594,8 @@ CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
# Compile the device metrics library
#
CONFIG_RTE_LIBRTE_METRICS=y
+
+#
+# Compile the bitrate statistics library
+#
+CONFIG_RTE_LIBRTE_BITRATE=y
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index ca50fa6..91e8ea6 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -148,4 +148,5 @@ There are many libraries, so their headers may be grouped by topics:
[ABI compat] (@ref rte_compat.h),
[keepalive] (@ref rte_keepalive.h),
[Device Metrics] (@ref rte_metrics.h),
+ [Bitrate Statistics] (@ref rte_bitrate.h),
[version] (@ref rte_version.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index fe830eb..8765ddd 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -58,6 +58,7 @@ INPUT = doc/api/doxy-api-index.md \
lib/librte_ring \
lib/librte_sched \
lib/librte_metrics \
+ lib/librte_bitratestats \
lib/librte_table \
lib/librte_timer \
lib/librte_vhost
diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index 507f715..b690b72 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -137,6 +137,11 @@ New Features
intended to provide a reporting mechanism that is independent of the
ethdev library.
+* **Added bit-rate calculation library.**
+
+ A library that can be used to calculate device bit-rates. Calculated
+ bitrates are reported using the metrics library.
+
Resolved Issues
---------------
diff --git a/lib/Makefile b/lib/Makefile
index 5d85dcf..e211bc0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -59,6 +59,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += librte_pipeline
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics
+DIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += librte_bitratestats
ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_bitratestats/Makefile b/lib/librte_bitratestats/Makefile
new file mode 100644
index 0000000..b725d4e
--- /dev/null
+++ b/lib/librte_bitratestats/Makefile
@@ -0,0 +1,53 @@
+# 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_bitratestats.a
+
+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
+
+EXPORT_MAP := rte_bitratestats_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_BITRATE) := rte_bitrate.c
+
+# Install header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_BITRATE)-include += rte_bitrate.h
+
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += lib/librte_metrics
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_bitratestats/rte_bitrate.c b/lib/librte_bitratestats/rte_bitrate.c
new file mode 100644
index 0000000..d97a526
--- /dev/null
+++ b/lib/librte_bitratestats/rte_bitrate.c
@@ -0,0 +1,128 @@
+/*-
+ * 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_common.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_metrics.h>
+#include <rte_bitrate.h>
+
+/*
+ * Persistent bit-rate data.
+ * @internal
+ */
+struct rte_stats_bitrate_s {
+ uint64_t last_ibytes;
+ uint64_t last_obytes;
+ uint64_t peak_ibits;
+ uint64_t peak_obits;
+ uint64_t ewma_ibits;
+ uint64_t ewma_obits;
+};
+
+struct rte_stats_bitrates_s {
+ struct rte_stats_bitrate_s port_stats[RTE_MAX_ETHPORTS];
+ uint16_t id_stats_set;
+};
+
+
+struct rte_stats_bitrates_s *
+rte_stats_bitrate_create(void)
+{
+ return rte_zmalloc(NULL, sizeof(struct rte_stats_bitrates_s), 0);
+}
+
+
+int
+rte_stats_bitrate_reg(struct rte_stats_bitrates_s *bitrate_data)
+{
+ const char *names[] = {
+ "mean_bits_in", "mean_bits_out",
+ "peak_bits_in", "peak_bits_out",
+ };
+ int return_value;
+
+ return_value = rte_metrics_reg_metrics(&names[0], 4);
+ if (return_value >= 0)
+ bitrate_data->id_stats_set = return_value;
+ return return_value;
+}
+
+
+int
+rte_stats_bitrate_calc(struct rte_stats_bitrates_s *bitrate_data,
+ uint8_t port_id)
+{
+ struct rte_stats_bitrate_s *port_data;
+ struct rte_eth_stats eth_stats;
+ int ret_code;
+ uint64_t cnt_bits;
+ int64_t delta;
+ const int64_t alpha_percent = 20;
+ uint64_t values[4];
+
+ ret_code = rte_eth_stats_get(port_id, ð_stats);
+ if (ret_code != 0)
+ return ret_code;
+
+ port_data = &bitrate_data->port_stats[port_id];
+
+ /* Incoming */
+ cnt_bits = (eth_stats.ibytes - port_data->last_ibytes) << 3;
+ port_data->last_ibytes = eth_stats.ibytes;
+ if (cnt_bits > port_data->peak_ibits)
+ port_data->peak_ibits = cnt_bits;
+ delta = cnt_bits;
+ delta -= port_data->ewma_ibits;
+ /* The +50 fixes integer rounding during divison */
+ delta = (delta * alpha_percent + 50) / 100;
+ port_data->ewma_ibits += delta;
+
+ /* Outgoing */
+ cnt_bits = (eth_stats.obytes - port_data->last_obytes) << 3;
+ port_data->last_obytes = eth_stats.obytes;
+ if (cnt_bits > port_data->peak_obits)
+ port_data->peak_obits = cnt_bits;
+ delta = cnt_bits;
+ delta -= port_data->ewma_obits;
+ delta = (delta * alpha_percent + 50) / 100;
+ port_data->ewma_obits += delta;
+
+ values[0] = port_data->ewma_ibits;
+ values[1] = port_data->ewma_obits;
+ values[2] = port_data->peak_ibits;
+ values[3] = port_data->peak_obits;
+ rte_metrics_update_metrics(port_id, bitrate_data->id_stats_set,
+ values, 4);
+ return 0;
+}
diff --git a/lib/librte_bitratestats/rte_bitrate.h b/lib/librte_bitratestats/rte_bitrate.h
new file mode 100644
index 0000000..cd566d6
--- /dev/null
+++ b/lib/librte_bitratestats/rte_bitrate.h
@@ -0,0 +1,80 @@
+/*-
+ * 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.
+ */
+
+
+
+/**
+ * Bitrate statistics data structure
+ */
+struct rte_stats_bitrates_s;
+
+
+/**
+ * Allocate a bitrate statistics structure
+ *
+ * @return
+ * - Pointer to structure on success
+ * - NULL on error (zmalloc failure)
+ */
+struct rte_stats_bitrates_s *rte_stats_bitrate_create(void);
+
+
+/**
+ * Register bitrate statistics
+ *
+ * @param bitrate_data
+ * Pointer allocated by rte_stats_create()
+ *
+ * @return
+ * Zero on success
+ * Negative on error
+ */
+int rte_stats_bitrate_reg(struct rte_stats_bitrates_s *bitrate_data);
+
+
+/**
+ * Calculate statistics for current time window. The period this function
+ * is called should be the intended time window width.
+ *
+ * @param bitrate_data
+ * Bitrate statistics data pointer
+ *
+ * @param port_id
+ * Port id to calculate statistics for
+ *
+ * @return
+ * - Zero on success
+ * - Negative value on error
+ */
+int rte_stats_bitrate_calc(struct rte_stats_bitrates_s *bitrate_data,
+ uint8_t port_id);
diff --git a/lib/librte_bitratestats/rte_bitratestats_version.map b/lib/librte_bitratestats/rte_bitratestats_version.map
new file mode 100644
index 0000000..9de6be9
--- /dev/null
+++ b/lib/librte_bitratestats/rte_bitratestats_version.map
@@ -0,0 +1,9 @@
+DPDK_16.11 {
+ global:
+
+ rte_stats_bitrate_calc;
+ rte_stats_bitrate_create;
+ rte_stats_bitrate_reg;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 2db5427..5b5e547 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -99,6 +99,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal
_LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline
_LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BITRATE) += -lrte_bitratestats
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
--
2.5.5
^ permalink raw reply related
* [PATCH v3 0/3] Expanded statistics reporting
From: Remy Horton @ 2016-11-04 3:36 UTC (permalink / raw)
To: dev; +Cc: Thomas Monjalon
In-Reply-To: <1477616671-9547-1-git-send-email-remy.horton@intel.com>
This patchset extends statistics reporting to include peak and
average data-rate metrics. It comes in two parts: a statistics
reporting library, and a bitrate calculation library that uses
it. This structure is intended to seperate statistic reporting
from ethdev and allow more flexible metric registration.
--
v3 changes:
* Marked rte_stats_bitrate_s as internal
* Minor integer roundoff correction
* Coding style corrections
* Removed spurious object allocation
* Changes to rte_metrics.[ch] moved from Patch 2/3 to 1/3.
* Reintroduced non-port values (RTE_METRICS_NONPORT)
* Added spinlocks to metric library
* Removed spurious test registration/update
* Added release notes entries
v2 changes:
* Uses a new metrics library rather than being part of ethdev
Remy Horton (3):
lib: add information metrics library
lib: add bitrate statistics library
app/test-pmd: add support for bitrate statistics
app/test-pmd/testpmd.c | 28 +-
config/common_base | 10 +
doc/api/doxy-api-index.md | 2 +
doc/api/doxy-api.conf | 2 +
doc/guides/rel_notes/release_16_11.rst | 11 +
lib/Makefile | 2 +
lib/librte_bitratestats/Makefile | 53 ++++
lib/librte_bitratestats/rte_bitrate.c | 128 +++++++++
lib/librte_bitratestats/rte_bitrate.h | 80 ++++++
.../rte_bitratestats_version.map | 9 +
lib/librte_metrics/Makefile | 51 ++++
lib/librte_metrics/rte_metrics.c | 300 +++++++++++++++++++++
lib/librte_metrics/rte_metrics.h | 204 ++++++++++++++
lib/librte_metrics/rte_metrics_version.map | 13 +
mk/rte.app.mk | 3 +
15 files changed, 895 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_bitratestats/Makefile
create mode 100644 lib/librte_bitratestats/rte_bitrate.c
create mode 100644 lib/librte_bitratestats/rte_bitrate.h
create mode 100644 lib/librte_bitratestats/rte_bitratestats_version.map
create mode 100644 lib/librte_metrics/Makefile
create mode 100644 lib/librte_metrics/rte_metrics.c
create mode 100644 lib/librte_metrics/rte_metrics.h
create mode 100644 lib/librte_metrics/rte_metrics_version.map
--
2.5.5
^ permalink raw reply
* [PATCH] net/bonding: only handle lacp slow packets
From: linhaifeng @ 2016-11-04 3:30 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, declan.doherty
From: Linhaifeng <haifeng.lin@huawei.com>
We should not drop the slow packets which subtype is
not marker or lacp. Because slow packets have other subtype
like OAM,OSSP,user defined and so on.
Signed-off-by: Linhaifeng <haifeng.lin@huawei.com>
---
drivers/net/bonding/rte_eth_bond_pmd.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 09ce7bf..751ff1c 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -122,6 +122,15 @@ bond_ethdev_rx_burst_active_backup(void *queue, struct rte_mbuf **bufs,
bd_rx_q->queue_id, bufs, nb_pkts);
}
+static inline uint8_t
+is_lacp_packets(uint16_t ethertype, uint8_t subtype, uint16_t vlan_tci)
+{
+ const uint16_t ether_type_slow_be = rte_be_to_cpu_16(ETHER_TYPE_SLOW);
+
+ return !vlan_tci && (ethertype == ether_type_slow_be &&
+ (subtype == SLOW_SUBTYPE_MARKER || subtype == SLOW_SUBTYPE_LACP));
+}
+
static uint16_t
bond_ethdev_rx_burst_8023ad(void *queue, struct rte_mbuf **bufs,
uint16_t nb_pkts)
@@ -141,6 +150,7 @@ bond_ethdev_rx_burst_8023ad(void *queue, struct rte_mbuf **bufs,
uint8_t collecting; /* current slave collecting status */
const uint8_t promisc = internals->promiscuous_en;
uint8_t i, j, k;
+ uint8_t subtype;
rte_eth_macaddr_get(internals->port_id, &bond_mac);
/* Copy slave list to protect against slave up/down changes during tx
@@ -166,10 +176,12 @@ bond_ethdev_rx_burst_8023ad(void *queue, struct rte_mbuf **bufs,
rte_prefetch0(rte_pktmbuf_mtod(bufs[j + 3], void *));
hdr = rte_pktmbuf_mtod(bufs[j], struct ether_hdr *);
+ subtype = ((struct slow_protocol_frame *)hdr)->slow_protocol.subtype;
+
/* Remove packet from array if it is slow packet or slave is not
* in collecting state or bondign interface is not in promiscus
* mode and packet address does not match. */
- if (unlikely(hdr->ether_type == ether_type_slow_be ||
+ if (unlikely(is_lacp_packets(hdr->ether_type, subtype, bufs[j]->vlan_tci) ||
!collecting || (!promisc &&
!is_multicast_ether_addr(&hdr->d_addr) &&
!is_same_ether_addr(&bond_mac, &hdr->d_addr)))) {
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] net/bonding: not handle vlan slow packet
From: linhaifeng @ 2016-11-04 3:16 UTC (permalink / raw)
To: Ferruh Yigit, dev, declan.doherty
In-Reply-To: <58188B66.2050108@huawei.com>
Hi,all
please ignore the patch which title is "net/bonding: not handle vlan slow packet",
I will send another one.
在 2016/11/1 20:32, linhaifeng 写道:
> 在 2016/11/1 18:46, Ferruh Yigit 写道:
>> Hi Haifeng,
>>
>> On 10/31/2016 3:52 AM, linhaifeng wrote:
>>> From: Haifeng Lin <haifeng.lin@huawei.com>
>>>
>>> if rx vlan offload is enable we should not handle vlan slow
>>> packets too.
>>>
>>> Signed-off-by: Haifeng Lin <haifeng.lin@huawei.com>
>>> ---
>>> drivers/net/bonding/rte_eth_bond_pmd.c | 3 ++-
>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
>>> index 09ce7bf..ca17898 100644
>>> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
>>> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
>>> @@ -169,7 +169,8 @@ bond_ethdev_rx_burst_8023ad(void *queue, struct rte_mbuf **bufs,
>>> /* Remove packet from array if it is slow packet or slave is not
>>> * in collecting state or bondign interface is not in promiscus
>>> * mode and packet address does not match. */
>>> - if (unlikely(hdr->ether_type == ether_type_slow_be ||
>>> + if (unlikely((hdr->ether_type == ether_type_slow_be &&
>>> + !bufs[j]->vlan_tci) ||
>>> !collecting || (!promisc &&
>>> !is_multicast_ether_addr(&hdr->d_addr) &&
>>> !is_same_ether_addr(&bond_mac, &hdr->d_addr)))) {
>>>
>>
>> There are a few version of this patch, I guess this one is the correct
>> one, can you please confirm?
>> Also this one supersede following one, right?
>> http://dpdk.org/dev/patchwork/patch/16840/
>
> yes,this is
>
>>
>> It helps a lot if you use versioning in the patches [PATCH -vN] and add
>> a description of changes in commit log (after "---") between patch versions.
>>
>
> ok,i think should not send patch so worry:)
>
> I have a question to ask:
> Is there any other packets' type also is 0x8809 except with lacp packets?
> I saw some guests try to use this type to check link status between VM
> but droped by lacp bond recv function.
>
>
>> Thanks,
>> ferruh
>>
>> .
>>
>
^ permalink raw reply
* HOW to forward vlan pkt using DPDK loadbalancer and L2FD, with intel 82599ES
From: Caianning @ 2016-11-04 2:51 UTC (permalink / raw)
To: users@dpdk.org, dev@dpdk.org
HI,
I am using DPDK 16.07 example loadbalancer to as LB to forward vlan pkt to applications. LB and applications are using VFs bound with DPDK igb_uio driver.
But I found the packet can not be send from LB to application. Pkt input to LB with vlan, after LB processing it is sent out to application using another VF.
As 82599 need vlan filters if we use VF to process vlan pkts, in the LB we called rte api to add a vlan filter and enable vlan flilter. And set port_conf with vlan strip off.
And for the application(L2FWD) we use the cmd: ip link set PFxxx VF yy vlan VLANID.
In the LB ,we can receive pkts with vlan, after processing(cut the head and add another L2 head with same vlan tag, set destination MAC to application VF), it is send out to the application VF.
the result is: LB can still processing ,but all the pkt post.
We also did an experiment using testPMD to forward vlan pkt to application on the same VF used by LB, and it is OK.
We tried kinds of different set of vlan filter, vlan strip, ip link set, but found no solution.
Does anyone meet the similar problem? And what factor casued the difference?
Thx.
^ permalink raw reply
* Re: [PATCH 1/8] net/virtio: revert "virtio: fix restart"
From: Yuanhan Liu @ 2016-11-04 2:00 UTC (permalink / raw)
To: Maxime Coquelin; +Cc: dev, stable, Ilya Maximets
In-Reply-To: <915489cd-7e1a-9a0c-ab9d-780f6103501b@redhat.com>
On Thu, Nov 03, 2016 at 09:36:52PM +0100, Maxime Coquelin wrote:
> Hi Yuanhan,
>
> On 11/03/2016 05:09 PM, Yuanhan Liu wrote:
> >This reverts commit 9a0615af7746 ("virtio: fix restart"); conflict is
> >manually addressed.
> >
> >Kyle reported an issue with above commit
> >
> > qemu-kvm: Guest moved used index from 5 to 1
> >
> >with following steps,
> >
> > 1) Start my virtio interfaces
> > 2) Send some traffic into/out of the interfaces
> > 3) Stop the interfaces
> > 4) Start the interfaces
> > 5) Send some more traffic
> >
> >And here are some quotes from Kyle's analysis,
> >
> > Prior to the patch, if an interface were stopped then started, without
> > restarting the application, the queues would be left as-is, because
> > hw->started would be set to 1. Now, calling stop sets hw->started to 0,
> > which means the next call to start will "touch the queues". This is the
> > unintended side-effect that causes the problem.
>
> Maybe a good idea to explain what is the problem the revert aims to fix.
It aims to fix the issue, by "not touching the queues" on restart.
> It does not seem to be clearly stated in the commit message.
I was thinking the quote from Kyle is enough. How about following supplement:
We should not touch the queues once the init is done, otherwise, the
vring state of virtio PMD driver and vhost-user would be inconsistent,
leading some issue like above.
Thus this patch is reverted.
Better now?
--yliu
^ permalink raw reply
* Re: [PATCH 3/8] net/virtio: simplify queue allocation
From: Yuanhan Liu @ 2016-11-04 1:51 UTC (permalink / raw)
To: Maxime Coquelin; +Cc: dev, Ilya Maximets
In-Reply-To: <3dcee423-4cad-3de2-2593-51415d8e8d7d@redhat.com>
On Thu, Nov 03, 2016 at 09:48:03PM +0100, Maxime Coquelin wrote:
>
>
> On 11/03/2016 05:09 PM, Yuanhan Liu wrote:
> >Let rxq/txq/cq be the union field of the virtqueue struct. This would
> >simplifies the vq allocation a bit: we don't need calculate the vq_size
> >any more based on the queue time.
> s/time/type/ ?
Oops... will fix it.
Thanks.
--yliu
> >
> >Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
> >---
> > drivers/net/virtio/virtio_ethdev.c | 18 +++++++-----------
> > drivers/net/virtio/virtqueue.h | 7 +++++++
> > 2 files changed, 14 insertions(+), 11 deletions(-)
>
> Other than that:
> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>
> Thanks,
> Maxime
^ permalink raw reply
* Re: [PATCH 4/8] net/virtio: allocate queue at init stage
From: Yuanhan Liu @ 2016-11-04 1:50 UTC (permalink / raw)
To: Maxime Coquelin; +Cc: dev, Ilya Maximets
In-Reply-To: <3106a280-db21-604d-7f3f-dd2575efa1e8@redhat.com>
On Thu, Nov 03, 2016 at 10:11:43PM +0100, Maxime Coquelin wrote:
>
>
> On 11/03/2016 05:09 PM, Yuanhan Liu wrote:
> >Queue allocation should be done once, since the queue related info (such
> >as vring addreess) will only be informed to the vhost-user backend once
> >without virtio device reset.
> >
> >That means, if you allocate queues again after the vhost-user negotiation,
> >the vhost-user backend will not be informed any more. Leading to a state
> >that the vring info mismatches between virtio PMD driver and vhost-backend:
> >the driver switches to the new address has just been allocated, while the
> >vhost-backend still sticks to the old address has been assigned in the init
> >stage.
> >
> >Unfortunately, that is exactly how the virtio driver is coded so far: queue
> >allocation is done at queue_setup stage (when rte_eth_tx/rx_queue_setup is
> >invoked). This is wrong, because queue_setup can be invoked several times.
> >For example,
> >
> > $ start_testpmd.sh ... --txq=1 --rxq=1 ...
> > > port stop 0
> > > port config all txq 1 # just trigger the queue_setup callback again
> > > port config all rxq 1
> > > port start 0
> >
> >The right way to do is allocate the queues in the init stage, so that the
> >vring info could be persistent with the vhost-user backend.
> >
> >Besides that, we should allocate max_queue pairs the device supports, but
> >not nr queue pairs firstly configured, to make following case work.
> I understand, but how much memory overhead does that represent?
We are allocating max queue pairs the device supports, but not the
virtio-net spec supports, which, as you stated, would be too much.
I don't know the typical value of the queue pairs being used in
production, but normally, I would assume it be small, something
like 2, or 4. It's 1 by default after all.
So I think it will not be an issue.
> Have you considered performing a device reset when queue number is
> changed?
Not a good idea and clean solution to me.
--yliu
^ permalink raw reply
* [PATCH] examples/l3fwd-power: fix inappropiate Rx queue count method
From: Pablo de Lara @ 2016-11-04 0:04 UTC (permalink / raw)
To: dev; +Cc: Pablo de Lara
Since commit b4f3c136a179 ("net/ixgbe: support checksum flags in SSE vector Rx"),
when HW IP Checksum is enabled, the RX vector function is available to use.
In case of L3fwd-power, since it is enabled, the RX vector function
was not used, but after this commit, it is. This has affected the way
to calculate how full an RX queue is, using rte_eth_rx_descriptor done
function, making the frequency to be at maximum, even when the frequency
is very low.
This commit reverts the way to know how full a queue is to the
previous way, using rte_eth_rx_queue_count(), making it work for both
vector and scalar RX functions.
Fixes: b451aa39db31 ("examples/l3fwd-power: use DD bit rather than RX queue count")
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
examples/l3fwd-power/main.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index b65d683..74369bb 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -370,7 +370,7 @@ static struct rte_timer power_timers[RTE_MAX_LCORE];
static inline uint32_t power_idle_heuristic(uint32_t zero_rx_packet_count);
static inline enum freq_scale_hint_t power_freq_scaleup_heuristic( \
- unsigned lcore_id, uint8_t port_id, uint16_t queue_id);
+ unsigned lcore_id, uint32_t rx_queue_count);
/* exit signal handler */
static void
@@ -705,9 +705,7 @@ power_idle_heuristic(uint32_t zero_rx_packet_count)
}
static inline enum freq_scale_hint_t
-power_freq_scaleup_heuristic(unsigned lcore_id,
- uint8_t port_id,
- uint16_t queue_id)
+power_freq_scaleup_heuristic(unsigned lcore_id, uint32_t rx_queue_count)
{
/**
* HW Rx queue size is 128 by default, Rx burst read at maximum 32 entries
@@ -720,15 +718,12 @@ power_freq_scaleup_heuristic(unsigned lcore_id,
#define FREQ_UP_TREND2_ACC 100
#define FREQ_UP_THRESHOLD 10000
- if (likely(rte_eth_rx_descriptor_done(port_id, queue_id,
- FREQ_GEAR3_RX_PACKET_THRESHOLD) > 0)) {
+ if (likely(rx_queue_count > FREQ_GEAR3_RX_PACKET_THRESHOLD)) {
stats[lcore_id].trend = 0;
return FREQ_HIGHEST;
- } else if (likely(rte_eth_rx_descriptor_done(port_id, queue_id,
- FREQ_GEAR2_RX_PACKET_THRESHOLD) > 0))
+ } else if (likely(rx_queue_count > FREQ_GEAR2_RX_PACKET_THRESHOLD))
stats[lcore_id].trend += FREQ_UP_TREND2_ACC;
- else if (likely(rte_eth_rx_descriptor_done(port_id, queue_id,
- FREQ_GEAR1_RX_PACKET_THRESHOLD) > 0))
+ else if (likely(rx_queue_count > FREQ_GEAR1_RX_PACKET_THRESHOLD))
stats[lcore_id].trend += FREQ_UP_TREND1_ACC;
if (likely(stats[lcore_id].trend > FREQ_UP_THRESHOLD)) {
@@ -833,6 +828,7 @@ main_loop(__attribute__((unused)) void *dummy)
enum freq_scale_hint_t lcore_scaleup_hint;
uint32_t lcore_rx_idle_count = 0;
uint32_t lcore_idle_hint = 0;
+ uint32_t rx_ring_length;
int intr_en = 0;
const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
@@ -923,6 +919,18 @@ start_rx:
rx_queue->zero_rx_packet_count = 0;
/**
+ * get available descriptor number via
+ * MMIO read is costly, so only do it when
+ * recent poll returns maximum number.
+ */
+ if (nb_rx >= MAX_PKT_BURST)
+ rx_ring_length =
+ rte_eth_rx_queue_count(portid,
+ queueid);
+ else
+ rx_ring_length = 0;
+
+ /**
* do not scale up frequency immediately as
* user to kernel space communication is costly
* which might impact packet I/O for received
@@ -930,7 +938,7 @@ start_rx:
*/
rx_queue->freq_up_hint =
power_freq_scaleup_heuristic(lcore_id,
- portid, queueid);
+ rx_ring_length);
}
/* Prefetch first packets */
--
2.5.5
^ permalink raw reply related
* Re: [PATCH] crypto: clarify how crypto operations affect buffers
From: De Lara Guarch, Pablo @ 2016-11-03 21:59 UTC (permalink / raw)
To: Trahe, Fiona, dev@dpdk.org
In-Reply-To: <1478109226-10982-1-git-send-email-fiona.trahe@intel.com>
> -----Original Message-----
> From: Trahe, Fiona
> Sent: Wednesday, November 02, 2016 5:54 PM
> To: dev@dpdk.org
> Cc: De Lara Guarch, Pablo; Trahe, Fiona; Griffin, John
> Subject: [PATCH] crypto: clarify how crypto operations affect buffers
>
> Updated comments on API to clarify which parts of mbufs are
> copied or changed by crypto operations.
>
> Signed-off-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
^ permalink raw reply
* Re: [PATCH 4/8] net/virtio: allocate queue at init stage
From: Maxime Coquelin @ 2016-11-03 21:11 UTC (permalink / raw)
To: Yuanhan Liu, dev; +Cc: Ilya Maximets
In-Reply-To: <1478189400-14606-5-git-send-email-yuanhan.liu@linux.intel.com>
On 11/03/2016 05:09 PM, Yuanhan Liu wrote:
> Queue allocation should be done once, since the queue related info (such
> as vring addreess) will only be informed to the vhost-user backend once
> without virtio device reset.
>
> That means, if you allocate queues again after the vhost-user negotiation,
> the vhost-user backend will not be informed any more. Leading to a state
> that the vring info mismatches between virtio PMD driver and vhost-backend:
> the driver switches to the new address has just been allocated, while the
> vhost-backend still sticks to the old address has been assigned in the init
> stage.
>
> Unfortunately, that is exactly how the virtio driver is coded so far: queue
> allocation is done at queue_setup stage (when rte_eth_tx/rx_queue_setup is
> invoked). This is wrong, because queue_setup can be invoked several times.
> For example,
>
> $ start_testpmd.sh ... --txq=1 --rxq=1 ...
> > port stop 0
> > port config all txq 1 # just trigger the queue_setup callback again
> > port config all rxq 1
> > port start 0
>
> The right way to do is allocate the queues in the init stage, so that the
> vring info could be persistent with the vhost-user backend.
>
> Besides that, we should allocate max_queue pairs the device supports, but
> not nr queue pairs firstly configured, to make following case work.
I understand, but how much memory overhead does that represent?
Have you considered performing a device reset when queue number is
changed?
>
> $ start_testpmd.sh ... --txq=1 --rxq=1 ...
> > port stop 0
> > port config all txq 2
> > port config all rxq 2
> > port start 0
>
> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
> ---
> drivers/net/virtio/virtio_ethdev.c | 105 +++++++++++++++++++++++--------------
> drivers/net/virtio/virtio_ethdev.h | 8 ---
> drivers/net/virtio/virtio_pci.h | 2 +
> drivers/net/virtio/virtio_rxtx.c | 38 +++++++-------
> 4 files changed, 85 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 5a2c14b..253bcb5 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -295,13 +295,19 @@ virtio_dev_queue_release(struct virtqueue *vq)
> }
> }
>
> -int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> - int queue_type,
> - uint16_t queue_idx,
> - uint16_t vtpci_queue_idx,
> - uint16_t nb_desc,
> - unsigned int socket_id,
> - void **pvq)
> +static int
> +virtio_get_queue_type(struct virtio_hw *hw, uint16_t vtpci_queue_idx)
> +{
> + if (vtpci_queue_idx == hw->max_queue_pairs * 2)
> + return VTNET_CQ;
> + else if (vtpci_queue_idx % 2 == 0)
> + return VTNET_RQ;
> + else
> + return VTNET_TQ;
> +}
> +
> +static int
> +virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
> {
> char vq_name[VIRTQUEUE_MAX_NAME_SZ];
> char vq_hdr_name[VIRTQUEUE_MAX_NAME_SZ];
> @@ -314,6 +320,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> struct virtqueue *vq;
> size_t sz_hdr_mz = 0;
> void *sw_ring = NULL;
> + int queue_type = virtio_get_queue_type(hw, vtpci_queue_idx);
> int ret;
>
> PMD_INIT_LOG(DEBUG, "setting up queue: %u", vtpci_queue_idx);
> @@ -351,18 +358,18 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> sz_hdr_mz = PAGE_SIZE;
> }
>
> - vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE, socket_id);
> + vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE,
> + SOCKET_ID_ANY);
> if (vq == NULL) {
> PMD_INIT_LOG(ERR, "can not allocate vq");
> return -ENOMEM;
> }
> + hw->vqs[vtpci_queue_idx] = vq;
> +
> vq->hw = hw;
> vq->vq_queue_index = vtpci_queue_idx;
> vq->vq_nentries = vq_size;
> -
> - if (nb_desc == 0 || nb_desc > vq_size)
> - nb_desc = vq_size;
> - vq->vq_free_cnt = nb_desc;
> + vq->vq_free_cnt = vq_size;
>
> /*
> * Reserve a memzone for vring elements
> @@ -372,7 +379,8 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> PMD_INIT_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d",
> size, vq->vq_ring_size);
>
> - mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size, socket_id,
> + mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
> + SOCKET_ID_ANY,
> 0, VIRTIO_PCI_VRING_ALIGN);
> if (mz == NULL) {
> if (rte_errno == EEXIST)
> @@ -396,7 +404,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
> dev->data->port_id, vtpci_queue_idx);
> hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
> - socket_id, 0,
> + SOCKET_ID_ANY, 0,
> RTE_CACHE_LINE_SIZE);
> if (hdr_mz == NULL) {
> if (rte_errno == EEXIST)
> @@ -413,7 +421,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> sizeof(vq->sw_ring[0]);
>
> sw_ring = rte_zmalloc_socket("sw_ring", sz_sw,
> - RTE_CACHE_LINE_SIZE, socket_id);
> + RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
> if (!sw_ring) {
> PMD_INIT_LOG(ERR, "can not allocate RX soft ring");
> ret = -ENOMEM;
> @@ -424,19 +432,14 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> rxvq = &vq->rxq;
> rxvq->vq = vq;
> rxvq->port_id = dev->data->port_id;
> - rxvq->queue_id = queue_idx;
> rxvq->mz = mz;
> - *pvq = rxvq;
> } else if (queue_type == VTNET_TQ) {
> txvq = &vq->txq;
> txvq->vq = vq;
> txvq->port_id = dev->data->port_id;
> - txvq->queue_id = queue_idx;
> txvq->mz = mz;
> txvq->virtio_net_hdr_mz = hdr_mz;
> txvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
> -
> - *pvq = txvq;
> } else if (queue_type == VTNET_CQ) {
> cvq = &vq->cq;
> cvq->vq = vq;
> @@ -444,7 +447,8 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> cvq->virtio_net_hdr_mz = hdr_mz;
> cvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
> memset(cvq->virtio_net_hdr_mz->addr, 0, PAGE_SIZE);
> - *pvq = cvq;
> +
> + hw->cvq = cvq;
> }
>
> /* For virtio_user case (that is when dev->pci_dev is NULL), we use
> @@ -502,23 +506,45 @@ fail_q_alloc:
> }
>
> static int
> -virtio_dev_cq_queue_setup(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx,
> - uint32_t socket_id)
> +virtio_alloc_queues(struct rte_eth_dev *dev)
> {
> - struct virtnet_ctl *cvq;
> - int ret;
> struct virtio_hw *hw = dev->data->dev_private;
> + uint16_t nr_vq = hw->max_queue_pairs * 2;
> + uint16_t i;
> + int ret;
>
> - PMD_INIT_FUNC_TRACE();
> - ret = virtio_dev_queue_setup(dev, VTNET_CQ, VTNET_SQ_CQ_QUEUE_IDX,
> - vtpci_queue_idx, 0, socket_id, (void **)&cvq);
> - if (ret < 0) {
> - PMD_INIT_LOG(ERR, "control vq initialization failed");
> - return ret;
> + if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
> + nr_vq += 1;
> +
> + hw->vqs = rte_zmalloc(NULL, sizeof(struct virtqueue *) * nr_vq, 0);
> + if (!hw->vqs) {
> + PMD_INIT_LOG(ERR, "failed to allocate vqs");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < nr_vq; i++) {
> + ret = virtio_init_queue(dev, i);
> + if (ret < 0)
> + goto cleanup;
> }
>
> - hw->cvq = cvq;
> return 0;
> +
> +cleanup:
> + /*
> + * ctrl queue is the last queue; if we go here, it means the ctrl
> + * queue is not allocated, that we can do no cleanup for it here.
> + */
> + while (i > 0) {
> + i--;
> + if (i % 2 == 0)
> + virtio_dev_rx_queue_release(&hw->vqs[i]->rxq);
> + else
> + virtio_dev_tx_queue_release(&hw->vqs[i]->txq);
> + }
> + rte_free(hw->vqs);
> +
> + return ret;
> }
>
> static void
> @@ -1141,6 +1167,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
> struct virtio_net_config *config;
> struct virtio_net_config local_config;
> struct rte_pci_device *pci_dev = eth_dev->pci_dev;
> + int ret;
>
> /* Reset the device although not necessary at startup */
> vtpci_reset(hw);
> @@ -1222,6 +1249,10 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
> hw->max_queue_pairs = 1;
> }
>
> + ret = virtio_alloc_queues(eth_dev);
> + if (ret < 0)
> + return ret;
> +
> if (pci_dev)
> PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
> eth_dev->data->port_id, pci_dev->id.vendor_id,
> @@ -1390,15 +1421,9 @@ virtio_dev_configure(struct rte_eth_dev *dev)
> return -ENOTSUP;
> }
>
> - /* Setup and start control queue */
> - if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
> - ret = virtio_dev_cq_queue_setup(dev,
> - hw->max_queue_pairs * 2,
> - SOCKET_ID_ANY);
> - if (ret < 0)
> - return ret;
> + /* start control queue */
> + if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
> virtio_dev_cq_start(dev);
> - }
>
> hw->vlan_strip = rxmode->hw_vlan_strip;
>
> diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
> index de33b32..5db8632 100644
> --- a/drivers/net/virtio/virtio_ethdev.h
> +++ b/drivers/net/virtio/virtio_ethdev.h
> @@ -80,14 +80,6 @@ void virtio_dev_cq_start(struct rte_eth_dev *dev);
> */
> void virtio_dev_rxtx_start(struct rte_eth_dev *dev);
>
> -int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> - int queue_type,
> - uint16_t queue_idx,
> - uint16_t vtpci_queue_idx,
> - uint16_t nb_desc,
> - unsigned int socket_id,
> - void **pvq);
> -
> void virtio_dev_queue_release(struct virtqueue *vq);
>
> int virtio_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
> diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
> index 0c5ed31..f63f76c 100644
> --- a/drivers/net/virtio/virtio_pci.h
> +++ b/drivers/net/virtio/virtio_pci.h
> @@ -264,6 +264,8 @@ struct virtio_hw {
> struct virtio_net_config *dev_cfg;
> const struct virtio_pci_ops *vtpci_ops;
> void *virtio_user_dev;
> +
> + struct virtqueue **vqs;
> };
>
> /*
> diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
> index b4c4aa4..fb703d2 100644
> --- a/drivers/net/virtio/virtio_rxtx.c
> +++ b/drivers/net/virtio/virtio_rxtx.c
> @@ -530,24 +530,24 @@ int
> virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
> uint16_t queue_idx,
> uint16_t nb_desc,
> - unsigned int socket_id,
> + unsigned int socket_id __rte_unused,
> __rte_unused const struct rte_eth_rxconf *rx_conf,
> struct rte_mempool *mp)
> {
> uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
> + struct virtio_hw *hw = dev->data->dev_private;
> + struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
> struct virtnet_rx *rxvq;
> - int ret;
>
> PMD_INIT_FUNC_TRACE();
> - ret = virtio_dev_queue_setup(dev, VTNET_RQ, queue_idx, vtpci_queue_idx,
> - nb_desc, socket_id, (void **)&rxvq);
> - if (ret < 0) {
> - PMD_INIT_LOG(ERR, "rvq initialization failed");
> - return ret;
> - }
>
> - /* Create mempool for rx mbuf allocation */
> + if (nb_desc == 0 || nb_desc > vq->vq_nentries)
> + nb_desc = vq->vq_nentries;
> + vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);
> +
> + rxvq = &vq->rxq;
> rxvq->mpool = mp;
> + rxvq->queue_id = queue_idx;
>
> dev->data->rx_queues[queue_idx] = rxvq;
>
> @@ -613,27 +613,25 @@ int
> virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
> uint16_t queue_idx,
> uint16_t nb_desc,
> - unsigned int socket_id,
> + unsigned int socket_id __rte_unused,
> const struct rte_eth_txconf *tx_conf)
> {
> uint8_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX;
> + struct virtio_hw *hw = dev->data->dev_private;
> + struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
> struct virtnet_tx *txvq;
> - struct virtqueue *vq;
> uint16_t tx_free_thresh;
> - int ret;
>
> PMD_INIT_FUNC_TRACE();
>
> -
> virtio_update_rxtx_handler(dev, tx_conf);
>
> - ret = virtio_dev_queue_setup(dev, VTNET_TQ, queue_idx, vtpci_queue_idx,
> - nb_desc, socket_id, (void **)&txvq);
> - if (ret < 0) {
> - PMD_INIT_LOG(ERR, "tvq initialization failed");
> - return ret;
> - }
> - vq = txvq->vq;
> + if (nb_desc == 0 || nb_desc > vq->vq_nentries)
> + nb_desc = vq->vq_nentries;
> + vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);
> +
> + txvq = &vq->txq;
> + txvq->queue_id = queue_idx;
>
> tx_free_thresh = tx_conf->tx_free_thresh;
> if (tx_free_thresh == 0)
>
^ permalink raw reply
* Re: [PATCH 3/8] net/virtio: simplify queue allocation
From: Maxime Coquelin @ 2016-11-03 20:48 UTC (permalink / raw)
To: Yuanhan Liu, dev; +Cc: Ilya Maximets
In-Reply-To: <1478189400-14606-4-git-send-email-yuanhan.liu@linux.intel.com>
On 11/03/2016 05:09 PM, Yuanhan Liu wrote:
> Let rxq/txq/cq be the union field of the virtqueue struct. This would
> simplifies the vq allocation a bit: we don't need calculate the vq_size
> any more based on the queue time.
s/time/type/ ?
>
> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
> ---
> drivers/net/virtio/virtio_ethdev.c | 18 +++++++-----------
> drivers/net/virtio/virtqueue.h | 7 +++++++
> 2 files changed, 14 insertions(+), 11 deletions(-)
Other than that:
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
^ permalink raw reply
* Re: [PATCH 2/8] net/virtio: simplify queue memzone name
From: Maxime Coquelin @ 2016-11-03 20:41 UTC (permalink / raw)
To: Yuanhan Liu, dev; +Cc: Ilya Maximets
In-Reply-To: <1478189400-14606-3-git-send-email-yuanhan.liu@linux.intel.com>
On 11/03/2016 05:09 PM, Yuanhan Liu wrote:
> Instead of setting up a queue memzone name like "port0_rxq0", "port0_txq0",
> it could be simplified a bit to something like "port0_vq0", "port0_vq1" ...
>
> Meanwhile, the code is also simplified a bit.
>
> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
> ---
> drivers/net/virtio/virtio_ethdev.c | 10 ++++------
> 1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 5815875..d082df5 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -312,7 +312,6 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> struct virtnet_tx *txvq = NULL;
> struct virtnet_ctl *cvq = NULL;
> struct virtqueue *vq;
> - const char *queue_names[] = {"rvq", "txq", "cvq"};
> size_t sz_vq, sz_q = 0, sz_hdr_mz = 0;
> void *sw_ring = NULL;
> int ret;
> @@ -335,8 +334,8 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> return -EINVAL;
> }
>
> - snprintf(vq_name, sizeof(vq_name), "port%d_%s%d",
> - dev->data->port_id, queue_names[queue_type], queue_idx);
> + snprintf(vq_name, sizeof(vq_name), "port%d_vq%d",
> + dev->data->port_id, vtpci_queue_idx);
>
> sz_vq = RTE_ALIGN_CEIL(sizeof(*vq) +
> vq_size * sizeof(struct vq_desc_extra),
> @@ -398,9 +397,8 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
> (uint64_t)(uintptr_t)mz->addr);
>
> if (sz_hdr_mz) {
> - snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_%s%d_hdr",
> - dev->data->port_id, queue_names[queue_type],
> - queue_idx);
> + snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
> + dev->data->port_id, vtpci_queue_idx);
> hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
> socket_id, 0,
> RTE_CACHE_LINE_SIZE);
>
Sounds reasonable:
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
^ permalink raw reply
* Re: [PATCH 1/8] net/virtio: revert "virtio: fix restart"
From: Maxime Coquelin @ 2016-11-03 20:36 UTC (permalink / raw)
To: Yuanhan Liu, dev; +Cc: Ilya Maximets, stable
In-Reply-To: <1478189400-14606-2-git-send-email-yuanhan.liu@linux.intel.com>
Hi Yuanhan,
On 11/03/2016 05:09 PM, Yuanhan Liu wrote:
> This reverts commit 9a0615af7746 ("virtio: fix restart"); conflict is
> manually addressed.
>
> Kyle reported an issue with above commit
>
> qemu-kvm: Guest moved used index from 5 to 1
>
> with following steps,
>
> 1) Start my virtio interfaces
> 2) Send some traffic into/out of the interfaces
> 3) Stop the interfaces
> 4) Start the interfaces
> 5) Send some more traffic
>
> And here are some quotes from Kyle's analysis,
>
> Prior to the patch, if an interface were stopped then started, without
> restarting the application, the queues would be left as-is, because
> hw->started would be set to 1. Now, calling stop sets hw->started to 0,
> which means the next call to start will "touch the queues". This is the
> unintended side-effect that causes the problem.
Maybe a good idea to explain what is the problem the revert aims to fix.
It does not seem to be clearly stated in the commit message.
>
> Fixes: 9a0615af7746 ("virtio: fix restart")
>
> Cc: Jianfeng Tan <jianfeng.tan@intel.com>
> Cc: <stable@dpdk.org>
> Reported-by: Kyle Larose <klarose@sandvine.com>
> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Thanks,
Maxime
^ permalink raw reply
* Re: [dpdk-users] rte_zmalloc() returning non-zeroed memory on FreeBSD
From: Lewis Donzis @ 2016-11-03 20:04 UTC (permalink / raw)
To: dev
I’m curious about how/whether this got resolved. The 16.07.1 code doesn’t appear to have this fixed.
Is it still forthcoming?
Thanks,
lew
^ permalink raw reply
* [PATCH 2/2] bnxt: add a FALLTHROUGH comment in the cascading switch statement
From: Ajit Khaparde @ 2016-11-03 18:58 UTC (permalink / raw)
To: dev
The cascading switch statement in bnxt_hwrm.c is missing the FALLTHROUGH
comment. Adding that.
Coverity: 127552
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
drivers/net/bnxt/bnxt_hwrm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index cf79fc6..07e7124 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -606,6 +606,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
switch (ring_type) {
case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
req.queue_id = bp->cos_queue[0].id;
+ /* FALLTHROUGH */
case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX:
req.ring_type = ring_type;
req.cmpl_ring_id =
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/2 v2] bnxt: use appropriate data type in bnxt_alloc_vnic_attributes
From: Ajit Khaparde @ 2016-11-03 18:58 UTC (permalink / raw)
To: dev
Prevent the arithmetic in bnxt_alloc_vnic_attributes from causing
any unintentional havoc because of the usage of a signed variable.
Coverity: 137874
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v2: Previous attempt did not seem complete.
---
drivers/net/bnxt/bnxt_vnic.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 205a940..23c85af 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -179,7 +179,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table) +
HW_HASH_KEY_SIZE);
uint16_t max_vnics;
- int i;
+ uint16_t i;
if (BNXT_PF(bp)) {
struct bnxt_pf_info *pf = &bp->pf;
@@ -197,7 +197,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
mz = rte_memzone_lookup(mz_name);
if (!mz) {
mz = rte_memzone_reserve(mz_name,
- entry_length * max_vnics,
+ (uint32_t) entry_length * max_vnics,
SOCKET_ID_ANY,
RTE_MEMZONE_2MB |
RTE_MEMZONE_SIZE_HINT_ONLY);
@@ -210,10 +210,11 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
/* Allocate rss table and hash key */
vnic->rss_table =
- (void *)((char *)mz->addr + (entry_length * i));
+ (void *)((char *)mz->addr + ((uint32_t) entry_length * i));
memset(vnic->rss_table, -1, entry_length);
- vnic->rss_table_dma_addr = mz->phys_addr + (entry_length * i);
+ vnic->rss_table_dma_addr =
+ mz->phys_addr + ((uint32_t) entry_length * i);
vnic->rss_hash_key = (void *)((char *)vnic->rss_table +
HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table));
--
1.8.3.1
^ permalink raw reply related
* [PATCH] doc: update release notes with enic PMD changes
From: John Daley @ 2016-11-03 18:01 UTC (permalink / raw)
To: john.mcnamara; +Cc: dev
Signed-off-by: John Daley <johndale@cisco.com>
---
doc/guides/nics/features/enic.ini | 2 +-
doc/guides/rel_notes/release_16_11.rst | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini
index 523d4f1..86576a7 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -7,7 +7,7 @@
Link status = Y
Link status event = Y
Queue start/stop = Y
-MTU update = P
+MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
Promiscuous mode = Y
diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index 26cdd62..4427c52 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -131,6 +131,15 @@ New Features
The GCC 4.9 ``-march`` option supports the Intel processor code names.
The config option ``RTE_MACHINE`` can be used to pass code names to the compiler as ``-march`` flag.
+* **Updated the enic driver.**
+
+ The following changes were made to enic:
+
+ * Use interrupt for link status checking instead of polling
+ * More flow director modes on UCS Blade with firmware version >= 2.0(13e)
+ * Full support for MTU update
+ * Support for rte_eth_rx_queue_count function
+ * Several bug fixes
Resolved Issues
---------------
@@ -153,6 +162,11 @@ EAL
Drivers
~~~~~~~
+* **enic: Fixed several flow director issues **
+
+* **enic: Fixed inadvertent setting of L4 checksum ptype on ICMP packets
+
+* **enic: Fixed high driver overhead when servicing Rx queues beyond the first
Libraries
~~~~~~~~~
--
2.10.0
^ permalink raw reply related
* [PATCH v9] app/testpmd: fix DCB configuration
From: Bernard Iremonger @ 2016-11-03 17:35 UTC (permalink / raw)
To: dev, rahul.r.shah, jingjing.wu, wenzhuo.lu
In-Reply-To: <1477996609-19629-1-git-send-email-bernard.iremonger@intel.com>
Data Centre Bridge (DCB) configuration fails when SRIOV is
enabled if nb_rxq or nb_txq are greater than nb_q_per_pool.
The failure occurs during configuration of the ixgbe PMD when
it is started, in the ixgbe_check_mq_mode function.
Fixes: 2a977b891f99 ("app/testpmd: fix DCB configuration")
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
Changes in v9:
when max_vfs is greater then 0, set nb_rxq and nb_txq to
dev_info.nb_rx_queues and dev_info.nb_tx_queues.
Changes in v8:
revise commit message.
Changes in v7:
restore nb_rxq and nb_txq setting when max_vfs is 0
app/test-pmd/testpmd.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 6185be6..a0332c2 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -2002,8 +2002,13 @@ init_port_dcb_config(portid_t pid,
* and has the same number of rxq and txq in dcb mode
*/
if (dcb_mode == DCB_VT_ENABLED) {
- nb_rxq = rte_port->dev_info.max_rx_queues;
- nb_txq = rte_port->dev_info.max_tx_queues;
+ if (rte_port->dev_info.max_vfs > 0) {
+ nb_rxq = rte_port->dev_info.nb_rx_queues;
+ nb_txq = rte_port->dev_info.nb_tx_queues;
+ } else {
+ nb_rxq = rte_port->dev_info.max_rx_queues;
+ nb_txq = rte_port->dev_info.max_tx_queues;
+ }
} else {
/*if vt is disabled, use all pf queues */
if (rte_port->dev_info.vmdq_pool_base == 0) {
--
2.10.1
^ permalink raw reply related
* [PATCH 1/8] net/virtio: revert "virtio: fix restart"
From: Yuanhan Liu @ 2016-11-03 16:09 UTC (permalink / raw)
To: dev; +Cc: stable, Ilya Maximets
In-Reply-To: <1478189400-14606-1-git-send-email-yuanhan.liu@linux.intel.com>
This reverts commit 9a0615af7746 ("virtio: fix restart"); conflict is
manually addressed.
Kyle reported an issue with above commit
qemu-kvm: Guest moved used index from 5 to 1
with following steps,
1) Start my virtio interfaces
2) Send some traffic into/out of the interfaces
3) Stop the interfaces
4) Start the interfaces
5) Send some more traffic
And here are some quotes from Kyle's analysis,
Prior to the patch, if an interface were stopped then started, without
restarting the application, the queues would be left as-is, because
hw->started would be set to 1. Now, calling stop sets hw->started to 0,
which means the next call to start will "touch the queues". This is the
unintended side-effect that causes the problem.
Fixes: 9a0615af7746 ("virtio: fix restart")
Cc: Jianfeng Tan <jianfeng.tan@intel.com>
Cc: <stable@dpdk.org>
Reported-by: Kyle Larose <klarose@sandvine.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index b388134..5815875 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -550,9 +550,6 @@ virtio_dev_close(struct rte_eth_dev *dev)
PMD_INIT_LOG(DEBUG, "virtio_dev_close");
- if (hw->started == 1)
- virtio_dev_stop(dev);
-
if (hw->cvq)
virtio_dev_queue_release(hw->cvq->vq);
@@ -560,6 +557,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
vtpci_irq_config(hw, VIRTIO_MSI_NO_VECTOR);
vtpci_reset(hw);
+ hw->started = 0;
virtio_dev_free_mbufs(dev);
virtio_free_queues(dev);
}
@@ -1296,15 +1294,17 @@ static int
eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev;
+ struct virtio_hw *hw = eth_dev->data->dev_private;
PMD_INIT_FUNC_TRACE();
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return -EPERM;
- /* Close it anyway since there's no way to know if closed */
- virtio_dev_close(eth_dev);
-
+ if (hw->started == 1) {
+ virtio_dev_stop(eth_dev);
+ virtio_dev_close(eth_dev);
+ }
pci_dev = eth_dev->pci_dev;
eth_dev->dev_ops = NULL;
@@ -1543,12 +1543,9 @@ static void
virtio_dev_stop(struct rte_eth_dev *dev)
{
struct rte_eth_link link;
- struct virtio_hw *hw = dev->data->dev_private;
PMD_INIT_LOG(DEBUG, "stop");
- hw->started = 0;
-
if (dev->data->dev_conf.intr_conf.lsc)
rte_intr_disable(&dev->pci_dev->intr_handle);
--
1.9.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox