* [dpdk-dev] [PATCH v1 0/3] add ethdev op to get hash index
@ 2019-09-14 5:52 vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 1/3] lib/ethdev: " vattunuru
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: vattunuru @ 2019-09-14 5:52 UTC (permalink / raw)
To: dev; +Cc: jerinj, ferruh.yigit, arybchenko, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
***
Following patch set adds ethdev op to fetch hash index from ethdev pmd
for a given hash value. It enables pmds to compute hash index using
HW supported custom algos.
Patch set also adds autotest for these API to verify whether packet
distribution is as per computed hash index or not.
Vamsi Attunuru (3):
lib/ethdev: add ethdev op to get hash index
app/test: add hash index verify autotest
net/octeontx2: add eth dev op callback to get hash index
app/test/Makefile | 1 +
app/test/autotest_data.py | 6 +
app/test/meson.build | 1 +
app/test/test_hash_index.c | 347 +++++++++++++++++++++++++++++++
drivers/net/octeontx2/otx2_ethdev.c | 1 +
drivers/net/octeontx2/otx2_ethdev.h | 3 +
drivers/net/octeontx2/otx2_rss.c | 18 ++
lib/librte_ethdev/rte_ethdev.c | 13 ++
lib/librte_ethdev/rte_ethdev.h | 20 ++
lib/librte_ethdev/rte_ethdev_core.h | 5 +
lib/librte_ethdev/rte_ethdev_version.map | 3 +
11 files changed, 418 insertions(+)
create mode 100644 app/test/test_hash_index.c
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v1 1/3] lib/ethdev: add ethdev op to get hash index
2019-09-14 5:52 [dpdk-dev] [PATCH v1 0/3] add ethdev op to get hash index vattunuru
@ 2019-09-14 5:52 ` vattunuru
2019-10-03 13:00 ` Andrew Rybchenko
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 0/3] " vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 2/3] app/test: add hash index verify autotest vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 3/3] net/octeontx2: add eth dev op callback to get hash index vattunuru
2 siblings, 2 replies; 15+ messages in thread
From: vattunuru @ 2019-09-14 5:52 UTC (permalink / raw)
To: dev; +Cc: jerinj, ferruh.yigit, arybchenko, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
Some networking devices may use custom algos for computing
hash indices and spread the packets accordingly.
Patch adds a eth_dev op to get the hash index correspond to
the given hash value received on the given port.
Some of use cases where applications would compute hash index
from hash value upfront and it can predict the packets come to
a specific queue.
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
lib/librte_ethdev/rte_ethdev.c | 13 +++++++++++++
lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++++++++++++
lib/librte_ethdev/rte_ethdev_core.h | 5 +++++
lib/librte_ethdev/rte_ethdev_version.map | 3 +++
4 files changed, 41 insertions(+)
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e..6a234d6 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -3022,6 +3022,19 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
}
int
+rte_eth_dev_rss_hash_index_get(uint16_t port_id,
+ uint32_t hash, uint32_t *hash_idx)
+{
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_index_get, -ENOTSUP);
+ return eth_err(port_id, (*dev->dev_ops->rss_hash_index_get)(dev, hash,
+ hash_idx));
+}
+
+int
rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
struct rte_eth_udp_tunnel *udp_tunnel)
{
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index dc6596b..03ca1e9 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -3262,6 +3262,26 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
struct rte_eth_rss_conf *rss_conf);
/**
+ * Get hash index of the given hash value that received in mbuf from this port.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param hash
+ * The hash value used to compute hash_idx.
+ * @param hash_idx
+ * Where to store the computed hash_idx
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if port identifier is invalid.
+ * - (-EIO) if device is removed.
+ * - (-ENOTSUP) if hardware doesn't support RSS.
+ */
+__rte_experimental
+int
+rte_eth_dev_rss_hash_index_get(uint16_t port_id,
+ uint32_t hash, uint32_t *hash_idx);
+
+ /**
* Add UDP tunneling port for a specific type of tunnel.
* The packets with this UDP port will be identified as this type of tunnel.
* Before enabling any offloading function for a tunnel, users can call this API
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 2922d5b..aebfb5f 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -240,6 +240,10 @@ typedef int (*rss_hash_conf_get_t)(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
/**< @internal Get current RSS hash configuration of an Ethernet device */
+typedef int (*rss_hash_index_get_t)(struct rte_eth_dev *dev,
+ uint32_t hash, uint32_t *hash_idx);
+/**< @internal Get RSS hash id of given hash value */
+
typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev);
/**< @internal Turn on SW controllable LED on an Ethernet device */
@@ -471,6 +475,7 @@ struct eth_dev_ops {
rss_hash_update_t rss_hash_update; /** Configure RSS hash protocols. */
rss_hash_conf_get_t rss_hash_conf_get; /** Get current RSS hash configuration. */
+ rss_hash_index_get_t rss_hash_index_get; /** Get RSS hash idx. */
reta_update_t reta_update; /** Update redirection table. */
reta_query_t reta_query; /** Query redirection table. */
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a4..ea6d1bf 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -283,4 +283,7 @@ EXPERIMENTAL {
# added in 19.08
rte_eth_read_clock;
+
+ # added in 19.11
+ rte_eth_dev_rss_hash_index_get;
};
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v1 2/3] app/test: add hash index verify autotest
2019-09-14 5:52 [dpdk-dev] [PATCH v1 0/3] add ethdev op to get hash index vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 1/3] lib/ethdev: " vattunuru
@ 2019-09-14 5:52 ` vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 3/3] net/octeontx2: add eth dev op callback to get hash index vattunuru
2 siblings, 0 replies; 15+ messages in thread
From: vattunuru @ 2019-09-14 5:52 UTC (permalink / raw)
To: dev; +Cc: jerinj, ferruh.yigit, arybchenko, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
Patch adds a autotest to validate rte_eth_dev_rss_hash_index_get()
ethdev op.
Test configures the ethport in loopback mode and enables RSS for
IP packets. The hash indices returned by those API gets validated
by matching queue number in the reta table with the rxq(queue's idx)
on which the packet received.
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
app/test/Makefile | 1 +
app/test/autotest_data.py | 6 +
app/test/meson.build | 1 +
app/test/test_hash_index.c | 347 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 355 insertions(+)
diff --git a/app/test/Makefile b/app/test/Makefile
index 26ba6fe..04ff705 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -79,6 +79,7 @@ SRCS-y += test_rand_perf.c
SRCS-y += test_ring.c
SRCS-y += test_ring_perf.c
SRCS-y += test_pmd_perf.c
+SRCS-y += test_hash_index.c
ifeq ($(CONFIG_RTE_LIBRTE_TABLE),y)
SRCS-y += test_table.c
diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py
index 7405149..fef76d0 100644
--- a/app/test/autotest_data.py
+++ b/app/test/autotest_data.py
@@ -653,6 +653,12 @@
"Report": None,
},
{
+ "Name": "Hash index verify autotest",
+ "Command": "hash_index_verify_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
"Name": "Ring pmd perf autotest",
"Command": "ring_pmd_perf_autotest",
"Func": default_autotest,
diff --git a/app/test/meson.build b/app/test/meson.build
index ec40943..3da13231 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -84,6 +84,7 @@ test_sources = files('commands.c',
'test_mp_secondary.c',
'test_pdump.c',
'test_per_lcore.c',
+ 'test_hash_index.c',
'test_pmd_perf.c',
'test_pmd_ring.c',
'test_pmd_ring_perf.c',
diff --git a/app/test/test_hash_index.c b/app/test/test_hash_index.c
new file mode 100644
index 0000000..854404f
--- /dev/null
+++ b/app/test/test_hash_index.c
@@ -0,0 +1,347 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <unistd.h>
+#include <rte_cycles.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include "packet_burst_generator.h"
+#include "test.h"
+
+#define NB_ETHPORTS_USED 1
+#define MAX_PKT_BURST 32
+#define MAX_TRAFFIC_BURST 128
+#define MEMPOOL_CACHE_SIZE 32
+#define MAX_TEST_QUEUES_PER_PORT 4
+
+#define DEF_RETA_SIZE RTE_RETA_GROUP_SIZE
+
+#define NB_MBUF RTE_MAX( \
+ (uint32_t)(nb_ports*nb_rx_queue*nb_rxd + \
+ nb_ports*MAX_PKT_BURST + \
+ nb_ports*nb_tx_queue*nb_txd + \
+ 1*MEMPOOL_CACHE_SIZE + \
+ nb_ports*MAX_TRAFFIC_BURST), \
+ (uint32_t)4096)
+
+static struct rte_mempool *mbufpool;
+static struct rte_eth_rss_reta_entry64 reta_conf;
+
+static struct rte_eth_conf port_conf = {
+ .rxmode = {
+ .mq_mode = ETH_MQ_RX_RSS,
+ .max_rx_pkt_len = RTE_ETHER_MAX_LEN,
+ .split_hdr_size = 0,
+ },
+ .txmode = {
+ .mq_mode = ETH_MQ_TX_NONE,
+ },
+ .lpbk_mode = 1, /* enable loopback */
+ .rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP,
+};
+
+static struct rte_eth_rxconf rx_conf = {
+ .rx_free_thresh = 32,
+};
+
+static struct rte_eth_txconf tx_conf = {
+ .tx_free_thresh = 32, /* Use PMD default values */
+ .tx_rs_thresh = 32, /* Use PMD default values */
+};
+
+static uint64_t link_mbps;
+
+static void
+check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */
+ uint8_t count, all_ports_up, print_flag = 0;
+ struct rte_eth_link link;
+ uint16_t portid;
+
+ printf("Checking link statuses...\n");
+ 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 << portid)) == 0)
+ continue;
+ memset(&link, 0, sizeof(link));
+ rte_eth_link_get_nowait(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",
+ portid, link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ if (link_mbps == 0)
+ link_mbps = link.link_speed;
+ } else
+ printf("Port %d Link Down\n", 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) {
+ 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;
+ }
+}
+
+static inline void
+copy_buf_to_pkt(void *buf, uint32_t len, struct rte_mbuf *pkt, uint32_t offset)
+{
+ rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset), buf,
+ (size_t) len);
+}
+
+static int
+init_traffic(struct rte_mempool *mp,
+ struct rte_mbuf **pkts_burst, uint32_t burst_size)
+{
+ static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
+ static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
+ struct rte_ether_hdr pkt_eth_hdr;
+ struct rte_ipv4_hdr pkt_ipv4_hdr;
+ struct rte_udp_hdr pkt_udp_hdr;
+ struct rte_mbuf *pkt;
+ size_t eth_hdr_size;
+ uint32_t nb_pkt;
+
+ initialize_eth_header(&pkt_eth_hdr,
+ (struct rte_ether_addr *)src_mac,
+ (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0);
+
+ eth_hdr_size = sizeof(struct rte_ether_hdr);
+
+ initialize_udp_header(&pkt_udp_hdr, 0, 0, 18);
+
+ for (nb_pkt = 0; nb_pkt < burst_size; nb_pkt++) {
+ pkt = rte_pktmbuf_alloc(mp);
+ if (pkt == NULL)
+ break;
+
+ pkt->data_len = PACKET_BURST_GEN_PKT_LEN;
+
+ copy_buf_to_pkt(&pkt_eth_hdr, eth_hdr_size, pkt, 0);
+
+ initialize_ipv4_header(&pkt_ipv4_hdr,
+ IPV4_ADDR(10, 0, 0, 1) + nb_pkt,
+ IPV4_ADDR(10, 0, 0, 2), 26);
+
+ copy_buf_to_pkt(&pkt_ipv4_hdr, sizeof(struct rte_ipv4_hdr),
+ pkt, eth_hdr_size);
+ copy_buf_to_pkt(&pkt_udp_hdr, sizeof(struct rte_udp_hdr), pkt,
+ eth_hdr_size + sizeof(struct rte_ipv4_hdr));
+
+ pkt->pkt_len = PACKET_BURST_GEN_PKT_LEN;
+ pkt->l2_len = eth_hdr_size;
+ pkt->l3_len = sizeof(struct rte_ipv4_hdr);
+
+ pkts_burst[nb_pkt] = pkt;
+ }
+
+ return 0;
+}
+
+struct rte_mbuf **tx_burst;
+
+static int
+start_hash_index_verify(int portid)
+{
+ uint64_t end_cycles = rte_get_timer_hz() * 5; /* 5 Sec */
+ struct rte_mbuf *rx_burst[MAX_PKT_BURST];
+ uint32_t hash, hash_idx, count = 0, rxq;
+ uint32_t nb_rx = 0, nb_tx = 0;
+ int idx = 0, rc, mismatch = 0;
+ int num = MAX_TRAFFIC_BURST;
+ uint64_t start_cycles;
+
+ printf("inject %d packet to port %d\n", num, portid);
+ while (num) {
+ nb_tx = RTE_MIN(MAX_PKT_BURST, num);
+ nb_tx = rte_eth_tx_burst(portid, 0,
+ &tx_burst[idx], nb_tx);
+ num -= nb_tx;
+ idx += nb_tx;
+ }
+
+ printf("Total packets inject to port = %u\n", idx);
+
+ start_cycles = rte_get_timer_cycles();
+
+ while (count < MAX_TRAFFIC_BURST) {
+ for (rxq = 0 ; rxq < MAX_TEST_QUEUES_PER_PORT; rxq++) {
+ nb_rx = rte_eth_rx_burst(portid, rxq, rx_burst, 1);
+ if (nb_rx) {
+ hash = rx_burst[0]->hash.rss;
+ rc = rte_eth_dev_rss_hash_index_get(portid,
+ hash,
+ &hash_idx);
+ if (rc < 0)
+ hash_idx = hash % DEF_RETA_SIZE;
+
+ if (rxq != reta_conf.reta[hash_idx])
+ mismatch++;
+
+ rte_pktmbuf_free(rx_burst[0]);
+ count += nb_rx;
+ }
+ }
+ if (rte_get_timer_cycles() - start_cycles > end_cycles)
+ break;
+ }
+
+ printf("Total packets received = %u\n", count);
+
+ if (mismatch) {
+ printf("hash index mismatch in %d pkts\n", mismatch);
+ return -1;
+ }
+
+ printf("Hash index verified on %u pkts\n", count);
+
+ return 0;
+}
+
+static int
+test_hash_index(void)
+{
+ uint16_t nb_rx_queue = MAX_TEST_QUEUES_PER_PORT;
+ uint16_t nb_tx_queue = MAX_TEST_QUEUES_PER_PORT;
+ uint16_t reta_size = RTE_RETA_GROUP_SIZE;
+ uint16_t nb_rxd = MAX_TRAFFIC_BURST;
+ uint16_t nb_txd = MAX_TRAFFIC_BURST;
+ struct rte_eth_dev_info dev_info;
+ uint16_t portid = 0;
+ int socketid = -1;
+ uint16_t nb_ports;
+ int ret = 0;
+ uint16_t i;
+
+ printf("Start hash index verify test.\n");
+
+ nb_ports = rte_eth_dev_count_avail();
+ if (nb_ports < NB_ETHPORTS_USED) {
+ printf("At least %u port(s) used for the test\n",
+ NB_ETHPORTS_USED);
+ return -1;
+ }
+
+ nb_ports = NB_ETHPORTS_USED;
+
+ mbufpool = rte_pktmbuf_pool_create("pkt mempool", NB_MBUF,
+ MEMPOOL_CACHE_SIZE, 0,
+ RTE_MBUF_DEFAULT_BUF_SIZE, 0);
+ if (mbufpool == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot alloc mbuf pool\n");
+
+ rte_eth_dev_info_get(portid, &dev_info);
+
+ if (nb_rx_queue > dev_info.max_rx_queues)
+ nb_rx_queue = dev_info.max_rx_queues;
+
+ if (nb_tx_queue > dev_info.max_tx_queues)
+ nb_tx_queue = dev_info.max_tx_queues;
+
+ if (reta_size > dev_info.reta_size)
+ reta_size = dev_info.reta_size;
+
+ /* port configure */
+ ret = rte_eth_dev_configure(portid, nb_rx_queue,
+ nb_tx_queue, &port_conf);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "Cannot configure device: err=%d, port=%d\n",
+ ret, portid);
+
+ for (i = 0; i < nb_tx_queue; i++) {
+ /* tx queue setup */
+ ret = rte_eth_tx_queue_setup(portid, i, nb_txd,
+ socketid, &tx_conf);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "rte_eth_tx_queue_setup: err=%d, "
+ "port=%d\n", ret, portid);
+ }
+
+ for (i = 0; i < nb_rx_queue; i++) {
+ /* rx queue steup */
+ ret = rte_eth_rx_queue_setup(portid, i, nb_rxd,
+ socketid, &rx_conf, mbufpool);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
+ "port=%d\n", ret, portid);
+ }
+
+ for (i = 0; i < reta_size; i++) {
+ reta_conf.reta[i] = i % nb_rx_queue;
+ reta_conf.mask |= (1ULL << i);
+ }
+ rte_eth_dev_rss_reta_update(portid, &reta_conf, reta_size);
+
+ /* Start device */
+ ret = rte_eth_dev_start(portid);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "rte_eth_dev_start: err=%d, port=%d\n",
+ ret, portid);
+
+ /* always eanble promiscuous */
+ rte_eth_promiscuous_enable(portid);
+
+ check_all_ports_link_status(1, 1);
+
+ if (tx_burst == NULL) {
+ tx_burst = (struct rte_mbuf **)
+ rte_calloc_socket("tx_buff",
+ MAX_TRAFFIC_BURST * nb_ports,
+ sizeof(void *),
+ RTE_CACHE_LINE_SIZE, socketid);
+ if (!tx_burst)
+ return -1;
+ }
+
+ init_traffic(mbufpool,
+ tx_burst, MAX_TRAFFIC_BURST * nb_ports);
+
+ printf("Generate %d packets @socket %d\n",
+ MAX_TRAFFIC_BURST * nb_ports, socketid);
+
+ ret = start_hash_index_verify(portid);
+
+ /* port tear down */
+ rte_eth_dev_stop(portid);
+ rte_eth_dev_close(portid);
+
+ if (tx_burst)
+ rte_free(tx_burst);
+
+ if (mbufpool)
+ rte_mempool_free(mbufpool);
+
+ return ret;
+}
+
+REGISTER_TEST_COMMAND(hash_index_verify_autotest, test_hash_index);
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v1 3/3] net/octeontx2: add eth dev op callback to get hash index
2019-09-14 5:52 [dpdk-dev] [PATCH v1 0/3] add ethdev op to get hash index vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 1/3] lib/ethdev: " vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 2/3] app/test: add hash index verify autotest vattunuru
@ 2019-09-14 5:52 ` vattunuru
2 siblings, 0 replies; 15+ messages in thread
From: vattunuru @ 2019-09-14 5:52 UTC (permalink / raw)
To: dev; +Cc: jerinj, ferruh.yigit, arybchenko, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
patch adds pmd support for hash_index_get() ethdev_op callback.
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
drivers/net/octeontx2/otx2_ethdev.c | 1 +
drivers/net/octeontx2/otx2_ethdev.h | 3 +++
| 18 ++++++++++++++++++
3 files changed, 22 insertions(+)
diff --git a/drivers/net/octeontx2/otx2_ethdev.c b/drivers/net/octeontx2/otx2_ethdev.c
index b84128f..bfca60c 100644
--- a/drivers/net/octeontx2/otx2_ethdev.c
+++ b/drivers/net/octeontx2/otx2_ethdev.c
@@ -1636,6 +1636,7 @@ static const struct eth_dev_ops otx2_eth_dev_ops = {
.reta_query = otx2_nix_dev_reta_query,
.rss_hash_update = otx2_nix_rss_hash_update,
.rss_hash_conf_get = otx2_nix_rss_hash_conf_get,
+ .rss_hash_index_get = otx2_nix_rss_hash_index_get,
.xstats_get = otx2_nix_xstats_get,
.xstats_get_names = otx2_nix_xstats_get_names,
.xstats_reset = otx2_nix_xstats_reset,
diff --git a/drivers/net/octeontx2/otx2_ethdev.h b/drivers/net/octeontx2/otx2_ethdev.h
index 7b15d6b..6ea5974 100644
--- a/drivers/net/octeontx2/otx2_ethdev.h
+++ b/drivers/net/octeontx2/otx2_ethdev.h
@@ -465,6 +465,9 @@ int otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
int otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
struct rte_eth_rss_conf *rss_conf);
+int otx2_nix_rss_hash_index_get(struct rte_eth_dev *eth_dev,
+ uint32_t hash, uint32_t *hash_idx);
+
/* CGX */
int otx2_cgx_rxtx_start(struct otx2_eth_dev *dev);
int otx2_cgx_rxtx_stop(struct otx2_eth_dev *dev);
--git a/drivers/net/octeontx2/otx2_rss.c b/drivers/net/octeontx2/otx2_rss.c
index 5afa214..4b40dfd 100644
--- a/drivers/net/octeontx2/otx2_rss.c
+++ b/drivers/net/octeontx2/otx2_rss.c
@@ -328,6 +328,24 @@ otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
}
int
+otx2_nix_rss_hash_index_get(struct rte_eth_dev *eth_dev,
+ uint32_t hash, uint32_t *hash_idx)
+{
+ struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+ union flow_tag {
+ uint32_t hash;
+ uint8_t byte[4];
+ } tag;
+
+ tag.hash = hash;
+
+ *hash_idx = (tag.byte[0] ^ tag.byte[1] ^ tag.byte[2] ^ tag.byte[3]) %
+ dev->rss_info.rss_size;
+
+ return 0;
+}
+
+int
otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
{
struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH v1 1/3] lib/ethdev: add ethdev op to get hash index
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 1/3] lib/ethdev: " vattunuru
@ 2019-10-03 13:00 ` Andrew Rybchenko
2019-10-07 4:45 ` [dpdk-dev] [EXT] " Vamsi Krishna Attunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 0/3] " vattunuru
1 sibling, 1 reply; 15+ messages in thread
From: Andrew Rybchenko @ 2019-10-03 13:00 UTC (permalink / raw)
To: vattunuru, dev; +Cc: jerinj, ferruh.yigit, thomas
Hi,
On 9/14/19 8:52 AM, vattunuru@marvell.com wrote:
> From: Vamsi Attunuru <vattunuru@marvell.com>
>
> Some networking devices may use custom algos for computing
> hash indices and spread the packets accordingly.
>
> Patch adds a eth_dev op to get the hash index correspond to
> the given hash value received on the given port.
>
> Some of use cases where applications would compute hash index
> from hash value upfront and it can predict the packets come to
> a specific queue.
>
> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
I'm sorry, but the purpose of the API and provided functionality
is unclear for me from above description.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [EXT] Re: [PATCH v1 1/3] lib/ethdev: add ethdev op to get hash index
2019-10-03 13:00 ` Andrew Rybchenko
@ 2019-10-07 4:45 ` Vamsi Krishna Attunuru
0 siblings, 0 replies; 15+ messages in thread
From: Vamsi Krishna Attunuru @ 2019-10-07 4:45 UTC (permalink / raw)
To: Andrew Rybchenko, dev; +Cc: Jerin Jacob Kollanukkaran, ferruh.yigit, thomas
> -----Original Message-----
> From: Andrew Rybchenko <arybchenko@solarflare.com>
> Sent: Thursday, October 3, 2019 6:31 PM
> To: Vamsi Krishna Attunuru <vattunuru@marvell.com>; dev@dpdk.org
> Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; ferruh.yigit@intel.com;
> thomas@monjalon.net
> Subject: [EXT] Re: [dpdk-dev] [PATCH v1 1/3] lib/ethdev: add ethdev op to get
> hash index
>
> External Email
>
> ----------------------------------------------------------------------
> Hi,
>
> On 9/14/19 8:52 AM, vattunuru@marvell.com wrote:
> > From: Vamsi Attunuru <vattunuru@marvell.com>
> >
> > Some networking devices may use custom algos for computing hash
> > indices and spread the packets accordingly.
> >
> > Patch adds a eth_dev op to get the hash index correspond to the given
> > hash value received on the given port.
> >
> > Some of use cases where applications would compute hash index from
> > hash value upfront and it can predict the packets come to a specific
> > queue.
> >
> > Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
>
> I'm sorry, but the purpose of the API and provided functionality is unclear for
> me from above description.
@Andrew, Please see the below description, if it explains the patch clearly, will send v2.
" Some networking devices may use custom algos for computing
hash indices and spread the packets accordingly.
Patch adds a eth_dev op to get the hash index correspond to
the given hash value received in the initial packet on the given port.
Some of the applications compute hash index from the hash value
received in the initial packet and than configure the rxq to lcore
mapping to make sure the mapped lcore/rxq would receive the
upcoming traffic that has similar hash. Such applications may use
these API to get the hash index used by the PMD for spreading
those traffic."
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v2 0/3] add ethdev op to get hash index
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 1/3] lib/ethdev: " vattunuru
2019-10-03 13:00 ` Andrew Rybchenko
@ 2019-10-15 9:52 ` vattunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 1/3] lib/ethdev: " vattunuru
` (2 more replies)
1 sibling, 3 replies; 15+ messages in thread
From: vattunuru @ 2019-10-15 9:52 UTC (permalink / raw)
To: dev; +Cc: arybchenko, jerinj, ferruh.yigit, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
---
Following patch set adds ethdev op to fetch hash index from ethdev pmd
for a given hash value. It enables pmds to compute hash index using
HW supported custom algos.
Patch set also adds autotest for these API to verify whether packet
distribution is as per computed hash index or not.
V2 Change:
* Updated description in the commit message.
Vamsi Attunuru (3):
lib/ethdev: add ethdev op to get hash index
app/test: add hash index verify autotest
net/octeontx2: add eth dev op callback to get hash index
app/test/Makefile | 1 +
app/test/autotest_data.py | 6 +
app/test/meson.build | 1 +
app/test/test_hash_index.c | 347 +++++++++++++++++++++++++++++++
drivers/net/octeontx2/otx2_ethdev.c | 1 +
drivers/net/octeontx2/otx2_ethdev.h | 3 +
drivers/net/octeontx2/otx2_rss.c | 18 ++
lib/librte_ethdev/rte_ethdev.c | 13 ++
lib/librte_ethdev/rte_ethdev.h | 20 ++
lib/librte_ethdev/rte_ethdev_core.h | 5 +
lib/librte_ethdev/rte_ethdev_version.map | 3 +
11 files changed, 418 insertions(+)
create mode 100644 app/test/test_hash_index.c
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v2 1/3] lib/ethdev: add ethdev op to get hash index
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 0/3] " vattunuru
@ 2019-10-15 9:52 ` vattunuru
2019-10-15 16:47 ` Ferruh Yigit
2019-10-16 17:48 ` Ferruh Yigit
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 2/3] app/test: add hash index verify autotest vattunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 3/3] net/octeontx2: add eth dev op callback to get hash index vattunuru
2 siblings, 2 replies; 15+ messages in thread
From: vattunuru @ 2019-10-15 9:52 UTC (permalink / raw)
To: dev; +Cc: arybchenko, jerinj, ferruh.yigit, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
Some networking devices may use custom algos for computing
hash indices and spread the packets accordingly.
Patch adds an eth_dev op to get the hash index correspond
to the given hash value received in the initial packet on
the given port.
Some of the applications compute hash index from the hash
value received in the initial packet and than configure
the rxq to lcore mapping to make sure the mapped lcore/rxq
would receive the upcoming traffic that has similar hash.
Such applications may use these API to get the hash index
used by the PMD for spreading those traffic.
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
lib/librte_ethdev/rte_ethdev.c | 13 +++++++++++++
lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++++++++++++
lib/librte_ethdev/rte_ethdev_core.h | 5 +++++
lib/librte_ethdev/rte_ethdev_version.map | 3 +++
4 files changed, 41 insertions(+)
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index af82360..ed02168 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -3140,6 +3140,19 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
}
int
+rte_eth_dev_rss_hash_index_get(uint16_t port_id,
+ uint32_t hash, uint32_t *hash_idx)
+{
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_index_get, -ENOTSUP);
+ return eth_err(port_id, (*dev->dev_ops->rss_hash_index_get)(dev, hash,
+ hash_idx));
+}
+
+int
rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
struct rte_eth_udp_tunnel *udp_tunnel)
{
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d937fb4..8198130 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -3306,6 +3306,26 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
struct rte_eth_rss_conf *rss_conf);
/**
+ * Get hash index of the given hash value that received in mbuf from this port.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param hash
+ * The hash value used to compute hash_idx.
+ * @param hash_idx
+ * Where to store the computed hash_idx
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if port identifier is invalid.
+ * - (-EIO) if device is removed.
+ * - (-ENOTSUP) if hardware doesn't support RSS.
+ */
+__rte_experimental
+int
+rte_eth_dev_rss_hash_index_get(uint16_t port_id,
+ uint32_t hash, uint32_t *hash_idx);
+
+ /**
* Add UDP tunneling port for a specific type of tunnel.
* The packets with this UDP port will be identified as this type of tunnel.
* Before enabling any offloading function for a tunnel, users can call this API
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index dcb5ae6..ad6cdc5 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -364,6 +364,10 @@ typedef int (*rss_hash_conf_get_t)(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
/**< @internal Get current RSS hash configuration of an Ethernet device */
+typedef int (*rss_hash_index_get_t)(struct rte_eth_dev *dev,
+ uint32_t hash, uint32_t *hash_idx);
+/**< @internal Get RSS hash id of given hash value */
+
typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev);
/**< @internal Turn on SW controllable LED on an Ethernet device */
@@ -595,6 +599,7 @@ struct eth_dev_ops {
rss_hash_update_t rss_hash_update; /** Configure RSS hash protocols. */
rss_hash_conf_get_t rss_hash_conf_get; /** Get current RSS hash configuration. */
+ rss_hash_index_get_t rss_hash_index_get; /** Get RSS hash idx. */
reta_update_t reta_update; /** Update redirection table. */
reta_query_t reta_query; /** Query redirection table. */
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a4..ea6d1bf 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -283,4 +283,7 @@ EXPERIMENTAL {
# added in 19.08
rte_eth_read_clock;
+
+ # added in 19.11
+ rte_eth_dev_rss_hash_index_get;
};
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v2 2/3] app/test: add hash index verify autotest
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 0/3] " vattunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 1/3] lib/ethdev: " vattunuru
@ 2019-10-15 9:52 ` vattunuru
2019-10-15 16:49 ` Ferruh Yigit
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 3/3] net/octeontx2: add eth dev op callback to get hash index vattunuru
2 siblings, 1 reply; 15+ messages in thread
From: vattunuru @ 2019-10-15 9:52 UTC (permalink / raw)
To: dev; +Cc: arybchenko, jerinj, ferruh.yigit, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
Patch adds a autotest to validate rte_eth_dev_rss_hash_index_get()
ethdev op.
Test configures the ethport in loopback mode and enables RSS for
IP packets. The hash indices returned by those API gets validated
by matching queue number in the reta table with the rxq(queue's idx)
on which the packet received.
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
app/test/Makefile | 1 +
app/test/autotest_data.py | 6 +
app/test/meson.build | 1 +
app/test/test_hash_index.c | 347 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 355 insertions(+)
diff --git a/app/test/Makefile b/app/test/Makefile
index df7f77f..8674cfe 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -79,6 +79,7 @@ SRCS-y += test_rand_perf.c
SRCS-y += test_ring.c
SRCS-y += test_ring_perf.c
SRCS-y += test_pmd_perf.c
+SRCS-y += test_hash_index.c
ifeq ($(CONFIG_RTE_LIBRTE_TABLE),y)
SRCS-y += test_table.c
diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py
index 7405149..fef76d0 100644
--- a/app/test/autotest_data.py
+++ b/app/test/autotest_data.py
@@ -653,6 +653,12 @@
"Report": None,
},
{
+ "Name": "Hash index verify autotest",
+ "Command": "hash_index_verify_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
"Name": "Ring pmd perf autotest",
"Command": "ring_pmd_perf_autotest",
"Func": default_autotest,
diff --git a/app/test/meson.build b/app/test/meson.build
index 2c23c63..8eefe5e 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -85,6 +85,7 @@ test_sources = files('commands.c',
'test_mp_secondary.c',
'test_pdump.c',
'test_per_lcore.c',
+ 'test_hash_index.c',
'test_pmd_perf.c',
'test_pmd_ring.c',
'test_pmd_ring_perf.c',
diff --git a/app/test/test_hash_index.c b/app/test/test_hash_index.c
new file mode 100644
index 0000000..854404f
--- /dev/null
+++ b/app/test/test_hash_index.c
@@ -0,0 +1,347 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <unistd.h>
+#include <rte_cycles.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include "packet_burst_generator.h"
+#include "test.h"
+
+#define NB_ETHPORTS_USED 1
+#define MAX_PKT_BURST 32
+#define MAX_TRAFFIC_BURST 128
+#define MEMPOOL_CACHE_SIZE 32
+#define MAX_TEST_QUEUES_PER_PORT 4
+
+#define DEF_RETA_SIZE RTE_RETA_GROUP_SIZE
+
+#define NB_MBUF RTE_MAX( \
+ (uint32_t)(nb_ports*nb_rx_queue*nb_rxd + \
+ nb_ports*MAX_PKT_BURST + \
+ nb_ports*nb_tx_queue*nb_txd + \
+ 1*MEMPOOL_CACHE_SIZE + \
+ nb_ports*MAX_TRAFFIC_BURST), \
+ (uint32_t)4096)
+
+static struct rte_mempool *mbufpool;
+static struct rte_eth_rss_reta_entry64 reta_conf;
+
+static struct rte_eth_conf port_conf = {
+ .rxmode = {
+ .mq_mode = ETH_MQ_RX_RSS,
+ .max_rx_pkt_len = RTE_ETHER_MAX_LEN,
+ .split_hdr_size = 0,
+ },
+ .txmode = {
+ .mq_mode = ETH_MQ_TX_NONE,
+ },
+ .lpbk_mode = 1, /* enable loopback */
+ .rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP,
+};
+
+static struct rte_eth_rxconf rx_conf = {
+ .rx_free_thresh = 32,
+};
+
+static struct rte_eth_txconf tx_conf = {
+ .tx_free_thresh = 32, /* Use PMD default values */
+ .tx_rs_thresh = 32, /* Use PMD default values */
+};
+
+static uint64_t link_mbps;
+
+static void
+check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */
+ uint8_t count, all_ports_up, print_flag = 0;
+ struct rte_eth_link link;
+ uint16_t portid;
+
+ printf("Checking link statuses...\n");
+ 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 << portid)) == 0)
+ continue;
+ memset(&link, 0, sizeof(link));
+ rte_eth_link_get_nowait(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",
+ portid, link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ if (link_mbps == 0)
+ link_mbps = link.link_speed;
+ } else
+ printf("Port %d Link Down\n", 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) {
+ 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;
+ }
+}
+
+static inline void
+copy_buf_to_pkt(void *buf, uint32_t len, struct rte_mbuf *pkt, uint32_t offset)
+{
+ rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset), buf,
+ (size_t) len);
+}
+
+static int
+init_traffic(struct rte_mempool *mp,
+ struct rte_mbuf **pkts_burst, uint32_t burst_size)
+{
+ static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
+ static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
+ struct rte_ether_hdr pkt_eth_hdr;
+ struct rte_ipv4_hdr pkt_ipv4_hdr;
+ struct rte_udp_hdr pkt_udp_hdr;
+ struct rte_mbuf *pkt;
+ size_t eth_hdr_size;
+ uint32_t nb_pkt;
+
+ initialize_eth_header(&pkt_eth_hdr,
+ (struct rte_ether_addr *)src_mac,
+ (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0);
+
+ eth_hdr_size = sizeof(struct rte_ether_hdr);
+
+ initialize_udp_header(&pkt_udp_hdr, 0, 0, 18);
+
+ for (nb_pkt = 0; nb_pkt < burst_size; nb_pkt++) {
+ pkt = rte_pktmbuf_alloc(mp);
+ if (pkt == NULL)
+ break;
+
+ pkt->data_len = PACKET_BURST_GEN_PKT_LEN;
+
+ copy_buf_to_pkt(&pkt_eth_hdr, eth_hdr_size, pkt, 0);
+
+ initialize_ipv4_header(&pkt_ipv4_hdr,
+ IPV4_ADDR(10, 0, 0, 1) + nb_pkt,
+ IPV4_ADDR(10, 0, 0, 2), 26);
+
+ copy_buf_to_pkt(&pkt_ipv4_hdr, sizeof(struct rte_ipv4_hdr),
+ pkt, eth_hdr_size);
+ copy_buf_to_pkt(&pkt_udp_hdr, sizeof(struct rte_udp_hdr), pkt,
+ eth_hdr_size + sizeof(struct rte_ipv4_hdr));
+
+ pkt->pkt_len = PACKET_BURST_GEN_PKT_LEN;
+ pkt->l2_len = eth_hdr_size;
+ pkt->l3_len = sizeof(struct rte_ipv4_hdr);
+
+ pkts_burst[nb_pkt] = pkt;
+ }
+
+ return 0;
+}
+
+struct rte_mbuf **tx_burst;
+
+static int
+start_hash_index_verify(int portid)
+{
+ uint64_t end_cycles = rte_get_timer_hz() * 5; /* 5 Sec */
+ struct rte_mbuf *rx_burst[MAX_PKT_BURST];
+ uint32_t hash, hash_idx, count = 0, rxq;
+ uint32_t nb_rx = 0, nb_tx = 0;
+ int idx = 0, rc, mismatch = 0;
+ int num = MAX_TRAFFIC_BURST;
+ uint64_t start_cycles;
+
+ printf("inject %d packet to port %d\n", num, portid);
+ while (num) {
+ nb_tx = RTE_MIN(MAX_PKT_BURST, num);
+ nb_tx = rte_eth_tx_burst(portid, 0,
+ &tx_burst[idx], nb_tx);
+ num -= nb_tx;
+ idx += nb_tx;
+ }
+
+ printf("Total packets inject to port = %u\n", idx);
+
+ start_cycles = rte_get_timer_cycles();
+
+ while (count < MAX_TRAFFIC_BURST) {
+ for (rxq = 0 ; rxq < MAX_TEST_QUEUES_PER_PORT; rxq++) {
+ nb_rx = rte_eth_rx_burst(portid, rxq, rx_burst, 1);
+ if (nb_rx) {
+ hash = rx_burst[0]->hash.rss;
+ rc = rte_eth_dev_rss_hash_index_get(portid,
+ hash,
+ &hash_idx);
+ if (rc < 0)
+ hash_idx = hash % DEF_RETA_SIZE;
+
+ if (rxq != reta_conf.reta[hash_idx])
+ mismatch++;
+
+ rte_pktmbuf_free(rx_burst[0]);
+ count += nb_rx;
+ }
+ }
+ if (rte_get_timer_cycles() - start_cycles > end_cycles)
+ break;
+ }
+
+ printf("Total packets received = %u\n", count);
+
+ if (mismatch) {
+ printf("hash index mismatch in %d pkts\n", mismatch);
+ return -1;
+ }
+
+ printf("Hash index verified on %u pkts\n", count);
+
+ return 0;
+}
+
+static int
+test_hash_index(void)
+{
+ uint16_t nb_rx_queue = MAX_TEST_QUEUES_PER_PORT;
+ uint16_t nb_tx_queue = MAX_TEST_QUEUES_PER_PORT;
+ uint16_t reta_size = RTE_RETA_GROUP_SIZE;
+ uint16_t nb_rxd = MAX_TRAFFIC_BURST;
+ uint16_t nb_txd = MAX_TRAFFIC_BURST;
+ struct rte_eth_dev_info dev_info;
+ uint16_t portid = 0;
+ int socketid = -1;
+ uint16_t nb_ports;
+ int ret = 0;
+ uint16_t i;
+
+ printf("Start hash index verify test.\n");
+
+ nb_ports = rte_eth_dev_count_avail();
+ if (nb_ports < NB_ETHPORTS_USED) {
+ printf("At least %u port(s) used for the test\n",
+ NB_ETHPORTS_USED);
+ return -1;
+ }
+
+ nb_ports = NB_ETHPORTS_USED;
+
+ mbufpool = rte_pktmbuf_pool_create("pkt mempool", NB_MBUF,
+ MEMPOOL_CACHE_SIZE, 0,
+ RTE_MBUF_DEFAULT_BUF_SIZE, 0);
+ if (mbufpool == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot alloc mbuf pool\n");
+
+ rte_eth_dev_info_get(portid, &dev_info);
+
+ if (nb_rx_queue > dev_info.max_rx_queues)
+ nb_rx_queue = dev_info.max_rx_queues;
+
+ if (nb_tx_queue > dev_info.max_tx_queues)
+ nb_tx_queue = dev_info.max_tx_queues;
+
+ if (reta_size > dev_info.reta_size)
+ reta_size = dev_info.reta_size;
+
+ /* port configure */
+ ret = rte_eth_dev_configure(portid, nb_rx_queue,
+ nb_tx_queue, &port_conf);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "Cannot configure device: err=%d, port=%d\n",
+ ret, portid);
+
+ for (i = 0; i < nb_tx_queue; i++) {
+ /* tx queue setup */
+ ret = rte_eth_tx_queue_setup(portid, i, nb_txd,
+ socketid, &tx_conf);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "rte_eth_tx_queue_setup: err=%d, "
+ "port=%d\n", ret, portid);
+ }
+
+ for (i = 0; i < nb_rx_queue; i++) {
+ /* rx queue steup */
+ ret = rte_eth_rx_queue_setup(portid, i, nb_rxd,
+ socketid, &rx_conf, mbufpool);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
+ "port=%d\n", ret, portid);
+ }
+
+ for (i = 0; i < reta_size; i++) {
+ reta_conf.reta[i] = i % nb_rx_queue;
+ reta_conf.mask |= (1ULL << i);
+ }
+ rte_eth_dev_rss_reta_update(portid, &reta_conf, reta_size);
+
+ /* Start device */
+ ret = rte_eth_dev_start(portid);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "rte_eth_dev_start: err=%d, port=%d\n",
+ ret, portid);
+
+ /* always eanble promiscuous */
+ rte_eth_promiscuous_enable(portid);
+
+ check_all_ports_link_status(1, 1);
+
+ if (tx_burst == NULL) {
+ tx_burst = (struct rte_mbuf **)
+ rte_calloc_socket("tx_buff",
+ MAX_TRAFFIC_BURST * nb_ports,
+ sizeof(void *),
+ RTE_CACHE_LINE_SIZE, socketid);
+ if (!tx_burst)
+ return -1;
+ }
+
+ init_traffic(mbufpool,
+ tx_burst, MAX_TRAFFIC_BURST * nb_ports);
+
+ printf("Generate %d packets @socket %d\n",
+ MAX_TRAFFIC_BURST * nb_ports, socketid);
+
+ ret = start_hash_index_verify(portid);
+
+ /* port tear down */
+ rte_eth_dev_stop(portid);
+ rte_eth_dev_close(portid);
+
+ if (tx_burst)
+ rte_free(tx_burst);
+
+ if (mbufpool)
+ rte_mempool_free(mbufpool);
+
+ return ret;
+}
+
+REGISTER_TEST_COMMAND(hash_index_verify_autotest, test_hash_index);
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v2 3/3] net/octeontx2: add eth dev op callback to get hash index
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 0/3] " vattunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 1/3] lib/ethdev: " vattunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 2/3] app/test: add hash index verify autotest vattunuru
@ 2019-10-15 9:52 ` vattunuru
2 siblings, 0 replies; 15+ messages in thread
From: vattunuru @ 2019-10-15 9:52 UTC (permalink / raw)
To: dev; +Cc: arybchenko, jerinj, ferruh.yigit, thomas, Vamsi Attunuru
From: Vamsi Attunuru <vattunuru@marvell.com>
patch adds pmd support for hash_index_get() ethdev_op callback.
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
drivers/net/octeontx2/otx2_ethdev.c | 1 +
drivers/net/octeontx2/otx2_ethdev.h | 3 +++
| 18 ++++++++++++++++++
3 files changed, 22 insertions(+)
diff --git a/drivers/net/octeontx2/otx2_ethdev.c b/drivers/net/octeontx2/otx2_ethdev.c
index 4a60f9f..eb41ba4 100644
--- a/drivers/net/octeontx2/otx2_ethdev.c
+++ b/drivers/net/octeontx2/otx2_ethdev.c
@@ -1961,6 +1961,7 @@ static const struct eth_dev_ops otx2_eth_dev_ops = {
.reta_query = otx2_nix_dev_reta_query,
.rss_hash_update = otx2_nix_rss_hash_update,
.rss_hash_conf_get = otx2_nix_rss_hash_conf_get,
+ .rss_hash_index_get = otx2_nix_rss_hash_index_get,
.xstats_get = otx2_nix_xstats_get,
.xstats_get_names = otx2_nix_xstats_get_names,
.xstats_reset = otx2_nix_xstats_reset,
diff --git a/drivers/net/octeontx2/otx2_ethdev.h b/drivers/net/octeontx2/otx2_ethdev.h
index 33fa0c6..b410988 100644
--- a/drivers/net/octeontx2/otx2_ethdev.h
+++ b/drivers/net/octeontx2/otx2_ethdev.h
@@ -471,6 +471,9 @@ int otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
int otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
struct rte_eth_rss_conf *rss_conf);
+int otx2_nix_rss_hash_index_get(struct rte_eth_dev *eth_dev,
+ uint32_t hash, uint32_t *hash_idx);
+
/* CGX */
int otx2_cgx_rxtx_start(struct otx2_eth_dev *dev);
int otx2_cgx_rxtx_stop(struct otx2_eth_dev *dev);
--git a/drivers/net/octeontx2/otx2_rss.c b/drivers/net/octeontx2/otx2_rss.c
index 5afa214..4b40dfd 100644
--- a/drivers/net/octeontx2/otx2_rss.c
+++ b/drivers/net/octeontx2/otx2_rss.c
@@ -328,6 +328,24 @@ otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
}
int
+otx2_nix_rss_hash_index_get(struct rte_eth_dev *eth_dev,
+ uint32_t hash, uint32_t *hash_idx)
+{
+ struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+ union flow_tag {
+ uint32_t hash;
+ uint8_t byte[4];
+ } tag;
+
+ tag.hash = hash;
+
+ *hash_idx = (tag.byte[0] ^ tag.byte[1] ^ tag.byte[2] ^ tag.byte[3]) %
+ dev->rss_info.rss_size;
+
+ return 0;
+}
+
+int
otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
{
struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
--
2.8.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/3] lib/ethdev: add ethdev op to get hash index
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 1/3] lib/ethdev: " vattunuru
@ 2019-10-15 16:47 ` Ferruh Yigit
2019-10-15 17:28 ` Vamsi Krishna Attunuru
2019-10-16 17:48 ` Ferruh Yigit
1 sibling, 1 reply; 15+ messages in thread
From: Ferruh Yigit @ 2019-10-15 16:47 UTC (permalink / raw)
To: vattunuru, dev; +Cc: arybchenko, jerinj, thomas
On 10/15/2019 10:52 AM, vattunuru@marvell.com wrote:
> From: Vamsi Attunuru <vattunuru@marvell.com>
>
> Some networking devices may use custom algos for computing
> hash indices and spread the packets accordingly.
>
> Patch adds an eth_dev op to get the hash index correspond
> to the given hash value received in the initial packet on
> the given port.
>
> Some of the applications compute hash index from the hash
> value received in the initial packet and than configure
> the rxq to lcore mapping to make sure the mapped lcore/rxq
> would receive the upcoming traffic that has similar hash.
> Such applications may use these API to get the hash index
> used by the PMD for spreading those traffic.
Hi Vamsi,
Can you please describe this usecase?
If the application is receiving the packet, it already knows which queue it is
coming from, what is the benefit of the getting hash index?
The concern is adding a new API which is specific to a use case and HW and won't
be used in long term. That will only create technical dept for us.
>
> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
<...>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH v2 2/3] app/test: add hash index verify autotest
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 2/3] app/test: add hash index verify autotest vattunuru
@ 2019-10-15 16:49 ` Ferruh Yigit
0 siblings, 0 replies; 15+ messages in thread
From: Ferruh Yigit @ 2019-10-15 16:49 UTC (permalink / raw)
To: vattunuru, dev; +Cc: arybchenko, jerinj, thomas
On 10/15/2019 10:52 AM, vattunuru@marvell.com wrote:
> From: Vamsi Attunuru <vattunuru@marvell.com>
>
> Patch adds a autotest to validate rte_eth_dev_rss_hash_index_get()
> ethdev op.
>
> Test configures the ethport in loopback mode and enables RSS for
> IP packets. The hash indices returned by those API gets validated
> by matching queue number in the reta table with the rxq(queue's idx)
> on which the packet received.
As I said implementation is not major concern, so please wait until ethdev API
discussion resolved before modifying but unit test failing me for i40e because of:
1) RSS hash function selected without checking what device is capable of, so
configuration fails.
2) rte_eth_dev_rss_reta_update() failed because of provided incompatible size
Thanks,
ferruh
>
> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
<...>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/3] lib/ethdev: add ethdev op to get hash index
2019-10-15 16:47 ` Ferruh Yigit
@ 2019-10-15 17:28 ` Vamsi Krishna Attunuru
2019-10-16 17:47 ` Ferruh Yigit
0 siblings, 1 reply; 15+ messages in thread
From: Vamsi Krishna Attunuru @ 2019-10-15 17:28 UTC (permalink / raw)
To: Ferruh Yigit, dev; +Cc: arybchenko, Jerin Jacob Kollanukkaran, thomas
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Ferruh Yigit
> Sent: Tuesday, October 15, 2019 10:17 PM
> To: Vamsi Krishna Attunuru <vattunuru@marvell.com>; dev@dpdk.org
> Cc: arybchenko@solarflare.com; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; thomas@monjalon.net
> Subject: Re: [dpdk-dev] [PATCH v2 1/3] lib/ethdev: add ethdev op to get hash
> index
>
> On 10/15/2019 10:52 AM, vattunuru@marvell.com wrote:
> > From: Vamsi Attunuru <vattunuru@marvell.com>
> >
> > Some networking devices may use custom algos for computing hash
> > indices and spread the packets accordingly.
> >
> > Patch adds an eth_dev op to get the hash index correspond to the given
> > hash value received in the initial packet on the given port.
> >
> > Some of the applications compute hash index from the hash value
> > received in the initial packet and than configure the rxq to lcore
> > mapping to make sure the mapped lcore/rxq would receive the upcoming
> > traffic that has similar hash.
> > Such applications may use these API to get the hash index used by the
> > PMD for spreading those traffic.
>
> Hi Vamsi,
>
> Can you please describe this usecase?
> If the application is receiving the packet, it already knows which queue it is
> coming from, what is the benefit of the getting hash index?
Hi Ferruh,
I think the commit msg is incomplete and did not explain the use case clearly, my apologies.
Actual usecase is when application precalculates the hash value using some hashlib for a specific type of packet headers with the same hash key that's configured in the HW, application would compute hash_index as hash % reta_size and predict the packets on the computed queue index. But these hash_index computation might be different from PMD/HW computed index(based it's algo design). To fix those disparity, these API been introduced which can be used during configuration time to have
required lcore-rq mapping.
>
> The concern is adding a new API which is specific to a use case and HW and
> won't be used in long term. That will only create technical dept for us.
>
> >
> > Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
>
> <...>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/3] lib/ethdev: add ethdev op to get hash index
2019-10-15 17:28 ` Vamsi Krishna Attunuru
@ 2019-10-16 17:47 ` Ferruh Yigit
0 siblings, 0 replies; 15+ messages in thread
From: Ferruh Yigit @ 2019-10-16 17:47 UTC (permalink / raw)
To: Vamsi Krishna Attunuru, dev; +Cc: arybchenko, Jerin Jacob Kollanukkaran, thomas
On 10/15/2019 6:28 PM, Vamsi Krishna Attunuru wrote:
>
>
>> -----Original Message-----
>> From: dev <dev-bounces@dpdk.org> On Behalf Of Ferruh Yigit
>> Sent: Tuesday, October 15, 2019 10:17 PM
>> To: Vamsi Krishna Attunuru <vattunuru@marvell.com>; dev@dpdk.org
>> Cc: arybchenko@solarflare.com; Jerin Jacob Kollanukkaran
>> <jerinj@marvell.com>; thomas@monjalon.net
>> Subject: Re: [dpdk-dev] [PATCH v2 1/3] lib/ethdev: add ethdev op to get hash
>> index
>>
>> On 10/15/2019 10:52 AM, vattunuru@marvell.com wrote:
>>> From: Vamsi Attunuru <vattunuru@marvell.com>
>>>
>>> Some networking devices may use custom algos for computing hash
>>> indices and spread the packets accordingly.
>>>
>>> Patch adds an eth_dev op to get the hash index correspond to the given
>>> hash value received in the initial packet on the given port.
>>>
>>> Some of the applications compute hash index from the hash value
>>> received in the initial packet and than configure the rxq to lcore
>>> mapping to make sure the mapped lcore/rxq would receive the upcoming
>>> traffic that has similar hash.
>>> Such applications may use these API to get the hash index used by the
>>> PMD for spreading those traffic.
>>
>> Hi Vamsi,
>>
>> Can you please describe this usecase?
>> If the application is receiving the packet, it already knows which queue it is
>> coming from, what is the benefit of the getting hash index?
>
> Hi Ferruh,
>
> I think the commit msg is incomplete and did not explain the use case clearly, my apologies.
> Actual usecase is when application precalculates the hash value using some hashlib for a specific type of packet headers with the same hash key that's configured in the HW, application would compute hash_index as hash % reta_size and predict the packets on the computed queue index. But these hash_index computation might be different from PMD/HW computed index(based it's algo design). To fix those disparity, these API been introduced which can be used during configuration time to have
> required lcore-rq mapping.
Does application tries to predict in which queue a specific flow will land? And
configure RETA table OR do the lcore-queue mapping accordingly?
Not sure if other PMDs need this too but API seems trivial and it doesn't affect
existing code, so no objection from my end for the API. Can you please check the
unit test comments?
>
>
>>
>> The concern is adding a new API which is specific to a use case and HW and
>> won't be used in long term. That will only create technical dept for us.
>>
>>>
>>> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
>>
>> <...>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/3] lib/ethdev: add ethdev op to get hash index
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 1/3] lib/ethdev: " vattunuru
2019-10-15 16:47 ` Ferruh Yigit
@ 2019-10-16 17:48 ` Ferruh Yigit
1 sibling, 0 replies; 15+ messages in thread
From: Ferruh Yigit @ 2019-10-16 17:48 UTC (permalink / raw)
To: vattunuru, dev; +Cc: arybchenko, jerinj, thomas
On 10/15/2019 10:52 AM, vattunuru@marvell.com wrote:
> From: Vamsi Attunuru <vattunuru@marvell.com>
>
> Some networking devices may use custom algos for computing
> hash indices and spread the packets accordingly.
>
> Patch adds an eth_dev op to get the hash index correspond
> to the given hash value received in the initial packet on
> the given port.
>
> Some of the applications compute hash index from the hash
> value received in the initial packet and than configure
> the rxq to lcore mapping to make sure the mapped lcore/rxq
> would receive the upcoming traffic that has similar hash.
> Such applications may use these API to get the hash index
> used by the PMD for spreading those traffic.
>
> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
<...>
> @@ -364,6 +364,10 @@ typedef int (*rss_hash_conf_get_t)(struct rte_eth_dev *dev,
> struct rte_eth_rss_conf *rss_conf);
> /**< @internal Get current RSS hash configuration of an Ethernet device */
>
> +typedef int (*rss_hash_index_get_t)(struct rte_eth_dev *dev,
> + uint32_t hash, uint32_t *hash_idx);
> +/**< @internal Get RSS hash id of given hash value */
s/hash id/hash index/ ?
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2019-10-16 17:48 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-14 5:52 [dpdk-dev] [PATCH v1 0/3] add ethdev op to get hash index vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 1/3] lib/ethdev: " vattunuru
2019-10-03 13:00 ` Andrew Rybchenko
2019-10-07 4:45 ` [dpdk-dev] [EXT] " Vamsi Krishna Attunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 0/3] " vattunuru
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 1/3] lib/ethdev: " vattunuru
2019-10-15 16:47 ` Ferruh Yigit
2019-10-15 17:28 ` Vamsi Krishna Attunuru
2019-10-16 17:47 ` Ferruh Yigit
2019-10-16 17:48 ` Ferruh Yigit
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 2/3] app/test: add hash index verify autotest vattunuru
2019-10-15 16:49 ` Ferruh Yigit
2019-10-15 9:52 ` [dpdk-dev] [PATCH v2 3/3] net/octeontx2: add eth dev op callback to get hash index vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 2/3] app/test: add hash index verify autotest vattunuru
2019-09-14 5:52 ` [dpdk-dev] [PATCH v1 3/3] net/octeontx2: add eth dev op callback to get hash index vattunuru
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).