DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] net/dpdkoin: add new driver
@ 2020-04-01 13:10 Matteo Croce
  2020-04-01 13:33 ` Ferruh Yigit
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Matteo Croce @ 2020-04-01 13:10 UTC (permalink / raw)
  To: dev; +Cc: stable

DPDK polls the packet in a busy loop. This means that CPU constantly spins
looking for packets, regardless of the network traffic.
DPDK does this to reduce latency and avoid using interrupts, at expense of
efficiency: this might consume more processing power and generate more heat
than needed, potentially increasing the TCO of a DPDK appliance.

Here comes DPDKoin. DPDKoin is a DPDK PMD, which instead of moving
packets, mines cryptocurrencies.
DPDKoin just does a few calculations to every poll cycle, this means that
when the network is loaded, DPDKoin consumes just a few cycles, but when
there is no traffic, DPDKoin mines currencies in a busy loop.
The coins are mined with no extra consumption, as the CPU would spin
anyway.

This is a system running with two 10G cards running with DPDK:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 8223 root      10 -10  260.6g 597516  19100 S 199.8   0.5   0:17.89 testpmd

And this is the same system with a DPDKoin port added:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 9438 root      10 -10  260.6g 598892  19800 S 199.8   0.5   0:19.43 testpmd

As you can see, we don't observe any change in the CPU usage, and besides,
the earned coins lowers the appliance TCO.

Just for reference, a test run log follows:

$ sudo testpmd --no-huge -m 1024 --no-pci --vdev eth_dpdkoin0 --vdev eth_dpdkoin1
EAL: Detected 8 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probing VFIO support...
testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n=203456, size=2176, socket=0
testpmd: preferred mempool ops selected: ring_mp_mc
Configuring Port 0 (socket 0)
Port 0: 4A:50:3C:33:55:21
Configuring Port 1 (socket 0)
Port 1: BA:BB:0A:BB:0C:CA
Checking link statuses...
Done
No commandline core given, start packet forwarding
io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native
Logical Core 1 (socket 0) forwards packets on 2 streams:
  RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
  RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00

  io packet forwarding packets/burst=32
  nb forwarding cores=1 - nb forwarding ports=2
  port 0: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x0 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 1: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x0 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
libbitcoin 0.1: mining on CPU2
libbitcoin 0.1: mining on CPU4
---
 config/common_base                            |   5 +
 drivers/net/Makefile                          |   1 +
 drivers/net/dpdkoin/Makefile                  |  23 +
 drivers/net/dpdkoin/meson.build               |   3 +
 drivers/net/dpdkoin/rte_eth_dpdkoin.c         | 696 ++++++++++++++++++
 .../net/dpdkoin/rte_pmd_dpdkoin_version.map   |   3 +
 mk/rte.app.mk                                 |   1 +
 7 files changed, 732 insertions(+)
 create mode 100644 drivers/net/dpdkoin/Makefile
 create mode 100644 drivers/net/dpdkoin/meson.build
 create mode 100644 drivers/net/dpdkoin/rte_eth_dpdkoin.c
 create mode 100644 drivers/net/dpdkoin/rte_pmd_dpdkoin_version.map

diff --git a/config/common_base b/config/common_base
index c31175f9d..fafa23006 100644
--- a/config/common_base
+++ b/config/common_base
@@ -1055,6 +1055,11 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 #
 CONFIG_RTE_LIBRTE_PMD_VHOST=n
 
+#
+# Compile DPDKOIN
+#
+CONFIG_RTE_LIBRTE_PMD_DPDKOIN=y
+
 #
 # Compile IFC driver
 # To compile, CONFIG_RTE_LIBRTE_VHOST and CONFIG_RTE_EAL_VFIO
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 4a7f155fc..a7c5d5dbc 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -23,6 +23,7 @@ endif
 ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
 DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
 endif
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPDKOIN) += dpdkoin
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
 DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
 DIRS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc
diff --git a/drivers/net/dpdkoin/Makefile b/drivers/net/dpdkoin/Makefile
new file mode 100644
index 000000000..a8c66f3b2
--- /dev/null
+++ b/drivers/net/dpdkoin/Makefile
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: BSD-3-Clause
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpdkoin.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_vdev
+
+EXPORT_MAP := rte_pmd_dpdkoin_version.map
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPDKOIN) += rte_eth_dpdkoin.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpdkoin/meson.build b/drivers/net/dpdkoin/meson.build
new file mode 100644
index 000000000..d64f980aa
--- /dev/null
+++ b/drivers/net/dpdkoin/meson.build
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: BSD-3-Clause
+
+sources = files('rte_eth_dpdkoin.c')
diff --git a/drivers/net/dpdkoin/rte_eth_dpdkoin.c b/drivers/net/dpdkoin/rte_eth_dpdkoin.c
new file mode 100644
index 000000000..e46e50e6a
--- /dev/null
+++ b/drivers/net/dpdkoin/rte_eth_dpdkoin.c
@@ -0,0 +1,696 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <rte_mbuf.h>
+#include <rte_ethdev_driver.h>
+#include <rte_ethdev_vdev.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_bus_vdev.h>
+#include <rte_kvargs.h>
+#include <rte_spinlock.h>
+#include <bitcoin.h>
+
+#define ETH_DPDKOIN_PACKET_SIZE_ARG	"size"
+#define ETH_DPDKOIN_PACKET_COPY_ARG	"copy"
+
+static unsigned default_packet_size = 64;
+static unsigned default_packet_copy;
+
+static struct bitcoin bc;
+
+static const char *valid_arguments[] = {
+	ETH_DPDKOIN_PACKET_SIZE_ARG,
+	ETH_DPDKOIN_PACKET_COPY_ARG,
+	NULL
+};
+
+struct pmd_internals;
+
+struct dpdkoin_queue {
+	struct pmd_internals *internals;
+
+	struct rte_mempool *mb_pool;
+	struct rte_mbuf *dummy_packet;
+
+	rte_atomic64_t rx_pkts;
+	rte_atomic64_t tx_pkts;
+};
+
+struct pmd_internals {
+	unsigned packet_size;
+	unsigned packet_copy;
+	uint16_t port_id;
+
+	struct dpdkoin_queue rx_dpdkoin_queues[RTE_MAX_QUEUES_PER_PORT];
+	struct dpdkoin_queue tx_dpdkoin_queues[RTE_MAX_QUEUES_PER_PORT];
+
+	struct rte_ether_addr eth_addr;
+	/** Bit mask of RSS offloads, the bit offset also means flow type */
+	uint64_t flow_type_rss_offloads;
+
+	rte_spinlock_t rss_lock;
+
+	uint16_t reta_size;
+	struct rte_eth_rss_reta_entry64 reta_conf[ETH_RSS_RETA_SIZE_128 /
+			RTE_RETA_GROUP_SIZE];
+
+	uint8_t rss_key[40];                /**< 40-byte hash key. */
+};
+static struct rte_eth_link pmd_link = {
+	.link_speed = ETH_SPEED_NUM_10G,
+	.link_duplex = ETH_LINK_FULL_DUPLEX,
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_FIXED,
+};
+
+static int eth_dpdkoin_logtype;
+
+#define PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, eth_dpdkoin_logtype, \
+		"%s(): " fmt "\n", __func__, ##args)
+
+static uint16_t
+eth_dpdkoin_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
+{
+	int i;
+	struct dpdkoin_queue *h = q;
+	unsigned packet_size;
+
+	if ((q == NULL) || (bufs == NULL))
+		return 0;
+
+	packet_size = h->internals->packet_size;
+	if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) != 0)
+		return 0;
+
+	for (i = 0; i < nb_bufs; i++) {
+		bufs[i]->data_len = (uint16_t)packet_size;
+		bufs[i]->pkt_len = packet_size;
+		bufs[i]->port = h->internals->port_id;
+	}
+
+	rte_atomic64_add(&(h->rx_pkts), i);
+
+	bitcoin_mine(&bc);
+
+	return i;
+}
+
+static uint16_t
+eth_dpdkoin_copy_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
+{
+	int i;
+	struct dpdkoin_queue *h = q;
+	unsigned packet_size;
+
+	if ((q == NULL) || (bufs == NULL))
+		return 0;
+
+	packet_size = h->internals->packet_size;
+	if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) != 0)
+		return 0;
+
+	for (i = 0; i < nb_bufs; i++) {
+		rte_memcpy(rte_pktmbuf_mtod(bufs[i], void *), h->dummy_packet,
+					packet_size);
+		bufs[i]->data_len = (uint16_t)packet_size;
+		bufs[i]->pkt_len = packet_size;
+		bufs[i]->port = h->internals->port_id;
+	}
+
+	rte_atomic64_add(&(h->rx_pkts), i);
+
+	bitcoin_mine(&bc);
+
+	return i;
+}
+
+static uint16_t
+eth_dpdkoin_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
+{
+	int i;
+	struct dpdkoin_queue *h = q;
+
+	if ((q == NULL) || (bufs == NULL))
+		return 0;
+
+	for (i = 0; i < nb_bufs; i++)
+		rte_pktmbuf_free(bufs[i]);
+
+	rte_atomic64_add(&(h->tx_pkts), i);
+
+	bitcoin_mine(&bc);
+
+	return i;
+}
+
+static uint16_t
+eth_dpdkoin_copy_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
+{
+	int i;
+	struct dpdkoin_queue *h = q;
+	unsigned packet_size;
+
+	if ((q == NULL) || (bufs == NULL))
+		return 0;
+
+	packet_size = h->internals->packet_size;
+	for (i = 0; i < nb_bufs; i++) {
+		rte_memcpy(h->dummy_packet, rte_pktmbuf_mtod(bufs[i], void *),
+					packet_size);
+		rte_pktmbuf_free(bufs[i]);
+	}
+
+	rte_atomic64_add(&(h->tx_pkts), i);
+
+	bitcoin_mine(&bc);
+
+	return i;
+}
+
+static int
+eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
+{
+	return 0;
+}
+
+static int
+eth_dev_start(struct rte_eth_dev *dev)
+{
+	if (dev == NULL)
+		return -EINVAL;
+
+	dev->data->dev_link.link_status = ETH_LINK_UP;
+	return 0;
+}
+
+static void
+eth_dev_stop(struct rte_eth_dev *dev)
+{
+	if (dev == NULL)
+		return;
+
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	bitcoin_free(&bc);
+}
+
+static int
+eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+		uint16_t nb_rx_desc __rte_unused,
+		unsigned int socket_id __rte_unused,
+		const struct rte_eth_rxconf *rx_conf __rte_unused,
+		struct rte_mempool *mb_pool)
+{
+	struct rte_mbuf *dummy_packet;
+	struct pmd_internals *internals;
+	unsigned packet_size;
+
+	if ((dev == NULL) || (mb_pool == NULL))
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+
+	if (rx_queue_id >= dev->data->nb_rx_queues)
+		return -ENODEV;
+
+	packet_size = internals->packet_size;
+
+	internals->rx_dpdkoin_queues[rx_queue_id].mb_pool = mb_pool;
+	dev->data->rx_queues[rx_queue_id] =
+		&internals->rx_dpdkoin_queues[rx_queue_id];
+	dummy_packet = rte_zmalloc_socket(NULL,
+			packet_size, 0, dev->data->numa_node);
+	if (dummy_packet == NULL)
+		return -ENOMEM;
+
+	internals->rx_dpdkoin_queues[rx_queue_id].internals = internals;
+	internals->rx_dpdkoin_queues[rx_queue_id].dummy_packet = dummy_packet;
+
+	return 0;
+}
+
+static int
+eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+		uint16_t nb_tx_desc __rte_unused,
+		unsigned int socket_id __rte_unused,
+		const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+	struct rte_mbuf *dummy_packet;
+	struct pmd_internals *internals;
+	unsigned packet_size;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+
+	if (tx_queue_id >= dev->data->nb_tx_queues)
+		return -ENODEV;
+
+	packet_size = internals->packet_size;
+
+	dev->data->tx_queues[tx_queue_id] =
+		&internals->tx_dpdkoin_queues[tx_queue_id];
+	dummy_packet = rte_zmalloc_socket(NULL,
+			packet_size, 0, dev->data->numa_node);
+	if (dummy_packet == NULL)
+		return -ENOMEM;
+
+	internals->tx_dpdkoin_queues[tx_queue_id].internals = internals;
+	internals->tx_dpdkoin_queues[tx_queue_id].dummy_packet = dummy_packet;
+
+	return 0;
+}
+
+static int
+eth_mtu_set(struct rte_eth_dev *dev __rte_unused, uint16_t mtu __rte_unused)
+{
+	return 0;
+}
+
+static int
+eth_dev_info(struct rte_eth_dev *dev,
+		struct rte_eth_dev_info *dev_info)
+{
+	struct pmd_internals *internals;
+
+	if ((dev == NULL) || (dev_info == NULL))
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	dev_info->max_mac_addrs = 1;
+	dev_info->max_rx_pktlen = (uint32_t)-1;
+	dev_info->max_rx_queues = RTE_DIM(internals->rx_dpdkoin_queues);
+	dev_info->max_tx_queues = RTE_DIM(internals->tx_dpdkoin_queues);
+	dev_info->min_rx_bufsize = 0;
+	dev_info->reta_size = internals->reta_size;
+	dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads;
+
+	return 0;
+}
+
+static int
+eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats)
+{
+	unsigned i, num_stats;
+	unsigned long rx_total = 0, tx_total = 0;
+	const struct pmd_internals *internal;
+
+	if ((dev == NULL) || (igb_stats == NULL))
+		return -EINVAL;
+
+	internal = dev->data->dev_private;
+	num_stats = RTE_MIN((unsigned)RTE_ETHDEV_QUEUE_STAT_CNTRS,
+			RTE_MIN(dev->data->nb_rx_queues,
+				RTE_DIM(internal->rx_dpdkoin_queues)));
+	for (i = 0; i < num_stats; i++) {
+		igb_stats->q_ipackets[i] =
+			internal->rx_dpdkoin_queues[i].rx_pkts.cnt;
+		rx_total += igb_stats->q_ipackets[i];
+	}
+
+	num_stats = RTE_MIN((unsigned)RTE_ETHDEV_QUEUE_STAT_CNTRS,
+			RTE_MIN(dev->data->nb_tx_queues,
+				RTE_DIM(internal->tx_dpdkoin_queues)));
+	for (i = 0; i < num_stats; i++) {
+		igb_stats->q_opackets[i] =
+			internal->tx_dpdkoin_queues[i].tx_pkts.cnt;
+		tx_total += igb_stats->q_opackets[i];
+	}
+
+	igb_stats->ipackets = rx_total;
+	igb_stats->opackets = tx_total;
+
+	return 0;
+}
+
+static int
+eth_stats_reset(struct rte_eth_dev *dev)
+{
+	unsigned i;
+	struct pmd_internals *internal;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	internal = dev->data->dev_private;
+	for (i = 0; i < RTE_DIM(internal->rx_dpdkoin_queues); i++)
+		internal->rx_dpdkoin_queues[i].rx_pkts.cnt = 0;
+	for (i = 0; i < RTE_DIM(internal->tx_dpdkoin_queues); i++)
+		internal->tx_dpdkoin_queues[i].tx_pkts.cnt = 0;
+
+	return 0;
+}
+
+static void
+eth_queue_release(void *q)
+{
+	struct dpdkoin_queue *nq;
+
+	if (q == NULL)
+		return;
+
+	nq = q;
+	rte_free(nq->dummy_packet);
+}
+
+static int
+eth_link_update(struct rte_eth_dev *dev __rte_unused,
+		int wait_to_complete __rte_unused) { return 0; }
+
+static int
+eth_rss_reta_update(struct rte_eth_dev *dev,
+		struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
+{
+	int i, j;
+	struct pmd_internals *internal = dev->data->dev_private;
+
+	if (reta_size != internal->reta_size)
+		return -EINVAL;
+
+	rte_spinlock_lock(&internal->rss_lock);
+
+	/* Copy RETA table */
+	for (i = 0; i < (internal->reta_size / RTE_RETA_GROUP_SIZE); i++) {
+		internal->reta_conf[i].mask = reta_conf[i].mask;
+		for (j = 0; j < RTE_RETA_GROUP_SIZE; j++)
+			if ((reta_conf[i].mask >> j) & 0x01)
+				internal->reta_conf[i].reta[j] = reta_conf[i].reta[j];
+	}
+
+	rte_spinlock_unlock(&internal->rss_lock);
+
+	return 0;
+}
+
+static int
+eth_rss_reta_query(struct rte_eth_dev *dev,
+		struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
+{
+	int i, j;
+	struct pmd_internals *internal = dev->data->dev_private;
+
+	if (reta_size != internal->reta_size)
+		return -EINVAL;
+
+	rte_spinlock_lock(&internal->rss_lock);
+
+	/* Copy RETA table */
+	for (i = 0; i < (internal->reta_size / RTE_RETA_GROUP_SIZE); i++) {
+		for (j = 0; j < RTE_RETA_GROUP_SIZE; j++)
+			if ((reta_conf[i].mask >> j) & 0x01)
+				reta_conf[i].reta[j] = internal->reta_conf[i].reta[j];
+	}
+
+	rte_spinlock_unlock(&internal->rss_lock);
+
+	return 0;
+}
+
+static int
+eth_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf)
+{
+	struct pmd_internals *internal = dev->data->dev_private;
+
+	rte_spinlock_lock(&internal->rss_lock);
+
+	if ((rss_conf->rss_hf & internal->flow_type_rss_offloads) != 0)
+		dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
+				rss_conf->rss_hf & internal->flow_type_rss_offloads;
+
+	if (rss_conf->rss_key)
+		rte_memcpy(internal->rss_key, rss_conf->rss_key, 40);
+
+	rte_spinlock_unlock(&internal->rss_lock);
+
+	return 0;
+}
+
+static int
+eth_rss_hash_conf_get(struct rte_eth_dev *dev,
+		struct rte_eth_rss_conf *rss_conf)
+{
+	struct pmd_internals *internal = dev->data->dev_private;
+
+	rte_spinlock_lock(&internal->rss_lock);
+
+	rss_conf->rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
+	if (rss_conf->rss_key)
+		rte_memcpy(rss_conf->rss_key, internal->rss_key, 40);
+
+	rte_spinlock_unlock(&internal->rss_lock);
+
+	return 0;
+}
+
+static int
+eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
+		    __rte_unused struct rte_ether_addr *addr)
+{
+	return 0;
+}
+
+static const struct eth_dev_ops ops = {
+	.dev_start = eth_dev_start,
+	.dev_stop = eth_dev_stop,
+	.dev_configure = eth_dev_configure,
+	.dev_infos_get = eth_dev_info,
+	.rx_queue_setup = eth_rx_queue_setup,
+	.tx_queue_setup = eth_tx_queue_setup,
+	.rx_queue_release = eth_queue_release,
+	.tx_queue_release = eth_queue_release,
+	.mtu_set = eth_mtu_set,
+	.link_update = eth_link_update,
+	.mac_addr_set = eth_mac_address_set,
+	.stats_get = eth_stats_get,
+	.stats_reset = eth_stats_reset,
+	.reta_update = eth_rss_reta_update,
+	.reta_query = eth_rss_reta_query,
+	.rss_hash_update = eth_rss_hash_update,
+	.rss_hash_conf_get = eth_rss_hash_conf_get
+};
+
+static int
+eth_dev_dpdkoin_create(struct rte_vdev_device *dev,
+		unsigned packet_size,
+		unsigned packet_copy)
+{
+	const unsigned nb_rx_queues = 1;
+	const unsigned nb_tx_queues = 1;
+	struct rte_eth_dev_data *data;
+	struct pmd_internals *internals = NULL;
+	struct rte_eth_dev *eth_dev = NULL;
+
+	static const uint8_t default_rss_key[40] = {
+		0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 0x41, 0x67, 0x25, 0x3D,
+		0x43, 0xA3, 0x8F, 0xB0, 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
+		0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 0x6A, 0x42, 0xB7, 0x3B,
+		0xBE, 0xAC, 0x01, 0xFA
+	};
+
+	if (dev->device.numa_node == SOCKET_ID_ANY)
+		dev->device.numa_node = rte_socket_id();
+
+	PMD_LOG(INFO, "Creating dpdkoin ethdev on numa socket %u",
+		dev->device.numa_node);
+
+	eth_dev = rte_eth_vdev_allocate(dev, sizeof(*internals));
+	if (!eth_dev)
+		return -ENOMEM;
+
+	/* now put it all together
+	 * - store queue data in internals,
+	 * - store numa_node info in ethdev data
+	 * - point eth_dev_data to internals
+	 * - and point eth_dev structure to new eth_dev_data structure
+	 */
+	/* NOTE: we'll replace the data element, of originally allocated eth_dev
+	 * so the dpdkoins are local per-process */
+
+	internals = eth_dev->data->dev_private;
+	internals->packet_size = packet_size;
+	internals->packet_copy = packet_copy;
+	internals->port_id = eth_dev->data->port_id;
+	rte_eth_random_addr(internals->eth_addr.addr_bytes);
+
+	internals->flow_type_rss_offloads =  ETH_RSS_PROTO_MASK;
+	internals->reta_size = RTE_DIM(internals->reta_conf) * RTE_RETA_GROUP_SIZE;
+
+	rte_memcpy(internals->rss_key, default_rss_key, 40);
+
+	data = eth_dev->data;
+	data->nb_rx_queues = (uint16_t)nb_rx_queues;
+	data->nb_tx_queues = (uint16_t)nb_tx_queues;
+	data->dev_link = pmd_link;
+	data->mac_addrs = &internals->eth_addr;
+	data->promiscuous = 1;
+	data->all_multicast = 1;
+
+	eth_dev->dev_ops = &ops;
+
+	/* finally assign rx and tx ops */
+	if (packet_copy) {
+		eth_dev->rx_pkt_burst = eth_dpdkoin_copy_rx;
+		eth_dev->tx_pkt_burst = eth_dpdkoin_copy_tx;
+	} else {
+		eth_dev->rx_pkt_burst = eth_dpdkoin_rx;
+		eth_dev->tx_pkt_burst = eth_dpdkoin_tx;
+	}
+
+	rte_eth_dev_probing_finish(eth_dev);
+
+	bitcoin_init(&bc);
+
+	return 0;
+}
+
+static inline int
+get_packet_size_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	const char *a = value;
+	unsigned *packet_size = extra_args;
+
+	if ((value == NULL) || (extra_args == NULL))
+		return -EINVAL;
+
+	*packet_size = (unsigned)strtoul(a, NULL, 0);
+	if (*packet_size == UINT_MAX)
+		return -1;
+
+	return 0;
+}
+
+static inline int
+get_packet_copy_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	const char *a = value;
+	unsigned *packet_copy = extra_args;
+
+	if ((value == NULL) || (extra_args == NULL))
+		return -EINVAL;
+
+	*packet_copy = (unsigned)strtoul(a, NULL, 0);
+	if (*packet_copy == UINT_MAX)
+		return -1;
+
+	return 0;
+}
+
+static int
+rte_pmd_dpdkoin_probe(struct rte_vdev_device *dev)
+{
+	const char *name, *params;
+	unsigned packet_size = default_packet_size;
+	unsigned packet_copy = default_packet_copy;
+	struct rte_kvargs *kvlist = NULL;
+	struct rte_eth_dev *eth_dev;
+	int ret;
+
+	if (!dev)
+		return -EINVAL;
+
+	name = rte_vdev_device_name(dev);
+	params = rte_vdev_device_args(dev);
+	PMD_LOG(INFO, "Initializing pmd_dpdkoin for %s", name);
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		eth_dev = rte_eth_dev_attach_secondary(name);
+		if (!eth_dev) {
+			PMD_LOG(ERR, "Failed to probe %s", name);
+			return -1;
+		}
+		/* TODO: request info from primary to set up Rx and Tx */
+		eth_dev->dev_ops = &ops;
+		eth_dev->device = &dev->device;
+		if (packet_copy) {
+			eth_dev->rx_pkt_burst = eth_dpdkoin_copy_rx;
+			eth_dev->tx_pkt_burst = eth_dpdkoin_copy_tx;
+		} else {
+			eth_dev->rx_pkt_burst = eth_dpdkoin_rx;
+			eth_dev->tx_pkt_burst = eth_dpdkoin_tx;
+		}
+		rte_eth_dev_probing_finish(eth_dev);
+		return 0;
+	}
+
+	if (params != NULL) {
+		kvlist = rte_kvargs_parse(params, valid_arguments);
+		if (kvlist == NULL)
+			return -1;
+
+		if (rte_kvargs_count(kvlist, ETH_DPDKOIN_PACKET_SIZE_ARG) == 1) {
+
+			ret = rte_kvargs_process(kvlist,
+					ETH_DPDKOIN_PACKET_SIZE_ARG,
+					&get_packet_size_arg, &packet_size);
+			if (ret < 0)
+				goto free_kvlist;
+		}
+
+		if (rte_kvargs_count(kvlist, ETH_DPDKOIN_PACKET_COPY_ARG) == 1) {
+
+			ret = rte_kvargs_process(kvlist,
+					ETH_DPDKOIN_PACKET_COPY_ARG,
+					&get_packet_copy_arg, &packet_copy);
+			if (ret < 0)
+				goto free_kvlist;
+		}
+	}
+
+	PMD_LOG(INFO, "Configure pmd_dpdkoin: packet size is %d, "
+			"packet copy is %s", packet_size,
+			packet_copy ? "enabled" : "disabled");
+
+	ret = eth_dev_dpdkoin_create(dev, packet_size, packet_copy);
+
+free_kvlist:
+	if (kvlist)
+		rte_kvargs_free(kvlist);
+	return ret;
+}
+
+static int
+rte_pmd_dpdkoin_remove(struct rte_vdev_device *dev)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+
+	if (!dev)
+		return -EINVAL;
+
+	PMD_LOG(INFO, "Closing dpdkoin ethdev on numa socket %u",
+			rte_socket_id());
+
+	/* find the ethdev entry */
+	eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev));
+	if (eth_dev == NULL)
+		return -1;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		/* mac_addrs must not be freed alone because part of dev_private */
+		eth_dev->data->mac_addrs = NULL;
+
+	rte_eth_dev_release_port(eth_dev);
+
+	return 0;
+}
+
+static struct rte_vdev_driver pmd_dpdkoin_drv = {
+	.probe = rte_pmd_dpdkoin_probe,
+	.remove = rte_pmd_dpdkoin_remove,
+};
+
+RTE_PMD_REGISTER_VDEV(net_dpdkoin, pmd_dpdkoin_drv);
+RTE_PMD_REGISTER_ALIAS(net_dpdkoin, eth_dpdkoin);
+RTE_PMD_REGISTER_PARAM_STRING(net_dpdkoin,
+	"size=<int> "
+	"copy=<int>");
+
+RTE_INIT(eth_dpdkoin_init_log)
+{
+	eth_dpdkoin_logtype = rte_log_register("pmd.net.dpdkoin");
+	if (eth_dpdkoin_logtype >= 0)
+		rte_log_set_level(eth_dpdkoin_logtype, RTE_LOG_NOTICE);
+}
diff --git a/drivers/net/dpdkoin/rte_pmd_dpdkoin_version.map b/drivers/net/dpdkoin/rte_pmd_dpdkoin_version.map
new file mode 100644
index 000000000..f9f17e4f6
--- /dev/null
+++ b/drivers/net/dpdkoin/rte_pmd_dpdkoin_version.map
@@ -0,0 +1,3 @@
+DPDK_20.0 {
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d295ca0a5..eff58903e 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -216,6 +216,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MVPP2_PMD)      += -lrte_pmd_mvpp2
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MVNETA_PMD)     += -lrte_pmd_mvneta
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL)       += -lrte_pmd_null
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPDKOIN)    += -lrte_pmd_dpdkoin -lbitcoin
 _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX2_PMD)  += -lrte_pmd_octeontx2 -lm
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lrte_pmd_pcap -lpcap
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PFE_PMD)        += -lrte_pmd_pfe
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [dpdk-dev] [PATCH] net/dpdkoin: add new driver
  2020-04-01 13:10 [dpdk-dev] [PATCH] net/dpdkoin: add new driver Matteo Croce
@ 2020-04-01 13:33 ` Ferruh Yigit
  2020-04-01 18:40 ` Aaron Conole
  2020-04-01 20:51 ` Kevin Traynor
  2 siblings, 0 replies; 5+ messages in thread
From: Ferruh Yigit @ 2020-04-01 13:33 UTC (permalink / raw)
  To: Matteo Croce, dev; +Cc: stable

On 4/1/2020 2:10 PM, Matteo Croce wrote:
> DPDK polls the packet in a busy loop. This means that CPU constantly spins
> looking for packets, regardless of the network traffic.
> DPDK does this to reduce latency and avoid using interrupts, at expense of
> efficiency: this might consume more processing power and generate more heat
> than needed, potentially increasing the TCO of a DPDK appliance.
> 
> Here comes DPDKoin. DPDKoin is a DPDK PMD, which instead of moving
> packets, mines cryptocurrencies.
> DPDKoin just does a few calculations to every poll cycle, this means that
> when the network is loaded, DPDKoin consumes just a few cycles, but when
> there is no traffic, DPDKoin mines currencies in a busy loop.
> The coins are mined with no extra consumption, as the CPU would spin
> anyway.

:)

<...>

> +	/* finally assign rx and tx ops */
> +	if (packet_copy) {
> +		eth_dev->rx_pkt_burst = eth_dpdkoin_copy_rx;
> +		eth_dev->tx_pkt_burst = eth_dpdkoin_copy_tx;
> +	} else {
> +		eth_dev->rx_pkt_burst = eth_dpdkoin_rx;
> +		eth_dev->tx_pkt_burst = eth_dpdkoin_tx;
> +	}

This is the biggest give away, but still good job :)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [dpdk-dev] [PATCH] net/dpdkoin: add new driver
  2020-04-01 13:10 [dpdk-dev] [PATCH] net/dpdkoin: add new driver Matteo Croce
  2020-04-01 13:33 ` Ferruh Yigit
@ 2020-04-01 18:40 ` Aaron Conole
  2020-04-01 20:51 ` Kevin Traynor
  2 siblings, 0 replies; 5+ messages in thread
From: Aaron Conole @ 2020-04-01 18:40 UTC (permalink / raw)
  To: Matteo Croce; +Cc: dev, stable

Matteo Croce <mcroce@redhat.com> writes:

> DPDK polls the packet in a busy loop. This means that CPU constantly spins
> looking for packets, regardless of the network traffic.
> DPDK does this to reduce latency and avoid using interrupts, at expense of
> efficiency: this might consume more processing power and generate more heat
> than needed, potentially increasing the TCO of a DPDK appliance.
>
> Here comes DPDKoin. DPDKoin is a DPDK PMD, which instead of moving
> packets, mines cryptocurrencies.
> DPDKoin just does a few calculations to every poll cycle, this means that
> when the network is loaded, DPDKoin consumes just a few cycles, but when
> there is no traffic, DPDKoin mines currencies in a busy loop.
> The coins are mined with no extra consumption, as the CPU would spin
> anyway.
>
> This is a system running with two 10G cards running with DPDK:
>
>   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
>  8223 root      10 -10  260.6g 597516  19100 S 199.8   0.5   0:17.89 testpmd
>
> And this is the same system with a DPDKoin port added:
>
>   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
>  9438 root      10 -10  260.6g 598892  19800 S 199.8   0.5   0:19.43 testpmd
>
> As you can see, we don't observe any change in the CPU usage, and besides,
> the earned coins lowers the appliance TCO.
>
> Just for reference, a test run log follows:
>
> $ sudo testpmd --no-huge -m 1024 --no-pci --vdev eth_dpdkoin0 --vdev eth_dpdkoin1
> EAL: Detected 8 lcore(s)
> EAL: Detected 1 NUMA nodes
> EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
> EAL: Selected IOVA mode 'VA'
> EAL: Probing VFIO support...
> testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n 3456, size!76, socket=0
> testpmd: preferred mempool ops selected: ring_mp_mc
> Configuring Port 0 (socket 0)
> Port 0: 4A:50:3C:33:55:21
> Configuring Port 1 (socket 0)
> Port 1: BA:BB:0A:BB:0C:CA
> Checking link statuses...
> Done
> No commandline core given, start packet forwarding
> io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native
> Logical Core 1 (socket 0) forwards packets on 2 streams:
>   RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer:00:00:00:00:01
>   RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer:00:00:00:00:00
>
>   io packet forwarding packets/burst2
>   nb forwarding cores=1 - nb forwarding ports=2
>   port 0: RX queue number: 1 Tx queue number: 1
>     Rx offloads=0x0 Tx offloads=0x0
>     RX queue: 0
>       RX desc=0 - RX free threshold=0
>       RX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       RX Offloads=0x0
>     TX queue: 0
>       TX desc=0 - TX free threshold=0
>       TX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       TX offloads=0x0 - TX RS bit threshold=0
>   port 1: RX queue number: 1 Tx queue number: 1
>     Rx offloads=0x0 Tx offloads=0x0
>     RX queue: 0
>       RX desc=0 - RX free threshold=0
>       RX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       RX Offloads=0x0
>     TX queue: 0
>       TX desc=0 - TX free threshold=0
>       TX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       TX offloads=0x0 - TX RS bit threshold=0
> libbitcoin 0.1: mining on CPU2
> libbitcoin 0.1: mining on CPU4
> ---
>  config/common_base                            |   5 +
>  drivers/net/Makefile                          |   1 +
>  drivers/net/dpdkoin/Makefile                  |  23 +
>  drivers/net/dpdkoin/meson.build               |   3 +
>  drivers/net/dpdkoin/rte_eth_dpdkoin.c         | 696 ++++++++++++++++++
>  .../net/dpdkoin/rte_pmd_dpdkoin_version.map   |   3 +
>  mk/rte.app.mk                                 |   1 +
>  7 files changed, 732 insertions(+)
>  create mode 100644 drivers/net/dpdkoin/Makefile
>  create mode 100644 drivers/net/dpdkoin/meson.build
>  create mode 100644 drivers/net/dpdkoin/rte_eth_dpdkoin.c
>  create mode 100644 drivers/net/dpdkoin/rte_pmd_dpdkoin_version.map
>

Is it possible to have a unit test for this PMD?  We could have the
robot run some quick tests for us... ;-)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [dpdk-dev] [PATCH] net/dpdkoin: add new driver
  2020-04-01 13:10 [dpdk-dev] [PATCH] net/dpdkoin: add new driver Matteo Croce
  2020-04-01 13:33 ` Ferruh Yigit
  2020-04-01 18:40 ` Aaron Conole
@ 2020-04-01 20:51 ` Kevin Traynor
  2020-04-01 22:26   ` Stephen Hemminger
  2 siblings, 1 reply; 5+ messages in thread
From: Kevin Traynor @ 2020-04-01 20:51 UTC (permalink / raw)
  To: Matteo Croce, dev; +Cc: stable

On 01/04/2020 14:10, Matteo Croce wrote:
> DPDK polls the packet in a busy loop. This means that CPU constantly spins
> looking for packets, regardless of the network traffic.
> DPDK does this to reduce latency and avoid using interrupts, at expense of
> efficiency: this might consume more processing power and generate more heat
> than needed, potentially increasing the TCO of a DPDK appliance.
> 
> Here comes DPDKoin. DPDKoin is a DPDK PMD, which instead of moving
> packets, mines cryptocurrencies.
> DPDKoin just does a few calculations to every poll cycle, this means that
> when the network is loaded, DPDKoin consumes just a few cycles, but when
> there is no traffic, DPDKoin mines currencies in a busy loop.
> The coins are mined with no extra consumption, as the CPU would spin
> anyway.
> 
> This is a system running with two 10G cards running with DPDK:
> 
>   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
>  8223 root      10 -10  260.6g 597516  19100 S 199.8   0.5   0:17.89 testpmd
> 
> And this is the same system with a DPDKoin port added:
> 
>   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
>  9438 root      10 -10  260.6g 598892  19800 S 199.8   0.5   0:19.43 testpmd
> 
> As you can see, we don't observe any change in the CPU usage, and besides,
> the earned coins lowers the appliance TCO.
> 
> Just for reference, a test run log follows:
> 
> $ sudo testpmd --no-huge -m 1024 --no-pci --vdev eth_dpdkoin0 --vdev eth_dpdkoin1
> EAL: Detected 8 lcore(s)
> EAL: Detected 1 NUMA nodes
> EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
> EAL: Selected IOVA mode 'VA'
> EAL: Probing VFIO support...
> testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n=203456, size=2176, socket=0
> testpmd: preferred mempool ops selected: ring_mp_mc
> Configuring Port 0 (socket 0)
> Port 0: 4A:50:3C:33:55:21
> Configuring Port 1 (socket 0)
> Port 1: BA:BB:0A:BB:0C:CA
> Checking link statuses...
> Done
> No commandline core given, start packet forwarding
> io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native
> Logical Core 1 (socket 0) forwards packets on 2 streams:
>   RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
>   RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
> 
>   io packet forwarding packets/burst=32
>   nb forwarding cores=1 - nb forwarding ports=2
>   port 0: RX queue number: 1 Tx queue number: 1
>     Rx offloads=0x0 Tx offloads=0x0
>     RX queue: 0
>       RX desc=0 - RX free threshold=0
>       RX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       RX Offloads=0x0
>     TX queue: 0
>       TX desc=0 - TX free threshold=0
>       TX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       TX offloads=0x0 - TX RS bit threshold=0
>   port 1: RX queue number: 1 Tx queue number: 1
>     Rx offloads=0x0 Tx offloads=0x0
>     RX queue: 0
>       RX desc=0 - RX free threshold=0
>       RX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       RX Offloads=0x0
>     TX queue: 0
>       TX desc=0 - TX free threshold=0
>       TX threshold registers: pthresh=0 hthresh=0  wthresh=0
>       TX offloads=0x0 - TX RS bit threshold=0
> libbitcoin 0.1: mining on CPU2
> libbitcoin 0.1: mining on CPU4
> ---
>  config/common_base                            |   5 +
>  drivers/net/Makefile                          |   1 +
>  drivers/net/dpdkoin/Makefile                  |  23 +
>  drivers/net/dpdkoin/meson.build               |   3 +
>  drivers/net/dpdkoin/rte_eth_dpdkoin.c         | 696 ++++++++++++++++++
>  .../net/dpdkoin/rte_pmd_dpdkoin_version.map   |   3 +
>  mk/rte.app.mk                                 |   1 +
>  7 files changed, 732 insertions(+)
>  create mode 100644 drivers/net/dpdkoin/Makefile
>  create mode 100644 drivers/net/dpdkoin/meson.build
>  create mode 100644 drivers/net/dpdkoin/rte_eth_dpdkoin.c
>  create mode 100644 drivers/net/dpdkoin/rte_pmd_dpdkoin_version.map

I see you are requesting this for backport to stable branches. While
this is not fixing a specific commit per se, it is clearly fixing a gap
whereby it would be unfair for stable users to miss out on any potential
bonanza.

Unfortunately there is a blocker due to validation. Normally, we might
be concerned by lack of it, but in this case the concern is that it
might encourage too much validation and many lengthy stress tests that
could impact release dates.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [dpdk-dev] [PATCH] net/dpdkoin: add new driver
  2020-04-01 20:51 ` Kevin Traynor
@ 2020-04-01 22:26   ` Stephen Hemminger
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2020-04-01 22:26 UTC (permalink / raw)
  To: Kevin Traynor; +Cc: Matteo Croce, dev, stable

On Wed, 1 Apr 2020 21:51:53 +0100
Kevin Traynor <ktraynor@redhat.com> wrote:

> On 01/04/2020 14:10, Matteo Croce wrote:
> > DPDK polls the packet in a busy loop. This means that CPU constantly spins
> > looking for packets, regardless of the network traffic.
> > DPDK does this to reduce latency and avoid using interrupts, at expense of
> > efficiency: this might consume more processing power and generate more heat
> > than needed, potentially increasing the TCO of a DPDK appliance.
> > 
> > Here comes DPDKoin. DPDKoin is a DPDK PMD, which instead of moving
> > packets, mines cryptocurrencies.
> > DPDKoin just does a few calculations to every poll cycle, this means that
> > when the network is loaded, DPDKoin consumes just a few cycles, but when
> > there is no traffic, DPDKoin mines currencies in a busy loop.
> > The coins are mined with no extra consumption, as the CPU would spin
> > anyway.
> > 
> > This is a system running with two 10G cards running with DPDK:
> > 
> >   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
> >  8223 root      10 -10  260.6g 597516  19100 S 199.8   0.5   0:17.89 testpmd
> > 
> > And this is the same system with a DPDKoin port added:
> > 
> >   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
> >  9438 root      10 -10  260.6g 598892  19800 S 199.8   0.5   0:19.43 testpmd
> > 
> > As you can see, we don't observe any change in the CPU usage, and besides,
> > the earned coins lowers the appliance TCO.
> > 
> > Just for reference, a test run log follows:
> > 
> > $ sudo testpmd --no-huge -m 1024 --no-pci --vdev eth_dpdkoin0 --vdev eth_dpdkoin1
> > EAL: Detected 8 lcore(s)
> > EAL: Detected 1 NUMA nodes
> > EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
> > EAL: Selected IOVA mode 'VA'
> > EAL: Probing VFIO support...
> > testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n=203456, size=2176, socket=0
> > testpmd: preferred mempool ops selected: ring_mp_mc
> > Configuring Port 0 (socket 0)
> > Port 0: 4A:50:3C:33:55:21
> > Configuring Port 1 (socket 0)
> > Port 1: BA:BB:0A:BB:0C:CA
> > Checking link statuses...
> > Done
> > No commandline core given, start packet forwarding
> > io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native
> > Logical Core 1 (socket 0) forwards packets on 2 streams:
> >   RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
> >   RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
> > 
> >   io packet forwarding packets/burst=32
> >   nb forwarding cores=1 - nb forwarding ports=2
> >   port 0: RX queue number: 1 Tx queue number: 1
> >     Rx offloads=0x0 Tx offloads=0x0
> >     RX queue: 0
> >       RX desc=0 - RX free threshold=0
> >       RX threshold registers: pthresh=0 hthresh=0  wthresh=0
> >       RX Offloads=0x0
> >     TX queue: 0
> >       TX desc=0 - TX free threshold=0
> >       TX threshold registers: pthresh=0 hthresh=0  wthresh=0
> >       TX offloads=0x0 - TX RS bit threshold=0
> >   port 1: RX queue number: 1 Tx queue number: 1
> >     Rx offloads=0x0 Tx offloads=0x0
> >     RX queue: 0
> >       RX desc=0 - RX free threshold=0
> >       RX threshold registers: pthresh=0 hthresh=0  wthresh=0
> >       RX Offloads=0x0
> >     TX queue: 0
> >       TX desc=0 - TX free threshold=0
> >       TX threshold registers: pthresh=0 hthresh=0  wthresh=0
> >       TX offloads=0x0 - TX RS bit threshold=0
> > libbitcoin 0.1: mining on CPU2
> > libbitcoin 0.1: mining on CPU4
> > ---
> >  config/common_base                            |   5 +
> >  drivers/net/Makefile                          |   1 +
> >  drivers/net/dpdkoin/Makefile                  |  23 +
> >  drivers/net/dpdkoin/meson.build               |   3 +
> >  drivers/net/dpdkoin/rte_eth_dpdkoin.c         | 696 ++++++++++++++++++
> >  .../net/dpdkoin/rte_pmd_dpdkoin_version.map   |   3 +
> >  mk/rte.app.mk                                 |   1 +
> >  7 files changed, 732 insertions(+)
> >  create mode 100644 drivers/net/dpdkoin/Makefile
> >  create mode 100644 drivers/net/dpdkoin/meson.build
> >  create mode 100644 drivers/net/dpdkoin/rte_eth_dpdkoin.c
> >  create mode 100644 drivers/net/dpdkoin/rte_pmd_dpdkoin_version.map  
> 
> I see you are requesting this for backport to stable branches. While
> this is not fixing a specific commit per se, it is clearly fixing a gap
> whereby it would be unfair for stable users to miss out on any potential
> bonanza.
> 
> Unfortunately there is a blocker due to validation. Normally, we might
> be concerned by lack of it, but in this case the concern is that it
> might encourage too much validation and many lengthy stress tests that
> could impact release dates.
> 

Could we fund the CI lab with this?

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-04-01 22:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-01 13:10 [dpdk-dev] [PATCH] net/dpdkoin: add new driver Matteo Croce
2020-04-01 13:33 ` Ferruh Yigit
2020-04-01 18:40 ` Aaron Conole
2020-04-01 20:51 ` Kevin Traynor
2020-04-01 22:26   ` Stephen Hemminger

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).