List patch comments

GET /api/patches/431/comments/?format=api&order=-date
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Link: 
<https://patches.dpdk.org/api/patches/431/comments/?format=api&order=-date&page=1>; rel="first",
<https://patches.dpdk.org/api/patches/431/comments/?format=api&order=-date&page=1>; rel="last"
Vary: Accept
[ { "id": 889, "web_url": "https://patches.dpdk.org/comment/889/", "msgid": "<541FD8CA.7060500@igel.co.jp>", "list_archive_url": "https://inbox.dpdk.org/dev/541FD8CA.7060500@igel.co.jp", "date": "2014-09-22T08:07:38", "subject": "Re: [dpdk-dev] [RFC] librte_pmd_null: Add null PMD", "submitter": { "id": 64, "url": "https://patches.dpdk.org/api/people/64/?format=api", "name": "Tetsuya Mukawa", "email": "mukawa@igel.co.jp" }, "content": "Hi Ivan\n\n(2014/09/22 16:46), Ivan Boule wrote:\n>\n> This is a \"nice to have\" PMD.\n>\n> Just a minor comment.\n> I guess it should be NTT instead of Intel in the following comment\n> \"# * Neither the name of Intel Corporation nor the names of its\".\n>\nI appreciate your comment. I will rewrite and post it again.\n\nRegards,\nTetsuya\n\n\n> Regards,\n> Ivan\n>\n>>\n>> Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>\n>> ---\n>> config/common_bsdapp | 5 +\n>> config/common_linuxapp | 5 +\n>> lib/Makefile | 1 +\n>> lib/librte_pmd_null/Makefile | 58 +++++\n>> lib/librte_pmd_null/rte_eth_null.c | 474\n>> +++++++++++++++++++++++++++++++++++++\n>> 5 files changed, 543 insertions(+)\n>> create mode 100644 lib/librte_pmd_null/Makefile\n>> create mode 100644 lib/librte_pmd_null/rte_eth_null.c\n>>\n>> diff --git a/config/common_bsdapp b/config/common_bsdapp\n>> index 645949f..a86321f 100644\n>> --- a/config/common_bsdapp\n>> +++ b/config/common_bsdapp\n>> @@ -226,6 +226,11 @@ CONFIG_RTE_LIBRTE_PMD_PCAP=y\n>> CONFIG_RTE_LIBRTE_PMD_BOND=y\n>>\n>> #\n>> +# Compile null PMD\n>> +#\n>> +CONFIG_RTE_LIBRTE_PMD_NULL=y\n>> +\n>> +#\n>> # Do prefetch of packet data within PMD driver receive function\n>> #\n>> CONFIG_RTE_PMD_PACKET_PREFETCH=y\n>> diff --git a/config/common_linuxapp b/config/common_linuxapp\n>> index 5bee910..e3bd8c0 100644\n>> --- a/config/common_linuxapp\n>> +++ b/config/common_linuxapp\n>> @@ -254,6 +254,11 @@ CONFIG_RTE_LIBRTE_PMD_BOND=y\n>> CONFIG_RTE_LIBRTE_PMD_XENVIRT=n\n>>\n>> #\n>> +# Compile null PMD\n>> +#\n>> +CONFIG_RTE_LIBRTE_PMD_NULL=y\n>> +\n>> +#\n>> # Do prefetch of packet data within PMD driver receive function\n>> #\n>> CONFIG_RTE_PMD_PACKET_PREFETCH=y\n>> diff --git a/lib/Makefile b/lib/Makefile\n>> index 10c5bb3..61d6ed1 100644\n>> --- a/lib/Makefile\n>> +++ b/lib/Makefile\n>> @@ -50,6 +50,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap\n>> DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio\n>> DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3\n>> DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt\n>> +DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += librte_pmd_null\n>> DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash\n>> DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm\n>> DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl\n>> diff --git a/lib/librte_pmd_null/Makefile b/lib/librte_pmd_null/Makefile\n>> new file mode 100644\n>> index 0000000..e017918\n>> --- /dev/null\n>> +++ b/lib/librte_pmd_null/Makefile\n>> @@ -0,0 +1,58 @@\n>> +# BSD LICENSE\n>> +#\n>> +# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.\n>> +# All rights reserved.\n>> +#\n>> +# Redistribution and use in source and binary forms, with or without\n>> +# modification, are permitted provided that the following conditions\n>> +# are met:\n>> +#\n>> +# * Redistributions of source code must retain the above copyright\n>> +# notice, this list of conditions and the following disclaimer.\n>> +# * Redistributions in binary form must reproduce the above\n>> copyright\n>> +# notice, this list of conditions and the following disclaimer in\n>> +# the documentation and/or other materials provided with the\n>> +# distribution.\n>> +# * Neither the name of Intel Corporation nor the names of its\n>> +# contributors may be used to endorse or promote products derived\n>> +# from this software without specific prior written permission.\n>> +#\n>> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n>> +# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n>> +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n>> FITNESS FOR\n>> +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n>> COPYRIGHT\n>> +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n>> INCIDENTAL,\n>> +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n>> +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n>> USE,\n>> +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n>> ON ANY\n>> +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n>> +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n>> THE USE\n>> +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n>> DAMAGE.\n>> +\n>> +include $(RTE_SDK)/mk/rte.vars.mk\n>> +\n>> +#\n>> +# library name\n>> +#\n>> +LIB = librte_pmd_null.a\n>> +\n>> +CFLAGS += -O3\n>> +CFLAGS += $(WERROR_FLAGS)\n>> +\n>> +#\n>> +# all source are stored in SRCS-y\n>> +#\n>> +SRCS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += rte_eth_null.c\n>> +\n>> +#\n>> +# Export include files\n>> +#\n>> +SYMLINK-y-include +=\n>> +\n>> +# this lib depends upon:\n>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_mbuf\n>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_ether\n>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_malloc\n>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_kvargs\n>> +\n>> +include $(RTE_SDK)/mk/rte.lib.mk\n>> diff --git a/lib/librte_pmd_null/rte_eth_null.c\n>> b/lib/librte_pmd_null/rte_eth_null.c\n>> new file mode 100644\n>> index 0000000..1a81843\n>> --- /dev/null\n>> +++ b/lib/librte_pmd_null/rte_eth_null.c\n>> @@ -0,0 +1,474 @@\n>> +/*-\n>> + * BSD LICENSE\n>> + *\n>> + * Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.\n>> + * All rights reserved.\n>> + *\n>> + * Redistribution and use in source and binary forms, with or without\n>> + * modification, are permitted provided that the following conditions\n>> + * are met:\n>> + *\n>> + * * Redistributions of source code must retain the above copyright\n>> + * notice, this list of conditions and the following disclaimer.\n>> + * * Redistributions in binary form must reproduce the above\n>> copyright\n>> + * notice, this list of conditions and the following\n>> disclaimer in\n>> + * the documentation and/or other materials provided with the\n>> + * distribution.\n>> + * * Neither the name of Intel Corporation nor the names of its\n>> + * contributors may be used to endorse or promote products\n>> derived\n>> + * from this software without specific prior written permission.\n>> + *\n>> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n>> CONTRIBUTORS\n>> + * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n>> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n>> FITNESS FOR\n>> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n>> COPYRIGHT\n>> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n>> INCIDENTAL,\n>> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n>> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n>> OF USE,\n>> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n>> ON ANY\n>> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n>> TORT\n>> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n>> THE USE\n>> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n>> DAMAGE.\n>> + */\n>> +\n>> +#include <rte_mbuf.h>\n>> +#include <rte_ethdev.h>\n>> +#include <rte_malloc.h>\n>> +#include <rte_memcpy.h>\n>> +#include <rte_dev.h>\n>> +#include <rte_kvargs.h>\n>> +\n>> +#define ETH_NULL_PACKET_SIZE_ARG \"size\"\n>> +#define ETH_NULL_PACKET_COPY_ARG \"copy\"\n>> +\n>> +static unsigned default_packet_size = 64;\n>> +static unsigned default_packet_copy;\n>> +\n>> +static const char const *valid_arguments[] = {\n>> + ETH_NULL_PACKET_SIZE_ARG,\n>> + ETH_NULL_PACKET_COPY_ARG,\n>> + NULL\n>> +};\n>> +\n>> +struct pmd_internals;\n>> +\n>> +struct null_queue {\n>> + struct pmd_internals *internals;\n>> +\n>> + struct rte_mempool *mb_pool;\n>> + struct rte_mbuf *dummy_packet;\n>> +\n>> + rte_atomic64_t rx_pkts;\n>> + rte_atomic64_t tx_pkts;\n>> + rte_atomic64_t err_pkts;\n>> +};\n>> +\n>> +struct pmd_internals {\n>> + unsigned packet_size;\n>> + unsigned packet_copy;\n>> + unsigned numa_node;\n>> +\n>> + unsigned nb_rx_queues;\n>> + unsigned nb_tx_queues;\n>> +\n>> + struct null_queue rx_null_queues[1];\n>> + struct null_queue tx_null_queues[1];\n>> +};\n>> +\n>> +\n>> +static struct ether_addr eth_addr = { .addr_bytes = {0} };\n>> +static const char *drivername = \"Null PMD\";\n>> +static struct rte_eth_link pmd_link = {\n>> + .link_speed = 10000,\n>> + .link_duplex = ETH_LINK_FULL_DUPLEX,\n>> + .link_status = 0\n>> +};\n>> +\n>> +static uint16_t\n>> +eth_null_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n>> +{\n>> + int i;\n>> + struct null_queue *h = q;\n>> + unsigned packet_size = h->internals->packet_size;\n>> +\n>> + for (i = 0; i < nb_bufs; i++) {\n>> + bufs[i] = rte_pktmbuf_alloc(h->mb_pool);\n>> + if (!bufs[i])\n>> + break;\n>> + bufs[i]->data_len = (uint16_t)packet_size;\n>> + bufs[i]->pkt_len = packet_size;\n>> + bufs[i]->nb_segs = 1;\n>> + bufs[i]->next = NULL;\n>> + }\n>> +\n>> + rte_atomic64_add(&(h->rx_pkts), i);\n>> +\n>> + return i;\n>> +}\n>> +\n>> +static uint16_t\n>> +eth_null_copy_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n>> +{\n>> + int i;\n>> + struct null_queue *h = q;\n>> + unsigned packet_size = h->internals->packet_size;\n>> +\n>> + for (i = 0; i < nb_bufs; i++) {\n>> + bufs[i] = rte_pktmbuf_alloc(h->mb_pool);\n>> + if (!bufs[i])\n>> + break;\n>> + rte_memcpy(rte_pktmbuf_mtod(bufs[i], void *), h->dummy_packet,\n>> + packet_size);\n>> + bufs[i]->data_len = (uint16_t)packet_size;\n>> + bufs[i]->pkt_len = packet_size;\n>> + bufs[i]->nb_segs = 1;\n>> + bufs[i]->next = NULL;\n>> + }\n>> +\n>> + rte_atomic64_add(&(h->rx_pkts), i);\n>> +\n>> + return i;\n>> +}\n>> +\n>> +static uint16_t\n>> +eth_null_tx(void *q, struct rte_mbuf **bufs __rte_unused, uint16_t\n>> nb_bufs)\n>> +{\n>> + int i;\n>> + struct null_queue *h = q;\n>> +\n>> + for (i = 0; i < nb_bufs; i++)\n>> + rte_pktmbuf_free(bufs[i]);\n>> +\n>> + rte_atomic64_add(&(h->tx_pkts), i);\n>> +\n>> + return i;\n>> +}\n>> +\n>> +static uint16_t\n>> +eth_null_copy_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n>> +{\n>> + int i;\n>> + struct null_queue *h = q;\n>> + unsigned packet_size = h->internals->packet_size;\n>> +\n>> + for (i = 0; i < nb_bufs; i++) {\n>> + rte_memcpy(h->dummy_packet, rte_pktmbuf_mtod(bufs[i], void *),\n>> + packet_size);\n>> + rte_pktmbuf_free(bufs[i]);\n>> + }\n>> +\n>> + rte_atomic64_add(&(h->tx_pkts), i);\n>> +\n>> + return i;\n>> +}\n>> +\n>> +static int\n>> +eth_dev_configure(struct rte_eth_dev *dev __rte_unused) { return 0; }\n>> +\n>> +static int\n>> +eth_dev_start(struct rte_eth_dev *dev)\n>> +{\n>> + dev->data->dev_link.link_status = 1;\n>> + return 0;\n>> +}\n>> +\n>> +static void\n>> +eth_dev_stop(struct rte_eth_dev *dev)\n>> +{\n>> + dev->data->dev_link.link_status = 0;\n>> +}\n>> +\n>> +static int\n>> +eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,\n>> + uint16_t nb_rx_desc __rte_unused,\n>> + unsigned int socket_id __rte_unused,\n>> + const struct rte_eth_rxconf *rx_conf __rte_unused,\n>> + struct rte_mempool *mb_pool __rte_unused)\n>> +{\n>> + struct rte_mbuf *dummy_packet;\n>> + struct pmd_internals *internals = dev->data->dev_private;\n>> + unsigned packet_size = internals->packet_size;\n>> +\n>> + if (rx_queue_id != 0)\n>> + return -ENODEV;\n>> +\n>> + internals->rx_null_queues[rx_queue_id].mb_pool = mb_pool;\n>> + dev->data->rx_queues[rx_queue_id] =\n>> + &internals->rx_null_queues[rx_queue_id];\n>> + dummy_packet = rte_zmalloc_socket(NULL,\n>> + packet_size, 0, internals->numa_node);\n>> + if (dummy_packet == NULL)\n>> + return -ENOMEM;\n>> +\n>> + internals->rx_null_queues[rx_queue_id].internals = internals;\n>> + internals->rx_null_queues[rx_queue_id].dummy_packet = dummy_packet;\n>> +\n>> + return 0;\n>> +}\n>> +\n>> +static int\n>> +eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,\n>> + uint16_t nb_tx_desc __rte_unused,\n>> + unsigned int socket_id __rte_unused,\n>> + const struct rte_eth_txconf *tx_conf __rte_unused)\n>> +{\n>> + struct rte_mbuf *dummy_packet;\n>> + struct pmd_internals *internals = dev->data->dev_private;\n>> + unsigned packet_size = internals->packet_size;\n>> +\n>> + if (tx_queue_id != 0)\n>> + return -ENODEV;\n>> +\n>> + dev->data->tx_queues[tx_queue_id] =\n>> + &internals->tx_null_queues[tx_queue_id];\n>> + dummy_packet = rte_zmalloc_socket(NULL,\n>> + packet_size, 0, internals->numa_node);\n>> + if (dummy_packet == NULL)\n>> + return -ENOMEM;\n>> +\n>> + internals->tx_null_queues[tx_queue_id].internals = internals;\n>> + internals->tx_null_queues[tx_queue_id].dummy_packet = dummy_packet;\n>> +\n>> + return 0;\n>> +}\n>> +\n>> +\n>> +static void\n>> +eth_dev_info(struct rte_eth_dev *dev,\n>> + struct rte_eth_dev_info *dev_info)\n>> +{\n>> + struct pmd_internals *internals = dev->data->dev_private;\n>> +\n>> + dev_info->driver_name = drivername;\n>> + dev_info->max_mac_addrs = 1;\n>> + dev_info->max_rx_pktlen = (uint32_t)-1;\n>> + dev_info->max_rx_queues = (uint16_t)internals->nb_rx_queues;\n>> + dev_info->max_tx_queues = (uint16_t)internals->nb_tx_queues;\n>> + dev_info->min_rx_bufsize = 0;\n>> + dev_info->pci_dev = NULL;\n>> +}\n>> +\n>> +static void\n>> +eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats)\n>> +{\n>> + unsigned i;\n>> + unsigned long rx_total = 0, tx_total = 0, tx_err_total = 0;\n>> + const struct pmd_internals *internal = dev->data->dev_private;\n>> +\n>> + memset(igb_stats, 0, sizeof(*igb_stats));\n>> + for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&\n>> + i < internal->nb_rx_queues; i++) {\n>> + igb_stats->q_ipackets[i] =\n>> + internal->rx_null_queues[i].rx_pkts.cnt;\n>> + rx_total += igb_stats->q_ipackets[i];\n>> + }\n>> +\n>> + for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&\n>> + i < internal->nb_tx_queues; i++) {\n>> + igb_stats->q_opackets[i] =\n>> + internal->tx_null_queues[i].tx_pkts.cnt;\n>> + igb_stats->q_errors[i] =\n>> + internal->tx_null_queues[i].err_pkts.cnt;\n>> + tx_total += igb_stats->q_opackets[i];\n>> + tx_err_total += igb_stats->q_errors[i];\n>> + }\n>> +\n>> + igb_stats->ipackets = rx_total;\n>> + igb_stats->opackets = tx_total;\n>> + igb_stats->oerrors = tx_err_total;\n>> +}\n>> +\n>> +static void\n>> +eth_stats_reset(struct rte_eth_dev *dev)\n>> +{\n>> + unsigned i;\n>> + struct pmd_internals *internal = dev->data->dev_private;\n>> +\n>> + for (i = 0; i < internal->nb_rx_queues; i++)\n>> + internal->rx_null_queues[i].rx_pkts.cnt = 0;\n>> + for (i = 0; i < internal->nb_tx_queues; i++) {\n>> + internal->tx_null_queues[i].tx_pkts.cnt = 0;\n>> + internal->tx_null_queues[i].err_pkts.cnt = 0;\n>> + }\n>> +}\n>> +\n>> +static void\n>> +eth_queue_release(void *q __rte_unused) { ; }\n>> +static int\n>> +eth_link_update(struct rte_eth_dev *dev __rte_unused,\n>> + int wait_to_complete __rte_unused) { return 0; }\n>> +\n>> +static struct eth_dev_ops ops = {\n>> + .dev_start = eth_dev_start,\n>> + .dev_stop = eth_dev_stop,\n>> + .dev_configure = eth_dev_configure,\n>> + .dev_infos_get = eth_dev_info,\n>> + .rx_queue_setup = eth_rx_queue_setup,\n>> + .tx_queue_setup = eth_tx_queue_setup,\n>> + .rx_queue_release = eth_queue_release,\n>> + .tx_queue_release = eth_queue_release,\n>> + .link_update = eth_link_update,\n>> + .stats_get = eth_stats_get,\n>> + .stats_reset = eth_stats_reset,\n>> +};\n>> +\n>> +static int\n>> +eth_dev_null_create(const char *name __rte_unused,\n>> + const unsigned numa_node,\n>> + unsigned packet_size,\n>> + unsigned packet_copy)\n>> +{\n>> + const unsigned nb_rx_queues = 1;\n>> + const unsigned nb_tx_queues = 1;\n>> + struct rte_eth_dev_data *data = NULL;\n>> + struct rte_pci_device *pci_dev = NULL;\n>> + struct pmd_internals *internals = NULL;\n>> + struct rte_eth_dev *eth_dev = NULL;\n>> +\n>> + RTE_LOG(INFO, PMD, \"Creating null ethdev on numa socket %u\\n\",\n>> + numa_node);\n>> +\n>> + /* now do all data allocation - for eth_dev structure, dummy pci\n>> driver\n>> + * and internal (private) data\n>> + */\n>> + data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);\n>> + if (data == NULL)\n>> + goto error;\n>> +\n>> + pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);\n>> + if (pci_dev == NULL)\n>> + goto error;\n>> +\n>> + internals = rte_zmalloc_socket(name, sizeof(*internals), 0,\n>> numa_node);\n>> + if (internals == NULL)\n>> + goto error;\n>> +\n>> + /* reserve an ethdev entry */\n>> + eth_dev = rte_eth_dev_allocate(name);\n>> + if (eth_dev == NULL)\n>> + goto error;\n>> +\n>> + /* now put it all together\n>> + * - store queue data in internals,\n>> + * - store numa_node info in pci_driver\n>> + * - point eth_dev_data to internals and pci_driver\n>> + * - and point eth_dev structure to new eth_dev_data structure\n>> + */\n>> + /* NOTE: we'll replace the data element, of originally allocated\n>> eth_dev\n>> + * so the nulls are local per-process */\n>> +\n>> + internals->nb_rx_queues = nb_rx_queues;\n>> + internals->nb_tx_queues = nb_tx_queues;\n>> + internals->packet_size = packet_size;\n>> + internals->packet_copy = packet_copy;\n>> + internals->numa_node = numa_node;\n>> +\n>> + pci_dev->numa_node = numa_node;\n>> +\n>> + data->dev_private = internals;\n>> + data->port_id = eth_dev->data->port_id;\n>> + data->nb_rx_queues = (uint16_t)nb_rx_queues;\n>> + data->nb_tx_queues = (uint16_t)nb_tx_queues;\n>> + data->dev_link = pmd_link;\n>> + data->mac_addrs = &eth_addr;\n>> +\n>> + eth_dev->data = data;\n>> + eth_dev->dev_ops = &ops;\n>> + eth_dev->pci_dev = pci_dev;\n>> +\n>> + /* finally assign rx and tx ops */\n>> + if (packet_copy) {\n>> + eth_dev->rx_pkt_burst = eth_null_copy_rx;\n>> + eth_dev->tx_pkt_burst = eth_null_copy_tx;\n>> + } else {\n>> + eth_dev->rx_pkt_burst = eth_null_rx;\n>> + eth_dev->tx_pkt_burst = eth_null_tx;\n>> + }\n>> +\n>> + return 0;\n>> +\n>> +error:\n>> + if (data)\n>> + rte_free(data);\n>> + if (pci_dev)\n>> + rte_free(pci_dev);\n>> + if (internals)\n>> + rte_free(internals);\n>> + return -1;\n>> +}\n>> +\n>> +static inline int\n>> +get_packet_size_arg(const char *key __rte_unused,\n>> + const char *value, void *extra_args)\n>> +{\n>> + const char *a = value;\n>> + unsigned *packet_size = extra_args;\n>> +\n>> + *packet_size = (unsigned)strtoul(a, NULL, 0);\n>> + if (*packet_size == UINT_MAX)\n>> + return -1;\n>> +\n>> + return 0;\n>> +}\n>> +\n>> +static inline int\n>> +get_packet_copy_arg(const char *key __rte_unused,\n>> + const char *value, void *extra_args)\n>> +{\n>> + const char *a = value;\n>> + unsigned *packet_copy = extra_args;\n>> +\n>> + *packet_copy = (unsigned)strtoul(a, NULL, 0);\n>> + if (*packet_copy == UINT_MAX)\n>> + return -1;\n>> +\n>> + return 0;\n>> +}\n>> +\n>> +static int\n>> +rte_pmd_null_devinit(const char *name, const char *params)\n>> +{\n>> + unsigned numa_node;\n>> + unsigned packet_size = default_packet_size;\n>> + unsigned packet_copy = default_packet_copy;\n>> + struct rte_kvargs *kvlist;\n>> + int ret;\n>> +\n>> + RTE_LOG(INFO, PMD, \"Initializing pmd_null for %s\\n\", name);\n>> +\n>> + numa_node = rte_socket_id();\n>> +\n>> + kvlist = rte_kvargs_parse(params, valid_arguments);\n>> + if (kvlist == NULL)\n>> + return -1;\n>> +\n>> + if (rte_kvargs_count(kvlist, ETH_NULL_PACKET_SIZE_ARG) == 1) {\n>> +\n>> + ret = rte_kvargs_process(kvlist, ETH_NULL_PACKET_SIZE_ARG,\n>> + &get_packet_size_arg, &packet_size);\n>> + if (ret < 0)\n>> + return -1;\n>> + }\n>> +\n>> + if (rte_kvargs_count(kvlist, ETH_NULL_PACKET_COPY_ARG) == 1) {\n>> +\n>> + ret = rte_kvargs_process(kvlist, ETH_NULL_PACKET_COPY_ARG,\n>> + &get_packet_copy_arg, &packet_copy);\n>> + if (ret < 0)\n>> + return -1;\n>> + }\n>> +\n>> + RTE_LOG(INFO, PMD, \"Configure pmd_null: packet size is %d, \"\n>> + \"packet copy is %s\\n\", packet_size,\n>> + packet_copy ? \"enabled\" : \"disabled\");\n>> +\n>> + return eth_dev_null_create(name, numa_node, packet_size,\n>> packet_copy);\n>> +}\n>> +\n>> +static struct rte_driver pmd_null_drv = {\n>> + .name = \"eth_null\",\n>> + .type = PMD_VDEV,\n>> + .init = rte_pmd_null_devinit,\n>> +};\n>> +\n>> +PMD_REGISTER_DRIVER(pmd_null_drv);\n>>\n>\n>", "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@dpdk.org", "Delivered-To": "patchwork@dpdk.org", "Received": [ "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 97D432E81;\n\tMon, 22 Sep 2014 10:01:41 +0200 (CEST)", "from mail-pa0-f49.google.com (mail-pa0-f49.google.com\n\t[209.85.220.49]) by dpdk.org (Postfix) with ESMTP id C16FA231C\n\tfor <dev@dpdk.org>; Mon, 22 Sep 2014 10:01:39 +0200 (CEST)", "by mail-pa0-f49.google.com with SMTP id lf10so4027459pab.8\n\tfor <dev@dpdk.org>; Mon, 22 Sep 2014 01:07:41 -0700 (PDT)", "from [10.16.129.101] (napt.igel.co.jp. [219.106.231.132])\n\tby mx.google.com with ESMTPSA id\n\tca3sm8532259pbb.80.2014.09.22.01.07.39 for <multiple recipients>\n\t(version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);\n\tMon, 22 Sep 2014 01:07:41 -0700 (PDT)" ], "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:message-id:date:from:user-agent:mime-version:to\n\t:cc:subject:references:in-reply-to:content-type\n\t:content-transfer-encoding;\n\tbh=uk/lh54nqkmzW5PYYYs5SF/ZNtE/3rzsemjYD71u84g=;\n\tb=OYcY/9WCcP5P2rUNbDc2kYwcA3FiXBTOqeFZPaRzqoyUz/75IGnobMK28yCMaRtKyL\n\tnTRjaRzvkBGKwFknx1KFQGZPqe56qgtjMKMyh7FybT76PxnyT9hZmdYOEi57QCDc/FVp\n\t25dmHUG/EMWQWQYc7sngtmqWiirW/ZiNHkPwYe/S7/aozGJUJhSMN6fJKm/YONLTtgcN\n\t07IKzlsr55V6rFqDSKyWOQosglwIS5emCIezIdl2vNYO3oM52Ociw3J6j5rBQUMPRQq4\n\td/+dVEvzbwPDfglKgphN5MJovXI9qiKkVJmTzra5dUfQrYOv+Zk3lJGixRHWFP1rvFOg\n\tjokA==", "X-Gm-Message-State": "ALoCoQm63CRYyEyqLkL7GWO7Xm8BhevSFF58/pJLpOUd+ZPbWPQ0M7VGmmnd3/+ug1VR0DCayPFF", "X-Received": "by 10.70.92.9 with SMTP id ci9mr26530740pdb.106.1411373261776;\n\tMon, 22 Sep 2014 01:07:41 -0700 (PDT)", "Message-ID": "<541FD8CA.7060500@igel.co.jp>", "Date": "Mon, 22 Sep 2014 17:07:38 +0900", "From": "Tetsuya Mukawa <mukawa@igel.co.jp>", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64;\n\trv:24.0) Gecko/20100101 Thunderbird/24.6.0", "MIME-Version": "1.0", "To": "Ivan Boule <ivan.boule@6wind.com>, dev@dpdk.org", "References": "<mukawa@igel.co.jp>\n\t<1411129659-7132-1-git-send-email-mukawa@igel.co.jp>\n\t<1411129659-7132-2-git-send-email-mukawa@igel.co.jp>\n\t<541FD3BD.2060606@6wind.com>", "In-Reply-To": "<541FD3BD.2060606@6wind.com>", "Content-Type": "text/plain; charset=ISO-8859-1", "Content-Transfer-Encoding": "7bit", "Cc": "nakajima.yoshihiro@lab.ntt.co.jp, masutani.hitoshi@lab.ntt.co.jp", "Subject": "Re: [dpdk-dev] [RFC] librte_pmd_null: Add null PMD", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "patches and discussions about DPDK <dev.dpdk.org>", "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://dpdk.org/ml/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "addressed": null }, { "id": 888, "web_url": "https://patches.dpdk.org/comment/888/", "msgid": "<541FD3BD.2060606@6wind.com>", "list_archive_url": "https://inbox.dpdk.org/dev/541FD3BD.2060606@6wind.com", "date": "2014-09-22T07:46:05", "subject": "Re: [dpdk-dev] [RFC] librte_pmd_null: Add null PMD", "submitter": { "id": 21, "url": "https://patches.dpdk.org/api/people/21/?format=api", "name": "Ivan Boule", "email": "ivan.boule@6wind.com" }, "content": "On 09/19/2014 02:27 PM, mukawa@igel.co.jp wrote:\n> From: Tetsuya Mukawa <mukawa@igel.co.jp>\n>\n> 'null PMD' is a virtual device driver particulary designed to measure\n> performance of DPDK applications and DPDK PMDs. When an application call rx,\n> null PMD just allocate mbufs and return those. Also tx, the PMD just free\n> mbufs.\n>\n> The PMD has following options.\n> - size: specify packe size allocated by RX. Default packet size is 64.\n> - copy: specify 1 or 0 to enable or disable copy while RX and TX.\n> \tDefault value is 0(disbaled).\n> \tThis option is used for emulating more realistic data transfer.\n> \tCopy size is equal to packet size.\nHi Tetsuya,\n\nThis is a \"nice to have\" PMD.\n\nJust a minor comment.\nI guess it should be NTT instead of Intel in the following comment\n\"# * Neither the name of Intel Corporation nor the names of its\".\n\nRegards,\nIvan\n\n>\n> Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>\n> ---\n> config/common_bsdapp | 5 +\n> config/common_linuxapp | 5 +\n> lib/Makefile | 1 +\n> lib/librte_pmd_null/Makefile | 58 +++++\n> lib/librte_pmd_null/rte_eth_null.c | 474 +++++++++++++++++++++++++++++++++++++\n> 5 files changed, 543 insertions(+)\n> create mode 100644 lib/librte_pmd_null/Makefile\n> create mode 100644 lib/librte_pmd_null/rte_eth_null.c\n>\n> diff --git a/config/common_bsdapp b/config/common_bsdapp\n> index 645949f..a86321f 100644\n> --- a/config/common_bsdapp\n> +++ b/config/common_bsdapp\n> @@ -226,6 +226,11 @@ CONFIG_RTE_LIBRTE_PMD_PCAP=y\n> CONFIG_RTE_LIBRTE_PMD_BOND=y\n>\n> #\n> +# Compile null PMD\n> +#\n> +CONFIG_RTE_LIBRTE_PMD_NULL=y\n> +\n> +#\n> # Do prefetch of packet data within PMD driver receive function\n> #\n> CONFIG_RTE_PMD_PACKET_PREFETCH=y\n> diff --git a/config/common_linuxapp b/config/common_linuxapp\n> index 5bee910..e3bd8c0 100644\n> --- a/config/common_linuxapp\n> +++ b/config/common_linuxapp\n> @@ -254,6 +254,11 @@ CONFIG_RTE_LIBRTE_PMD_BOND=y\n> CONFIG_RTE_LIBRTE_PMD_XENVIRT=n\n>\n> #\n> +# Compile null PMD\n> +#\n> +CONFIG_RTE_LIBRTE_PMD_NULL=y\n> +\n> +#\n> # Do prefetch of packet data within PMD driver receive function\n> #\n> CONFIG_RTE_PMD_PACKET_PREFETCH=y\n> diff --git a/lib/Makefile b/lib/Makefile\n> index 10c5bb3..61d6ed1 100644\n> --- a/lib/Makefile\n> +++ b/lib/Makefile\n> @@ -50,6 +50,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap\n> DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio\n> DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3\n> DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt\n> +DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += librte_pmd_null\n> DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash\n> DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm\n> DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl\n> diff --git a/lib/librte_pmd_null/Makefile b/lib/librte_pmd_null/Makefile\n> new file mode 100644\n> index 0000000..e017918\n> --- /dev/null\n> +++ b/lib/librte_pmd_null/Makefile\n> @@ -0,0 +1,58 @@\n> +# BSD LICENSE\n> +#\n> +# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.\n> +# All rights reserved.\n> +#\n> +# Redistribution and use in source and binary forms, with or without\n> +# modification, are permitted provided that the following conditions\n> +# are met:\n> +#\n> +# * Redistributions of source code must retain the above copyright\n> +# notice, this list of conditions and the following disclaimer.\n> +# * Redistributions in binary form must reproduce the above copyright\n> +# notice, this list of conditions and the following disclaimer in\n> +# the documentation and/or other materials provided with the\n> +# distribution.\n> +# * Neither the name of Intel Corporation nor the names of its\n> +# contributors may be used to endorse or promote products derived\n> +# from this software without specific prior written permission.\n> +#\n> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n> +# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n> +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n> +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n> +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n> +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n> +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n> +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n> +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n> +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n> +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n> +\n> +include $(RTE_SDK)/mk/rte.vars.mk\n> +\n> +#\n> +# library name\n> +#\n> +LIB = librte_pmd_null.a\n> +\n> +CFLAGS += -O3\n> +CFLAGS += $(WERROR_FLAGS)\n> +\n> +#\n> +# all source are stored in SRCS-y\n> +#\n> +SRCS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += rte_eth_null.c\n> +\n> +#\n> +# Export include files\n> +#\n> +SYMLINK-y-include +=\n> +\n> +# this lib depends upon:\n> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_mbuf\n> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_ether\n> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_malloc\n> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_kvargs\n> +\n> +include $(RTE_SDK)/mk/rte.lib.mk\n> diff --git a/lib/librte_pmd_null/rte_eth_null.c b/lib/librte_pmd_null/rte_eth_null.c\n> new file mode 100644\n> index 0000000..1a81843\n> --- /dev/null\n> +++ b/lib/librte_pmd_null/rte_eth_null.c\n> @@ -0,0 +1,474 @@\n> +/*-\n> + * BSD LICENSE\n> + *\n> + * Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.\n> + * All rights reserved.\n> + *\n> + * Redistribution and use in source and binary forms, with or without\n> + * modification, are permitted provided that the following conditions\n> + * are met:\n> + *\n> + * * Redistributions of source code must retain the above copyright\n> + * notice, this list of conditions and the following disclaimer.\n> + * * Redistributions in binary form must reproduce the above copyright\n> + * notice, this list of conditions and the following disclaimer in\n> + * the documentation and/or other materials provided with the\n> + * distribution.\n> + * * Neither the name of Intel Corporation nor the names of its\n> + * contributors may be used to endorse or promote products derived\n> + * from this software without specific prior written permission.\n> + *\n> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n> + * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n> + */\n> +\n> +#include <rte_mbuf.h>\n> +#include <rte_ethdev.h>\n> +#include <rte_malloc.h>\n> +#include <rte_memcpy.h>\n> +#include <rte_dev.h>\n> +#include <rte_kvargs.h>\n> +\n> +#define ETH_NULL_PACKET_SIZE_ARG\t\"size\"\n> +#define ETH_NULL_PACKET_COPY_ARG\t\"copy\"\n> +\n> +static unsigned default_packet_size = 64;\n> +static unsigned default_packet_copy;\n> +\n> +static const char const *valid_arguments[] = {\n> +\tETH_NULL_PACKET_SIZE_ARG,\n> +\tETH_NULL_PACKET_COPY_ARG,\n> +\tNULL\n> +};\n> +\n> +struct pmd_internals;\n> +\n> +struct null_queue {\n> +\tstruct pmd_internals *internals;\n> +\n> +\tstruct rte_mempool *mb_pool;\n> +\tstruct rte_mbuf *dummy_packet;\n> +\n> +\trte_atomic64_t rx_pkts;\n> +\trte_atomic64_t tx_pkts;\n> +\trte_atomic64_t err_pkts;\n> +};\n> +\n> +struct pmd_internals {\n> +\tunsigned packet_size;\n> +\tunsigned packet_copy;\n> +\tunsigned numa_node;\n> +\n> +\tunsigned nb_rx_queues;\n> +\tunsigned nb_tx_queues;\n> +\n> +\tstruct null_queue rx_null_queues[1];\n> +\tstruct null_queue tx_null_queues[1];\n> +};\n> +\n> +\n> +static struct ether_addr eth_addr = { .addr_bytes = {0} };\n> +static const char *drivername = \"Null PMD\";\n> +static struct rte_eth_link pmd_link = {\n> +\t.link_speed = 10000,\n> +\t.link_duplex = ETH_LINK_FULL_DUPLEX,\n> +\t.link_status = 0\n> +};\n> +\n> +static uint16_t\n> +eth_null_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n> +{\n> +\tint i;\n> +\tstruct null_queue *h = q;\n> +\tunsigned packet_size = h->internals->packet_size;\n> +\n> +\tfor (i = 0; i < nb_bufs; i++) {\n> +\t\tbufs[i] = rte_pktmbuf_alloc(h->mb_pool);\n> +\t\tif (!bufs[i])\n> +\t\t\tbreak;\n> +\t\tbufs[i]->data_len = (uint16_t)packet_size;\n> +\t\tbufs[i]->pkt_len = packet_size;\n> +\t\tbufs[i]->nb_segs = 1;\n> +\t\tbufs[i]->next = NULL;\n> +\t}\n> +\n> +\trte_atomic64_add(&(h->rx_pkts), i);\n> +\n> +\treturn i;\n> +}\n> +\n> +static uint16_t\n> +eth_null_copy_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n> +{\n> +\tint i;\n> +\tstruct null_queue *h = q;\n> +\tunsigned packet_size = h->internals->packet_size;\n> +\n> +\tfor (i = 0; i < nb_bufs; i++) {\n> +\t\tbufs[i] = rte_pktmbuf_alloc(h->mb_pool);\n> +\t\tif (!bufs[i])\n> +\t\t\tbreak;\n> +\t\trte_memcpy(rte_pktmbuf_mtod(bufs[i], void *), h->dummy_packet,\n> +\t\t\t\t\tpacket_size);\n> +\t\tbufs[i]->data_len = (uint16_t)packet_size;\n> +\t\tbufs[i]->pkt_len = packet_size;\n> +\t\tbufs[i]->nb_segs = 1;\n> +\t\tbufs[i]->next = NULL;\n> +\t}\n> +\n> +\trte_atomic64_add(&(h->rx_pkts), i);\n> +\n> +\treturn i;\n> +}\n> +\n> +static uint16_t\n> +eth_null_tx(void *q, struct rte_mbuf **bufs __rte_unused, uint16_t nb_bufs)\n> +{\n> +\tint i;\n> +\tstruct null_queue *h = q;\n> +\n> +\tfor (i = 0; i < nb_bufs; i++)\n> +\t\trte_pktmbuf_free(bufs[i]);\n> +\n> +\trte_atomic64_add(&(h->tx_pkts), i);\n> +\n> +\treturn i;\n> +}\n> +\n> +static uint16_t\n> +eth_null_copy_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n> +{\n> +\tint i;\n> +\tstruct null_queue *h = q;\n> +\tunsigned packet_size = h->internals->packet_size;\n> +\n> +\tfor (i = 0; i < nb_bufs; i++) {\n> +\t\trte_memcpy(h->dummy_packet, rte_pktmbuf_mtod(bufs[i], void *),\n> +\t\t\t\t\tpacket_size);\n> +\t\trte_pktmbuf_free(bufs[i]);\n> +\t}\n> +\n> +\trte_atomic64_add(&(h->tx_pkts), i);\n> +\n> +\treturn i;\n> +}\n> +\n> +static int\n> +eth_dev_configure(struct rte_eth_dev *dev __rte_unused) { return 0; }\n> +\n> +static int\n> +eth_dev_start(struct rte_eth_dev *dev)\n> +{\n> +\tdev->data->dev_link.link_status = 1;\n> +\treturn 0;\n> +}\n> +\n> +static void\n> +eth_dev_stop(struct rte_eth_dev *dev)\n> +{\n> +\tdev->data->dev_link.link_status = 0;\n> +}\n> +\n> +static int\n> +eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,\n> +\t\tuint16_t nb_rx_desc __rte_unused,\n> +\t\tunsigned int socket_id __rte_unused,\n> +\t\tconst struct rte_eth_rxconf *rx_conf __rte_unused,\n> +\t\tstruct rte_mempool *mb_pool __rte_unused)\n> +{\n> +\tstruct rte_mbuf *dummy_packet;\n> +\tstruct pmd_internals *internals = dev->data->dev_private;\n> +\tunsigned packet_size = internals->packet_size;\n> +\n> +\tif (rx_queue_id != 0)\n> +\t\t\treturn -ENODEV;\n> +\n> +\tinternals->rx_null_queues[rx_queue_id].mb_pool = mb_pool;\n> +\tdev->data->rx_queues[rx_queue_id] =\n> +\t\t&internals->rx_null_queues[rx_queue_id];\n> +\tdummy_packet = rte_zmalloc_socket(NULL,\n> +\t\t\tpacket_size, 0, internals->numa_node);\n> +\tif (dummy_packet == NULL)\n> +\t\treturn -ENOMEM;\n> +\n> +\tinternals->rx_null_queues[rx_queue_id].internals = internals;\n> +\tinternals->rx_null_queues[rx_queue_id].dummy_packet = dummy_packet;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int\n> +eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,\n> +\t\tuint16_t nb_tx_desc __rte_unused,\n> +\t\tunsigned int socket_id __rte_unused,\n> +\t\tconst struct rte_eth_txconf *tx_conf __rte_unused)\n> +{\n> +\tstruct rte_mbuf *dummy_packet;\n> +\tstruct pmd_internals *internals = dev->data->dev_private;\n> +\tunsigned packet_size = internals->packet_size;\n> +\n> +\tif (tx_queue_id != 0)\n> +\t\t\treturn -ENODEV;\n> +\n> +\tdev->data->tx_queues[tx_queue_id] =\n> +\t\t&internals->tx_null_queues[tx_queue_id];\n> +\tdummy_packet = rte_zmalloc_socket(NULL,\n> +\t\t\tpacket_size, 0, internals->numa_node);\n> +\tif (dummy_packet == NULL)\n> +\t\treturn -ENOMEM;\n> +\n> +\tinternals->tx_null_queues[tx_queue_id].internals = internals;\n> +\tinternals->tx_null_queues[tx_queue_id].dummy_packet = dummy_packet;\n> +\n> +\treturn 0;\n> +}\n> +\n> +\n> +static void\n> +eth_dev_info(struct rte_eth_dev *dev,\n> +\t\tstruct rte_eth_dev_info *dev_info)\n> +{\n> +\tstruct pmd_internals *internals = dev->data->dev_private;\n> +\n> +\tdev_info->driver_name = drivername;\n> +\tdev_info->max_mac_addrs = 1;\n> +\tdev_info->max_rx_pktlen = (uint32_t)-1;\n> +\tdev_info->max_rx_queues = (uint16_t)internals->nb_rx_queues;\n> +\tdev_info->max_tx_queues = (uint16_t)internals->nb_tx_queues;\n> +\tdev_info->min_rx_bufsize = 0;\n> +\tdev_info->pci_dev = NULL;\n> +}\n> +\n> +static void\n> +eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats)\n> +{\n> +\tunsigned i;\n> +\tunsigned long rx_total = 0, tx_total = 0, tx_err_total = 0;\n> +\tconst struct pmd_internals *internal = dev->data->dev_private;\n> +\n> +\tmemset(igb_stats, 0, sizeof(*igb_stats));\n> +\tfor (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&\n> +\t\t\ti < internal->nb_rx_queues; i++) {\n> +\t\tigb_stats->q_ipackets[i] =\n> +\t\t\tinternal->rx_null_queues[i].rx_pkts.cnt;\n> +\t\trx_total += igb_stats->q_ipackets[i];\n> +\t}\n> +\n> +\tfor (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&\n> +\t\t\ti < internal->nb_tx_queues; i++) {\n> +\t\tigb_stats->q_opackets[i] =\n> +\t\t\tinternal->tx_null_queues[i].tx_pkts.cnt;\n> +\t\tigb_stats->q_errors[i] =\n> +\t\t\tinternal->tx_null_queues[i].err_pkts.cnt;\n> +\t\ttx_total += igb_stats->q_opackets[i];\n> +\t\ttx_err_total += igb_stats->q_errors[i];\n> +\t}\n> +\n> +\tigb_stats->ipackets = rx_total;\n> +\tigb_stats->opackets = tx_total;\n> +\tigb_stats->oerrors = tx_err_total;\n> +}\n> +\n> +static void\n> +eth_stats_reset(struct rte_eth_dev *dev)\n> +{\n> +\tunsigned i;\n> +\tstruct pmd_internals *internal = dev->data->dev_private;\n> +\n> +\tfor (i = 0; i < internal->nb_rx_queues; i++)\n> +\t\tinternal->rx_null_queues[i].rx_pkts.cnt = 0;\n> +\tfor (i = 0; i < internal->nb_tx_queues; i++) {\n> +\t\tinternal->tx_null_queues[i].tx_pkts.cnt = 0;\n> +\t\tinternal->tx_null_queues[i].err_pkts.cnt = 0;\n> +\t}\n> +}\n> +\n> +static void\n> +eth_queue_release(void *q __rte_unused) { ; }\n> +static int\n> +eth_link_update(struct rte_eth_dev *dev __rte_unused,\n> +\t\tint wait_to_complete __rte_unused) { return 0; }\n> +\n> +static struct eth_dev_ops ops = {\n> +\t\t.dev_start = eth_dev_start,\n> +\t\t.dev_stop = eth_dev_stop,\n> +\t\t.dev_configure = eth_dev_configure,\n> +\t\t.dev_infos_get = eth_dev_info,\n> +\t\t.rx_queue_setup = eth_rx_queue_setup,\n> +\t\t.tx_queue_setup = eth_tx_queue_setup,\n> +\t\t.rx_queue_release = eth_queue_release,\n> +\t\t.tx_queue_release = eth_queue_release,\n> +\t\t.link_update = eth_link_update,\n> +\t\t.stats_get = eth_stats_get,\n> +\t\t.stats_reset = eth_stats_reset,\n> +};\n> +\n> +static int\n> +eth_dev_null_create(const char *name __rte_unused,\n> +\t\tconst unsigned numa_node,\n> +\t\tunsigned packet_size,\n> +\t\tunsigned packet_copy)\n> +{\n> +\tconst unsigned nb_rx_queues = 1;\n> +\tconst unsigned nb_tx_queues = 1;\n> +\tstruct rte_eth_dev_data *data = NULL;\n> +\tstruct rte_pci_device *pci_dev = NULL;\n> +\tstruct pmd_internals *internals = NULL;\n> +\tstruct rte_eth_dev *eth_dev = NULL;\n> +\n> +\tRTE_LOG(INFO, PMD, \"Creating null ethdev on numa socket %u\\n\",\n> +\t\t\tnuma_node);\n> +\n> +\t/* now do all data allocation - for eth_dev structure, dummy pci driver\n> +\t * and internal (private) data\n> +\t */\n> +\tdata = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);\n> +\tif (data == NULL)\n> +\t\tgoto error;\n> +\n> +\tpci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);\n> +\tif (pci_dev == NULL)\n> +\t\tgoto error;\n> +\n> +\tinternals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);\n> +\tif (internals == NULL)\n> +\t\tgoto error;\n> +\n> +\t/* reserve an ethdev entry */\n> +\teth_dev = rte_eth_dev_allocate(name);\n> +\tif (eth_dev == NULL)\n> +\t\tgoto error;\n> +\n> +\t/* now put it all together\n> +\t * - store queue data in internals,\n> +\t * - store numa_node info in pci_driver\n> +\t * - point eth_dev_data to internals and pci_driver\n> +\t * - and point eth_dev structure to new eth_dev_data structure\n> +\t */\n> +\t/* NOTE: we'll replace the data element, of originally allocated eth_dev\n> +\t * so the nulls are local per-process */\n> +\n> +\tinternals->nb_rx_queues = nb_rx_queues;\n> +\tinternals->nb_tx_queues = nb_tx_queues;\n> +\tinternals->packet_size = packet_size;\n> +\tinternals->packet_copy = packet_copy;\n> +\tinternals->numa_node = numa_node;\n> +\n> +\tpci_dev->numa_node = numa_node;\n> +\n> +\tdata->dev_private = internals;\n> +\tdata->port_id = eth_dev->data->port_id;\n> +\tdata->nb_rx_queues = (uint16_t)nb_rx_queues;\n> +\tdata->nb_tx_queues = (uint16_t)nb_tx_queues;\n> +\tdata->dev_link = pmd_link;\n> +\tdata->mac_addrs = &eth_addr;\n> +\n> +\teth_dev->data = data;\n> +\teth_dev->dev_ops = &ops;\n> +\teth_dev->pci_dev = pci_dev;\n> +\n> +\t/* finally assign rx and tx ops */\n> +\tif (packet_copy) {\n> +\t\teth_dev->rx_pkt_burst = eth_null_copy_rx;\n> +\t\teth_dev->tx_pkt_burst = eth_null_copy_tx;\n> +\t} else {\n> +\t\teth_dev->rx_pkt_burst = eth_null_rx;\n> +\t\teth_dev->tx_pkt_burst = eth_null_tx;\n> +\t}\n> +\n> +\treturn 0;\n> +\n> +error:\n> +\tif (data)\n> +\t\trte_free(data);\n> +\tif (pci_dev)\n> +\t\trte_free(pci_dev);\n> +\tif (internals)\n> +\t\trte_free(internals);\n> +\treturn -1;\n> +}\n> +\n> +static inline int\n> +get_packet_size_arg(const char *key __rte_unused,\n> +\t\tconst char *value, void *extra_args)\n> +{\n> +\tconst char *a = value;\n> +\tunsigned *packet_size = extra_args;\n> +\n> +\t*packet_size = (unsigned)strtoul(a, NULL, 0);\n> +\tif (*packet_size == UINT_MAX)\n> +\t\treturn -1;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static inline int\n> +get_packet_copy_arg(const char *key __rte_unused,\n> +\t\tconst char *value, void *extra_args)\n> +{\n> +\tconst char *a = value;\n> +\tunsigned *packet_copy = extra_args;\n> +\n> +\t*packet_copy = (unsigned)strtoul(a, NULL, 0);\n> +\tif (*packet_copy == UINT_MAX)\n> +\t\treturn -1;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int\n> +rte_pmd_null_devinit(const char *name, const char *params)\n> +{\n> +\tunsigned numa_node;\n> +\tunsigned packet_size = default_packet_size;\n> +\tunsigned packet_copy = default_packet_copy;\n> +\tstruct rte_kvargs *kvlist;\n> +\tint ret;\n> +\n> +\tRTE_LOG(INFO, PMD, \"Initializing pmd_null for %s\\n\", name);\n> +\n> +\tnuma_node = rte_socket_id();\n> +\n> +\tkvlist = rte_kvargs_parse(params, valid_arguments);\n> +\tif (kvlist == NULL)\n> +\t\treturn -1;\n> +\n> +\tif (rte_kvargs_count(kvlist, ETH_NULL_PACKET_SIZE_ARG) == 1) {\n> +\n> +\t\tret = rte_kvargs_process(kvlist, ETH_NULL_PACKET_SIZE_ARG,\n> +\t\t\t\t&get_packet_size_arg, &packet_size);\n> +\t\tif (ret < 0)\n> +\t\t\treturn -1;\n> +\t}\n> +\n> +\tif (rte_kvargs_count(kvlist, ETH_NULL_PACKET_COPY_ARG) == 1) {\n> +\n> +\t\tret = rte_kvargs_process(kvlist, ETH_NULL_PACKET_COPY_ARG,\n> +\t\t\t\t&get_packet_copy_arg, &packet_copy);\n> +\t\tif (ret < 0)\n> +\t\t\treturn -1;\n> +\t}\n> +\n> +\tRTE_LOG(INFO, PMD, \"Configure pmd_null: packet size is %d, \"\n> +\t\t\t\"packet copy is %s\\n\", packet_size,\n> +\t\t\tpacket_copy ? \"enabled\" : \"disabled\");\n> +\n> +\treturn eth_dev_null_create(name, numa_node, packet_size, packet_copy);\n> +}\n> +\n> +static struct rte_driver pmd_null_drv = {\n> +\t.name = \"eth_null\",\n> +\t.type = PMD_VDEV,\n> +\t.init = rte_pmd_null_devinit,\n> +};\n> +\n> +PMD_REGISTER_DRIVER(pmd_null_drv);\n>", "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@dpdk.org", "Delivered-To": "patchwork@dpdk.org", "Received": [ "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 66FE22E81;\n\tMon, 22 Sep 2014 09:40:01 +0200 (CEST)", "from mail-wi0-f173.google.com (mail-wi0-f173.google.com\n\t[209.85.212.173]) by dpdk.org (Postfix) with ESMTP id DED02231C\n\tfor <dev@dpdk.org>; Mon, 22 Sep 2014 09:40:00 +0200 (CEST)", "by mail-wi0-f173.google.com with SMTP id r20so2348396wiv.12\n\tfor <dev@dpdk.org>; Mon, 22 Sep 2014 00:46:03 -0700 (PDT)", "from [10.16.0.189] (guy78-3-82-239-227-177.fbx.proxad.net.\n\t[82.239.227.177]) by mx.google.com with ESMTPSA id\n\tu5sm11116877wia.17.2014.09.22.00.46.02 for <multiple recipients>\n\t(version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);\n\tMon, 22 Sep 2014 00:46:02 -0700 (PDT)" ], "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:message-id:date:from:user-agent:mime-version:to\n\t:cc:subject:references:in-reply-to:content-type\n\t:content-transfer-encoding;\n\tbh=WiQOC7z8tVwjClW5Uyzvnf+wGQXubYDk4EWup7+0Xmc=;\n\tb=kRX1VH25UPYibLgDTGuApUd8OSGyATPd3IsMTzmW6gsyWUNDy6KGYdaJvZw8Gbd230\n\tCH/8JpQ2WtRklSE1IM7Gu70+LkxDNNE0vP8CQDrJYKnLtYZAsFgbP8B/OPos8rqi9/gj\n\t52XW0/rsvuV4YJ3/FFRnbV+gyFwoO/bI/5vlTs0czQSUBSURk+cFuTYsZlS96X7tavSb\n\tf/eMAEoDLgwTSSC1uzPdx8/GZsesGjxOTYpRInppk4/kN2WwRB69ztfgc0pXSDSgj+Ny\n\tpWzVMuQwP5nUe3QgnE+/55AV79QXs04RhBgjJBNu9O8e8h9UABhcc2QW4SWHlV0/vWK6\n\tfybw==", "X-Gm-Message-State": "ALoCoQlxQ9iXD6FdqsB4cMlwdy4VAvdy1ZDm+Jf3R3pIEoUvZfEXw5aJp/3HYNlPGFzuP4uFVbaH", "X-Received": "by 10.180.86.225 with SMTP id s1mr5385692wiz.21.1411371963610;\n\tMon, 22 Sep 2014 00:46:03 -0700 (PDT)", "Message-ID": "<541FD3BD.2060606@6wind.com>", "Date": "Mon, 22 Sep 2014 09:46:05 +0200", "From": "Ivan Boule <ivan.boule@6wind.com>", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64;\n\trv:24.0) Gecko/20100101 Icedove/24.7.0", "MIME-Version": "1.0", "To": "mukawa@igel.co.jp, dev@dpdk.org", "References": "<mukawa@igel.co.jp>\n\t<1411129659-7132-1-git-send-email-mukawa@igel.co.jp>\n\t<1411129659-7132-2-git-send-email-mukawa@igel.co.jp>", "In-Reply-To": "<1411129659-7132-2-git-send-email-mukawa@igel.co.jp>", "Content-Type": "text/plain; charset=ISO-8859-1; format=flowed", "Content-Transfer-Encoding": "7bit", "Cc": "nakajima.yoshihiro@lab.ntt.co.jp, masutani.hitoshi@lab.ntt.co.jp", "Subject": "Re: [dpdk-dev] [RFC] librte_pmd_null: Add null PMD", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "patches and discussions about DPDK <dev.dpdk.org>", "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://dpdk.org/ml/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "addressed": null } ]