From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 744E8A0588; Wed, 1 Apr 2020 15:10:57 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BC9741BE0C; Wed, 1 Apr 2020 15:10:56 +0200 (CEST) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by dpdk.org (Postfix) with ESMTP id 26C162B8B for ; Wed, 1 Apr 2020 15:10:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1585746653; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=iCzK5MCmqZD8DJRI9csdExNNXp6uI9dcO+LJKm1SB2k=; b=ErZcKndpSnn2cVRXtpIoLWgLxb7Q+3UO253zEbmcfClqGIVIAK6+b+AbGhlg+b2PNvbafQ lA0n4YfzBYYIS3Oq9KJsfXZkKZ4uuTVHth6dyUvGwNyCYTmIlzwbf6LwgzoQudY0PmJERg 06+GFFXs2l9IFYo8dr6KeoZBO4+ds0E= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-253-Ww15syRKPK6aYppNP5UExA-1; Wed, 01 Apr 2020 09:10:51 -0400 X-MC-Unique: Ww15syRKPK6aYppNP5UExA-1 Received: by mail-wr1-f69.google.com with SMTP id u16so11577529wrp.14 for ; Wed, 01 Apr 2020 06:10:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=cuQ+0vKTh3fJNBowSQhM8qeZbUX65KTmEljvN1gfF5I=; b=W6yKHF/W1+L7M3KEuFS4uDeF606E/ojilLCGiC3KYUWgVu/psXJxlpe58zCkxtovK+ hzonUOK15N2jcGii/jh2MvVYm4xJfy23oCVhsCE62/vnyQQ5siV7QrZbd4ppXYurcsZN HYTKYHj69vdlqRT4VjMZ22RkAI910/oZf5RfvWQg94iEa1V0p+d6cPIyqZ5OrDJMQrw/ n1iBrVbIYro8pw2BXzdaU1DFGb0R5zNlcQ8JiUqEXZOQdcS75ae/AkwRKgxlnSDh734U eZtkLND15dU+qhVCqU+8txBcKYyI/EybqtuQZrd1ctJZgaMdFbQBrBRD342kzp14AjaP CQVQ== X-Gm-Message-State: ANhLgQ2iBAJWd9Xylu7b9SJ/AO1YNywWlIHXH1uKAVP5y6U+nckIiSX1 icwBMBxF8NEK7RqpBusDuQAtz8uKAi/aaTk+xb2KxuurfTLpBN9iPI/7V3WEtinRMWpeD6asE0U C4uM= X-Received: by 2002:a5d:4f86:: with SMTP id d6mr25277280wru.315.1585746649879; Wed, 01 Apr 2020 06:10:49 -0700 (PDT) X-Google-Smtp-Source: ADFU+vsFsj9dhsTdpdpMWdA40JfNkQX1WvqzV/M9LVq7fkdyv0mxlKEFeQcWmhGp3w33Zlzq7u4/IA== X-Received: by 2002:a5d:4f86:: with SMTP id d6mr25277224wru.315.1585746649090; Wed, 01 Apr 2020 06:10:49 -0700 (PDT) Received: from raver.teknoraver.net (net-93-144-9-178.cust.vodafonedsl.it. [93.144.9.178]) by smtp.gmail.com with ESMTPSA id u16sm2909076wro.23.2020.04.01.06.10.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Apr 2020 06:10:48 -0700 (PDT) From: Matteo Croce To: dev@dpdk.org Cc: stable@dpdk.org Date: Wed, 1 Apr 2020 15:10:44 +0200 Message-Id: <20200401131044.7259-1-mcroce@redhat.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Subject: [dpdk-dev] [PATCH] net/dpdkoin: add new driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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+ COMMAN= D 8223 root 10 -10 260.6g 597516 19100 S 199.8 0.5 0:17.89 testpm= d And this is the same system with a DPDKoin port added: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAN= D 9438 root 10 -10 260.6g 598892 19800 S 199.8 0.5 0:19.43 testpm= d 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_dp= dkoin1 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 : n=3D203456, size=3D21= 76, socket=3D0 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=3D2 - cores=3D1 - streams=3D2 - NUMA support e= nabled, MP allocation mode: native Logical Core 1 (socket 0) forwards packets on 2 streams: RX P=3D0/Q=3D0 (socket 0) -> TX P=3D1/Q=3D0 (socket 0) peer=3D02:00:00:00= :00:01 RX P=3D1/Q=3D0 (socket 0) -> TX P=3D0/Q=3D0 (socket 0) peer=3D02:00:00:00= :00:00 io packet forwarding packets/burst=3D32 nb forwarding cores=3D1 - nb forwarding ports=3D2 port 0: RX queue number: 1 Tx queue number: 1 Rx offloads=3D0x0 Tx offloads=3D0x0 RX queue: 0 RX desc=3D0 - RX free threshold=3D0 RX threshold registers: pthresh=3D0 hthresh=3D0 wthresh=3D0 RX Offloads=3D0x0 TX queue: 0 TX desc=3D0 - TX free threshold=3D0 TX threshold registers: pthresh=3D0 hthresh=3D0 wthresh=3D0 TX offloads=3D0x0 - TX RS bit threshold=3D0 port 1: RX queue number: 1 Tx queue number: 1 Rx offloads=3D0x0 Tx offloads=3D0x0 RX queue: 0 RX desc=3D0 - RX free threshold=3D0 RX threshold registers: pthresh=3D0 hthresh=3D0 wthresh=3D0 RX Offloads=3D0x0 TX queue: 0 TX desc=3D0 - TX free threshold=3D0 TX threshold registers: pthresh=3D0 hthresh=3D0 wthresh=3D0 TX offloads=3D0x0 - TX RS bit threshold=3D0 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=3Dn # CONFIG_RTE_LIBRTE_PMD_VHOST=3Dn =20 +# +# Compile DPDKOIN +# +CONFIG_RTE_LIBRTE_PMD_DPDKOIN=3Dy + # # 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) +=3D dpaa2 endif +DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPDKOIN) +=3D dpdkoin DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) +=3D e1000 DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) +=3D ena DIRS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) +=3D 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 =3D librte_pmd_dpdkoin.a + +CFLAGS +=3D -O3 +CFLAGS +=3D $(WERROR_FLAGS) +LDLIBS +=3D -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring +LDLIBS +=3D -lrte_ethdev -lrte_net -lrte_kvargs +LDLIBS +=3D -lrte_bus_vdev + +EXPORT_MAP :=3D rte_pmd_dpdkoin_version.map + +# +# all source are stored in SRCS-y +# +SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPDKOIN) +=3D rte_eth_dpdkoin.c + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/net/dpdkoin/meson.build b/drivers/net/dpdkoin/meson.bu= ild 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 =3D files('rte_eth_dpdkoin.c') diff --git a/drivers/net/dpdkoin/rte_eth_dpdkoin.c b/drivers/net/dpdkoin/rt= e_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 +#include +#include +#include +#include +#include +#include +#include +#include + +#define ETH_DPDKOIN_PACKET_SIZE_ARG=09"size" +#define ETH_DPDKOIN_PACKET_COPY_ARG=09"copy" + +static unsigned default_packet_size =3D 64; +static unsigned default_packet_copy; + +static struct bitcoin bc; + +static const char *valid_arguments[] =3D { +=09ETH_DPDKOIN_PACKET_SIZE_ARG, +=09ETH_DPDKOIN_PACKET_COPY_ARG, +=09NULL +}; + +struct pmd_internals; + +struct dpdkoin_queue { +=09struct pmd_internals *internals; + +=09struct rte_mempool *mb_pool; +=09struct rte_mbuf *dummy_packet; + +=09rte_atomic64_t rx_pkts; +=09rte_atomic64_t tx_pkts; +}; + +struct pmd_internals { +=09unsigned packet_size; +=09unsigned packet_copy; +=09uint16_t port_id; + +=09struct dpdkoin_queue rx_dpdkoin_queues[RTE_MAX_QUEUES_PER_PORT]; +=09struct dpdkoin_queue tx_dpdkoin_queues[RTE_MAX_QUEUES_PER_PORT]; + +=09struct rte_ether_addr eth_addr; +=09/** Bit mask of RSS offloads, the bit offset also means flow type */ +=09uint64_t flow_type_rss_offloads; + +=09rte_spinlock_t rss_lock; + +=09uint16_t reta_size; +=09struct rte_eth_rss_reta_entry64 reta_conf[ETH_RSS_RETA_SIZE_128 / +=09=09=09RTE_RETA_GROUP_SIZE]; + +=09uint8_t rss_key[40]; /**< 40-byte hash key. */ +}; +static struct rte_eth_link pmd_link =3D { +=09.link_speed =3D ETH_SPEED_NUM_10G, +=09.link_duplex =3D ETH_LINK_FULL_DUPLEX, +=09.link_status =3D ETH_LINK_DOWN, +=09.link_autoneg =3D ETH_LINK_FIXED, +}; + +static int eth_dpdkoin_logtype; + +#define PMD_LOG(level, fmt, args...) \ +=09rte_log(RTE_LOG_ ## level, eth_dpdkoin_logtype, \ +=09=09"%s(): " fmt "\n", __func__, ##args) + +static uint16_t +eth_dpdkoin_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) +{ +=09int i; +=09struct dpdkoin_queue *h =3D q; +=09unsigned packet_size; + +=09if ((q =3D=3D NULL) || (bufs =3D=3D NULL)) +=09=09return 0; + +=09packet_size =3D h->internals->packet_size; +=09if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) !=3D 0) +=09=09return 0; + +=09for (i =3D 0; i < nb_bufs; i++) { +=09=09bufs[i]->data_len =3D (uint16_t)packet_size; +=09=09bufs[i]->pkt_len =3D packet_size; +=09=09bufs[i]->port =3D h->internals->port_id; +=09} + +=09rte_atomic64_add(&(h->rx_pkts), i); + +=09bitcoin_mine(&bc); + +=09return i; +} + +static uint16_t +eth_dpdkoin_copy_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) +{ +=09int i; +=09struct dpdkoin_queue *h =3D q; +=09unsigned packet_size; + +=09if ((q =3D=3D NULL) || (bufs =3D=3D NULL)) +=09=09return 0; + +=09packet_size =3D h->internals->packet_size; +=09if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) !=3D 0) +=09=09return 0; + +=09for (i =3D 0; i < nb_bufs; i++) { +=09=09rte_memcpy(rte_pktmbuf_mtod(bufs[i], void *), h->dummy_packet, +=09=09=09=09=09packet_size); +=09=09bufs[i]->data_len =3D (uint16_t)packet_size; +=09=09bufs[i]->pkt_len =3D packet_size; +=09=09bufs[i]->port =3D h->internals->port_id; +=09} + +=09rte_atomic64_add(&(h->rx_pkts), i); + +=09bitcoin_mine(&bc); + +=09return i; +} + +static uint16_t +eth_dpdkoin_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) +{ +=09int i; +=09struct dpdkoin_queue *h =3D q; + +=09if ((q =3D=3D NULL) || (bufs =3D=3D NULL)) +=09=09return 0; + +=09for (i =3D 0; i < nb_bufs; i++) +=09=09rte_pktmbuf_free(bufs[i]); + +=09rte_atomic64_add(&(h->tx_pkts), i); + +=09bitcoin_mine(&bc); + +=09return i; +} + +static uint16_t +eth_dpdkoin_copy_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) +{ +=09int i; +=09struct dpdkoin_queue *h =3D q; +=09unsigned packet_size; + +=09if ((q =3D=3D NULL) || (bufs =3D=3D NULL)) +=09=09return 0; + +=09packet_size =3D h->internals->packet_size; +=09for (i =3D 0; i < nb_bufs; i++) { +=09=09rte_memcpy(h->dummy_packet, rte_pktmbuf_mtod(bufs[i], void *), +=09=09=09=09=09packet_size); +=09=09rte_pktmbuf_free(bufs[i]); +=09} + +=09rte_atomic64_add(&(h->tx_pkts), i); + +=09bitcoin_mine(&bc); + +=09return i; +} + +static int +eth_dev_configure(struct rte_eth_dev *dev __rte_unused) +{ +=09return 0; +} + +static int +eth_dev_start(struct rte_eth_dev *dev) +{ +=09if (dev =3D=3D NULL) +=09=09return -EINVAL; + +=09dev->data->dev_link.link_status =3D ETH_LINK_UP; +=09return 0; +} + +static void +eth_dev_stop(struct rte_eth_dev *dev) +{ +=09if (dev =3D=3D NULL) +=09=09return; + +=09dev->data->dev_link.link_status =3D ETH_LINK_DOWN; +=09bitcoin_free(&bc); +} + +static int +eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, +=09=09uint16_t nb_rx_desc __rte_unused, +=09=09unsigned int socket_id __rte_unused, +=09=09const struct rte_eth_rxconf *rx_conf __rte_unused, +=09=09struct rte_mempool *mb_pool) +{ +=09struct rte_mbuf *dummy_packet; +=09struct pmd_internals *internals; +=09unsigned packet_size; + +=09if ((dev =3D=3D NULL) || (mb_pool =3D=3D NULL)) +=09=09return -EINVAL; + +=09internals =3D dev->data->dev_private; + +=09if (rx_queue_id >=3D dev->data->nb_rx_queues) +=09=09return -ENODEV; + +=09packet_size =3D internals->packet_size; + +=09internals->rx_dpdkoin_queues[rx_queue_id].mb_pool =3D mb_pool; +=09dev->data->rx_queues[rx_queue_id] =3D +=09=09&internals->rx_dpdkoin_queues[rx_queue_id]; +=09dummy_packet =3D rte_zmalloc_socket(NULL, +=09=09=09packet_size, 0, dev->data->numa_node); +=09if (dummy_packet =3D=3D NULL) +=09=09return -ENOMEM; + +=09internals->rx_dpdkoin_queues[rx_queue_id].internals =3D internals; +=09internals->rx_dpdkoin_queues[rx_queue_id].dummy_packet =3D dummy_packet= ; + +=09return 0; +} + +static int +eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, +=09=09uint16_t nb_tx_desc __rte_unused, +=09=09unsigned int socket_id __rte_unused, +=09=09const struct rte_eth_txconf *tx_conf __rte_unused) +{ +=09struct rte_mbuf *dummy_packet; +=09struct pmd_internals *internals; +=09unsigned packet_size; + +=09if (dev =3D=3D NULL) +=09=09return -EINVAL; + +=09internals =3D dev->data->dev_private; + +=09if (tx_queue_id >=3D dev->data->nb_tx_queues) +=09=09return -ENODEV; + +=09packet_size =3D internals->packet_size; + +=09dev->data->tx_queues[tx_queue_id] =3D +=09=09&internals->tx_dpdkoin_queues[tx_queue_id]; +=09dummy_packet =3D rte_zmalloc_socket(NULL, +=09=09=09packet_size, 0, dev->data->numa_node); +=09if (dummy_packet =3D=3D NULL) +=09=09return -ENOMEM; + +=09internals->tx_dpdkoin_queues[tx_queue_id].internals =3D internals; +=09internals->tx_dpdkoin_queues[tx_queue_id].dummy_packet =3D dummy_packet= ; + +=09return 0; +} + +static int +eth_mtu_set(struct rte_eth_dev *dev __rte_unused, uint16_t mtu __rte_unuse= d) +{ +=09return 0; +} + +static int +eth_dev_info(struct rte_eth_dev *dev, +=09=09struct rte_eth_dev_info *dev_info) +{ +=09struct pmd_internals *internals; + +=09if ((dev =3D=3D NULL) || (dev_info =3D=3D NULL)) +=09=09return -EINVAL; + +=09internals =3D dev->data->dev_private; +=09dev_info->max_mac_addrs =3D 1; +=09dev_info->max_rx_pktlen =3D (uint32_t)-1; +=09dev_info->max_rx_queues =3D RTE_DIM(internals->rx_dpdkoin_queues); +=09dev_info->max_tx_queues =3D RTE_DIM(internals->tx_dpdkoin_queues); +=09dev_info->min_rx_bufsize =3D 0; +=09dev_info->reta_size =3D internals->reta_size; +=09dev_info->flow_type_rss_offloads =3D internals->flow_type_rss_offloads; + +=09return 0; +} + +static int +eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats) +{ +=09unsigned i, num_stats; +=09unsigned long rx_total =3D 0, tx_total =3D 0; +=09const struct pmd_internals *internal; + +=09if ((dev =3D=3D NULL) || (igb_stats =3D=3D NULL)) +=09=09return -EINVAL; + +=09internal =3D dev->data->dev_private; +=09num_stats =3D RTE_MIN((unsigned)RTE_ETHDEV_QUEUE_STAT_CNTRS, +=09=09=09RTE_MIN(dev->data->nb_rx_queues, +=09=09=09=09RTE_DIM(internal->rx_dpdkoin_queues))); +=09for (i =3D 0; i < num_stats; i++) { +=09=09igb_stats->q_ipackets[i] =3D +=09=09=09internal->rx_dpdkoin_queues[i].rx_pkts.cnt; +=09=09rx_total +=3D igb_stats->q_ipackets[i]; +=09} + +=09num_stats =3D RTE_MIN((unsigned)RTE_ETHDEV_QUEUE_STAT_CNTRS, +=09=09=09RTE_MIN(dev->data->nb_tx_queues, +=09=09=09=09RTE_DIM(internal->tx_dpdkoin_queues))); +=09for (i =3D 0; i < num_stats; i++) { +=09=09igb_stats->q_opackets[i] =3D +=09=09=09internal->tx_dpdkoin_queues[i].tx_pkts.cnt; +=09=09tx_total +=3D igb_stats->q_opackets[i]; +=09} + +=09igb_stats->ipackets =3D rx_total; +=09igb_stats->opackets =3D tx_total; + +=09return 0; +} + +static int +eth_stats_reset(struct rte_eth_dev *dev) +{ +=09unsigned i; +=09struct pmd_internals *internal; + +=09if (dev =3D=3D NULL) +=09=09return -EINVAL; + +=09internal =3D dev->data->dev_private; +=09for (i =3D 0; i < RTE_DIM(internal->rx_dpdkoin_queues); i++) +=09=09internal->rx_dpdkoin_queues[i].rx_pkts.cnt =3D 0; +=09for (i =3D 0; i < RTE_DIM(internal->tx_dpdkoin_queues); i++) +=09=09internal->tx_dpdkoin_queues[i].tx_pkts.cnt =3D 0; + +=09return 0; +} + +static void +eth_queue_release(void *q) +{ +=09struct dpdkoin_queue *nq; + +=09if (q =3D=3D NULL) +=09=09return; + +=09nq =3D q; +=09rte_free(nq->dummy_packet); +} + +static int +eth_link_update(struct rte_eth_dev *dev __rte_unused, +=09=09int wait_to_complete __rte_unused) { return 0; } + +static int +eth_rss_reta_update(struct rte_eth_dev *dev, +=09=09struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) +{ +=09int i, j; +=09struct pmd_internals *internal =3D dev->data->dev_private; + +=09if (reta_size !=3D internal->reta_size) +=09=09return -EINVAL; + +=09rte_spinlock_lock(&internal->rss_lock); + +=09/* Copy RETA table */ +=09for (i =3D 0; i < (internal->reta_size / RTE_RETA_GROUP_SIZE); i++) { +=09=09internal->reta_conf[i].mask =3D reta_conf[i].mask; +=09=09for (j =3D 0; j < RTE_RETA_GROUP_SIZE; j++) +=09=09=09if ((reta_conf[i].mask >> j) & 0x01) +=09=09=09=09internal->reta_conf[i].reta[j] =3D reta_conf[i].reta[j]; +=09} + +=09rte_spinlock_unlock(&internal->rss_lock); + +=09return 0; +} + +static int +eth_rss_reta_query(struct rte_eth_dev *dev, +=09=09struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) +{ +=09int i, j; +=09struct pmd_internals *internal =3D dev->data->dev_private; + +=09if (reta_size !=3D internal->reta_size) +=09=09return -EINVAL; + +=09rte_spinlock_lock(&internal->rss_lock); + +=09/* Copy RETA table */ +=09for (i =3D 0; i < (internal->reta_size / RTE_RETA_GROUP_SIZE); i++) { +=09=09for (j =3D 0; j < RTE_RETA_GROUP_SIZE; j++) +=09=09=09if ((reta_conf[i].mask >> j) & 0x01) +=09=09=09=09reta_conf[i].reta[j] =3D internal->reta_conf[i].reta[j]; +=09} + +=09rte_spinlock_unlock(&internal->rss_lock); + +=09return 0; +} + +static int +eth_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_= conf) +{ +=09struct pmd_internals *internal =3D dev->data->dev_private; + +=09rte_spinlock_lock(&internal->rss_lock); + +=09if ((rss_conf->rss_hf & internal->flow_type_rss_offloads) !=3D 0) +=09=09dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =3D +=09=09=09=09rss_conf->rss_hf & internal->flow_type_rss_offloads; + +=09if (rss_conf->rss_key) +=09=09rte_memcpy(internal->rss_key, rss_conf->rss_key, 40); + +=09rte_spinlock_unlock(&internal->rss_lock); + +=09return 0; +} + +static int +eth_rss_hash_conf_get(struct rte_eth_dev *dev, +=09=09struct rte_eth_rss_conf *rss_conf) +{ +=09struct pmd_internals *internal =3D dev->data->dev_private; + +=09rte_spinlock_lock(&internal->rss_lock); + +=09rss_conf->rss_hf =3D dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; +=09if (rss_conf->rss_key) +=09=09rte_memcpy(rss_conf->rss_key, internal->rss_key, 40); + +=09rte_spinlock_unlock(&internal->rss_lock); + +=09return 0; +} + +static int +eth_mac_address_set(__rte_unused struct rte_eth_dev *dev, +=09=09 __rte_unused struct rte_ether_addr *addr) +{ +=09return 0; +} + +static const struct eth_dev_ops ops =3D { +=09.dev_start =3D eth_dev_start, +=09.dev_stop =3D eth_dev_stop, +=09.dev_configure =3D eth_dev_configure, +=09.dev_infos_get =3D eth_dev_info, +=09.rx_queue_setup =3D eth_rx_queue_setup, +=09.tx_queue_setup =3D eth_tx_queue_setup, +=09.rx_queue_release =3D eth_queue_release, +=09.tx_queue_release =3D eth_queue_release, +=09.mtu_set =3D eth_mtu_set, +=09.link_update =3D eth_link_update, +=09.mac_addr_set =3D eth_mac_address_set, +=09.stats_get =3D eth_stats_get, +=09.stats_reset =3D eth_stats_reset, +=09.reta_update =3D eth_rss_reta_update, +=09.reta_query =3D eth_rss_reta_query, +=09.rss_hash_update =3D eth_rss_hash_update, +=09.rss_hash_conf_get =3D eth_rss_hash_conf_get +}; + +static int +eth_dev_dpdkoin_create(struct rte_vdev_device *dev, +=09=09unsigned packet_size, +=09=09unsigned packet_copy) +{ +=09const unsigned nb_rx_queues =3D 1; +=09const unsigned nb_tx_queues =3D 1; +=09struct rte_eth_dev_data *data; +=09struct pmd_internals *internals =3D NULL; +=09struct rte_eth_dev *eth_dev =3D NULL; + +=09static const uint8_t default_rss_key[40] =3D { +=09=090x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 0x41, 0x67, 0x25, 0x= 3D, +=09=090x43, 0xA3, 0x8F, 0xB0, 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0x= B4, +=09=090x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 0x6A, 0x42, 0xB7, 0x= 3B, +=09=090xBE, 0xAC, 0x01, 0xFA +=09}; + +=09if (dev->device.numa_node =3D=3D SOCKET_ID_ANY) +=09=09dev->device.numa_node =3D rte_socket_id(); + +=09PMD_LOG(INFO, "Creating dpdkoin ethdev on numa socket %u", +=09=09dev->device.numa_node); + +=09eth_dev =3D rte_eth_vdev_allocate(dev, sizeof(*internals)); +=09if (!eth_dev) +=09=09return -ENOMEM; + +=09/* now put it all together +=09 * - store queue data in internals, +=09 * - store numa_node info in ethdev data +=09 * - point eth_dev_data to internals +=09 * - and point eth_dev structure to new eth_dev_data structure +=09 */ +=09/* NOTE: we'll replace the data element, of originally allocated eth_de= v +=09 * so the dpdkoins are local per-process */ + +=09internals =3D eth_dev->data->dev_private; +=09internals->packet_size =3D packet_size; +=09internals->packet_copy =3D packet_copy; +=09internals->port_id =3D eth_dev->data->port_id; +=09rte_eth_random_addr(internals->eth_addr.addr_bytes); + +=09internals->flow_type_rss_offloads =3D ETH_RSS_PROTO_MASK; +=09internals->reta_size =3D RTE_DIM(internals->reta_conf) * RTE_RETA_GROUP= _SIZE; + +=09rte_memcpy(internals->rss_key, default_rss_key, 40); + +=09data =3D eth_dev->data; +=09data->nb_rx_queues =3D (uint16_t)nb_rx_queues; +=09data->nb_tx_queues =3D (uint16_t)nb_tx_queues; +=09data->dev_link =3D pmd_link; +=09data->mac_addrs =3D &internals->eth_addr; +=09data->promiscuous =3D 1; +=09data->all_multicast =3D 1; + +=09eth_dev->dev_ops =3D &ops; + +=09/* finally assign rx and tx ops */ +=09if (packet_copy) { +=09=09eth_dev->rx_pkt_burst =3D eth_dpdkoin_copy_rx; +=09=09eth_dev->tx_pkt_burst =3D eth_dpdkoin_copy_tx; +=09} else { +=09=09eth_dev->rx_pkt_burst =3D eth_dpdkoin_rx; +=09=09eth_dev->tx_pkt_burst =3D eth_dpdkoin_tx; +=09} + +=09rte_eth_dev_probing_finish(eth_dev); + +=09bitcoin_init(&bc); + +=09return 0; +} + +static inline int +get_packet_size_arg(const char *key __rte_unused, +=09=09const char *value, void *extra_args) +{ +=09const char *a =3D value; +=09unsigned *packet_size =3D extra_args; + +=09if ((value =3D=3D NULL) || (extra_args =3D=3D NULL)) +=09=09return -EINVAL; + +=09*packet_size =3D (unsigned)strtoul(a, NULL, 0); +=09if (*packet_size =3D=3D UINT_MAX) +=09=09return -1; + +=09return 0; +} + +static inline int +get_packet_copy_arg(const char *key __rte_unused, +=09=09const char *value, void *extra_args) +{ +=09const char *a =3D value; +=09unsigned *packet_copy =3D extra_args; + +=09if ((value =3D=3D NULL) || (extra_args =3D=3D NULL)) +=09=09return -EINVAL; + +=09*packet_copy =3D (unsigned)strtoul(a, NULL, 0); +=09if (*packet_copy =3D=3D UINT_MAX) +=09=09return -1; + +=09return 0; +} + +static int +rte_pmd_dpdkoin_probe(struct rte_vdev_device *dev) +{ +=09const char *name, *params; +=09unsigned packet_size =3D default_packet_size; +=09unsigned packet_copy =3D default_packet_copy; +=09struct rte_kvargs *kvlist =3D NULL; +=09struct rte_eth_dev *eth_dev; +=09int ret; + +=09if (!dev) +=09=09return -EINVAL; + +=09name =3D rte_vdev_device_name(dev); +=09params =3D rte_vdev_device_args(dev); +=09PMD_LOG(INFO, "Initializing pmd_dpdkoin for %s", name); + +=09if (rte_eal_process_type() =3D=3D RTE_PROC_SECONDARY) { +=09=09eth_dev =3D rte_eth_dev_attach_secondary(name); +=09=09if (!eth_dev) { +=09=09=09PMD_LOG(ERR, "Failed to probe %s", name); +=09=09=09return -1; +=09=09} +=09=09/* TODO: request info from primary to set up Rx and Tx */ +=09=09eth_dev->dev_ops =3D &ops; +=09=09eth_dev->device =3D &dev->device; +=09=09if (packet_copy) { +=09=09=09eth_dev->rx_pkt_burst =3D eth_dpdkoin_copy_rx; +=09=09=09eth_dev->tx_pkt_burst =3D eth_dpdkoin_copy_tx; +=09=09} else { +=09=09=09eth_dev->rx_pkt_burst =3D eth_dpdkoin_rx; +=09=09=09eth_dev->tx_pkt_burst =3D eth_dpdkoin_tx; +=09=09} +=09=09rte_eth_dev_probing_finish(eth_dev); +=09=09return 0; +=09} + +=09if (params !=3D NULL) { +=09=09kvlist =3D rte_kvargs_parse(params, valid_arguments); +=09=09if (kvlist =3D=3D NULL) +=09=09=09return -1; + +=09=09if (rte_kvargs_count(kvlist, ETH_DPDKOIN_PACKET_SIZE_ARG) =3D=3D 1) = { + +=09=09=09ret =3D rte_kvargs_process(kvlist, +=09=09=09=09=09ETH_DPDKOIN_PACKET_SIZE_ARG, +=09=09=09=09=09&get_packet_size_arg, &packet_size); +=09=09=09if (ret < 0) +=09=09=09=09goto free_kvlist; +=09=09} + +=09=09if (rte_kvargs_count(kvlist, ETH_DPDKOIN_PACKET_COPY_ARG) =3D=3D 1) = { + +=09=09=09ret =3D rte_kvargs_process(kvlist, +=09=09=09=09=09ETH_DPDKOIN_PACKET_COPY_ARG, +=09=09=09=09=09&get_packet_copy_arg, &packet_copy); +=09=09=09if (ret < 0) +=09=09=09=09goto free_kvlist; +=09=09} +=09} + +=09PMD_LOG(INFO, "Configure pmd_dpdkoin: packet size is %d, " +=09=09=09"packet copy is %s", packet_size, +=09=09=09packet_copy ? "enabled" : "disabled"); + +=09ret =3D eth_dev_dpdkoin_create(dev, packet_size, packet_copy); + +free_kvlist: +=09if (kvlist) +=09=09rte_kvargs_free(kvlist); +=09return ret; +} + +static int +rte_pmd_dpdkoin_remove(struct rte_vdev_device *dev) +{ +=09struct rte_eth_dev *eth_dev =3D NULL; + +=09if (!dev) +=09=09return -EINVAL; + +=09PMD_LOG(INFO, "Closing dpdkoin ethdev on numa socket %u", +=09=09=09rte_socket_id()); + +=09/* find the ethdev entry */ +=09eth_dev =3D rte_eth_dev_allocated(rte_vdev_device_name(dev)); +=09if (eth_dev =3D=3D NULL) +=09=09return -1; + +=09if (rte_eal_process_type() =3D=3D RTE_PROC_PRIMARY) +=09=09/* mac_addrs must not be freed alone because part of dev_private */ +=09=09eth_dev->data->mac_addrs =3D NULL; + +=09rte_eth_dev_release_port(eth_dev); + +=09return 0; +} + +static struct rte_vdev_driver pmd_dpdkoin_drv =3D { +=09.probe =3D rte_pmd_dpdkoin_probe, +=09.remove =3D 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, +=09"size=3D " +=09"copy=3D"); + +RTE_INIT(eth_dpdkoin_init_log) +{ +=09eth_dpdkoin_logtype =3D rte_log_register("pmd.net.dpdkoin"); +=09if (eth_dpdkoin_logtype >=3D 0) +=09=09rte_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 { +=09local: *; +}; 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) +=3D -lrte_= pmd_mvpp2 _LDLIBS-$(CONFIG_RTE_LIBRTE_MVNETA_PMD) +=3D -lrte_pmd_mvneta _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) +=3D -lrte_pmd_nfp _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL) +=3D -lrte_pmd_null +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPDKOIN) +=3D -lrte_pmd_dpdkoin -lbitco= in _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX2_PMD) +=3D -lrte_pmd_octeontx2 -lm _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) +=3D -lrte_pmd_pcap -lpcap _LDLIBS-$(CONFIG_RTE_LIBRTE_PFE_PMD) +=3D -lrte_pmd_pfe --=20 2.25.1