get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/76965/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 76965,
    "url": "http://patches.dpdk.org/api/patches/76965/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200908201830.74206-34-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200908201830.74206-34-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200908201830.74206-34-cristian.dumitrescu@intel.com",
    "date": "2020-09-08T20:18:22",
    "name": "[v3,33/41] port: add ethernet device SWX port",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "bad00a3d9f0966dd836fe4a69049bde540362c79",
    "submitter": {
        "id": 19,
        "url": "http://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200908201830.74206-34-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 12034,
            "url": "http://patches.dpdk.org/api/series/12034/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12034",
            "date": "2020-09-08T20:17:52",
            "name": "Pipeline alignment with the P4 language",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/12034/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/76965/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/76965/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id AD8BDA04B1;\n\tTue,  8 Sep 2020 22:24:11 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 1866F1C219;\n\tTue,  8 Sep 2020 22:19:42 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by dpdk.org (Postfix) with ESMTP id 816761C11E\n for <dev@dpdk.org>; Tue,  8 Sep 2020 22:19:05 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 08 Sep 2020 13:19:05 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com) ([10.237.223.107])\n by fmsmga006.fm.intel.com with ESMTP; 08 Sep 2020 13:19:04 -0700"
        ],
        "IronPort-SDR": [
            "\n rvPFurKqX+KqNPelAcceVC7s61sINO5egnT0xUMuHPv4JPTATKlNQYVeTSk/4bPOadGbHk9nr8\n OLdTLd59oM+w==",
            "\n QRPYJ2TC6h5pkkTCZZ6wwZVaQ2Dcx5MKSO0Qni2k85ur7U+jxF3f5+H5DzsAVq+jL5IPpdP/t9\n SePdpNi7lrlA=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9738\"; a=\"145939449\"",
            "E=Sophos;i=\"5.76,407,1592895600\"; d=\"scan'208\";a=\"145939449\"",
            "E=Sophos;i=\"5.76,406,1592895600\"; d=\"scan'208\";a=\"504493539\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue,  8 Sep 2020 21:18:22 +0100",
        "Message-Id": "<20200908201830.74206-34-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200908201830.74206-1-cristian.dumitrescu@intel.com>",
        "References": "<20200907214032.95052-2-cristian.dumitrescu@intel.com>\n <20200908201830.74206-1-cristian.dumitrescu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 33/41] port: add ethernet device SWX port",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add the Ethernet device input/output port type for the SWX pipeline.\nUsed under the hood by the pipeline rx and tx instructions.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\n---\n lib/librte_port/meson.build           |   6 +-\n lib/librte_port/rte_port_version.map  |   3 +-\n lib/librte_port/rte_swx_port_ethdev.c | 313 ++++++++++++++++++++++++++\n lib/librte_port/rte_swx_port_ethdev.h |  54 +++++\n 4 files changed, 373 insertions(+), 3 deletions(-)\n create mode 100644 lib/librte_port/rte_swx_port_ethdev.c\n create mode 100644 lib/librte_port/rte_swx_port_ethdev.h",
    "diff": "diff --git a/lib/librte_port/meson.build b/lib/librte_port/meson.build\nindex 5b5fbf6c4..3d7f309bb 100644\n--- a/lib/librte_port/meson.build\n+++ b/lib/librte_port/meson.build\n@@ -10,7 +10,8 @@ sources = files(\n \t'rte_port_sched.c',\n \t'rte_port_source_sink.c',\n \t'rte_port_sym_crypto.c',\n-\t'rte_port_eventdev.c')\n+\t'rte_port_eventdev.c',\n+\t'rte_swx_port_ethdev.c',)\n headers = files(\n \t'rte_port_ethdev.h',\n \t'rte_port_fd.h',\n@@ -22,7 +23,8 @@ headers = files(\n \t'rte_port_source_sink.h',\n \t'rte_port_sym_crypto.h',\n \t'rte_port_eventdev.h',\n-\t'rte_swx_port.h',)\n+\t'rte_swx_port.h',\n+\t'rte_swx_port_ethdev.h',)\n deps += ['ethdev', 'sched', 'ip_frag', 'cryptodev', 'eventdev']\n \n if dpdk_conf.has('RTE_PORT_PCAP')\ndiff --git a/lib/librte_port/rte_port_version.map b/lib/librte_port/rte_port_version.map\nindex bd1fbb66b..6da5c8074 100644\n--- a/lib/librte_port/rte_port_version.map\n+++ b/lib/librte_port/rte_port_version.map\n@@ -37,5 +37,6 @@ EXPERIMENTAL {\n \trte_port_eventdev_reader_ops;\n \trte_port_eventdev_writer_ops;\n \trte_port_eventdev_writer_nodrop_ops;\n-\n+\trte_swx_port_ethdev_reader_ops;\n+\trte_swx_port_ethdev_writer_ops;\n };\ndiff --git a/lib/librte_port/rte_swx_port_ethdev.c b/lib/librte_port/rte_swx_port_ethdev.c\nnew file mode 100644\nindex 000000000..18d1c0b5d\n--- /dev/null\n+++ b/lib/librte_port/rte_swx_port_ethdev.c\n@@ -0,0 +1,313 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#include <string.h>\n+#include <stdlib.h>\n+#include <stdio.h>\n+#include <stdint.h>\n+\n+#include <rte_mbuf.h>\n+#include <rte_ethdev.h>\n+#include <rte_hexdump.h>\n+\n+#include \"rte_swx_port_ethdev.h\"\n+\n+#define CHECK(condition)                                                       \\\n+do {                                                                           \\\n+\tif (!(condition))                                                      \\\n+\t\treturn NULL;                                                   \\\n+} while (0)\n+\n+#ifndef TRACE_LEVEL\n+#define TRACE_LEVEL 0\n+#endif\n+\n+#if TRACE_LEVEL\n+#define TRACE(...) printf(__VA_ARGS__)\n+#else\n+#define TRACE(...)\n+#endif\n+\n+/*\n+ * Port ETHDEV Reader\n+ */\n+struct reader {\n+\tstruct {\n+\t\tuint16_t port_id;\n+\t\tuint16_t queue_id;\n+\t\tuint32_t burst_size;\n+\t} params;\n+\tstruct rte_swx_port_in_stats stats;\n+\tstruct rte_mbuf **pkts;\n+\tint n_pkts;\n+\tint pos;\n+};\n+\n+static void *\n+reader_create(void *args)\n+{\n+\tstruct rte_eth_dev_info info;\n+\tstruct rte_swx_port_ethdev_reader_params *params = args;\n+\tstruct reader *p;\n+\tint status;\n+\tuint16_t port_id;\n+\n+\t/* Check input parameters. */\n+\tCHECK(params);\n+\n+\tCHECK(params->dev_name);\n+\tstatus = rte_eth_dev_get_port_by_name(params->dev_name, &port_id);\n+\tCHECK(!status);\n+\n+\tstatus = rte_eth_dev_info_get(port_id, &info);\n+\tCHECK((status == -ENOTSUP) || (params->queue_id < info.nb_rx_queues));\n+\n+\tCHECK(params->burst_size);\n+\n+\t/* Memory allocation. */\n+\tp = calloc(1, sizeof(struct reader));\n+\tCHECK(p);\n+\n+\tp->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));\n+\tif (!p->pkts) {\n+\t\tfree(p);\n+\t\tCHECK(0);\n+\t}\n+\n+\t/* Initialization. */\n+\tp->params.port_id = port_id;\n+\tp->params.queue_id = params->queue_id;\n+\tp->params.burst_size = params->burst_size;\n+\n+\treturn p;\n+}\n+\n+static int\n+reader_pkt_rx(void *port, struct rte_swx_pkt *pkt)\n+{\n+\tstruct reader *p = port;\n+\tstruct rte_mbuf *m;\n+\n+\tif (p->pos == p->n_pkts) {\n+\t\tint n_pkts;\n+\n+\t\tn_pkts = rte_eth_rx_burst(p->params.port_id,\n+\t\t\t\t\t  p->params.queue_id,\n+\t\t\t\t\t  p->pkts,\n+\t\t\t\t\t  p->params.burst_size);\n+\t\tif (!n_pkts) {\n+\t\t\tp->stats.n_empty++;\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tTRACE(\"[Ethdev RX port %u queue %u] %d packets in\\n\",\n+\t\t      (uint32_t)p->params.port_id,\n+\t\t      (uint32_t)p->params.queue_id,\n+\t\t      n_pkts);\n+\n+\t\tp->n_pkts = n_pkts;\n+\t\tp->pos = 0;\n+\t}\n+\n+\tm = p->pkts[p->pos++];\n+\tpkt->handle = m;\n+\tpkt->pkt = m->buf_addr;\n+\tpkt->offset = m->data_off;\n+\tpkt->length = m->pkt_len;\n+\n+\tTRACE(\"[Ethdev RX port %u queue %u] Pkt %d (%u bytes at offset %u)\\n\",\n+\t      (uint32_t)p->params.port_id,\n+\t      (uint32_t)p->params.queue_id,\n+\t      p->pos - 1,\n+\t      pkt->length,\n+\t      pkt->offset);\n+\tif (TRACE_LEVEL)\n+\t\trte_hexdump(stdout,\n+\t\t\t    NULL,\n+\t\t\t    &((uint8_t *)m->buf_addr)[m->data_off],\n+\t\t\t    m->data_len);\n+\n+\tp->stats.n_pkts++;\n+\tp->stats.n_bytes += pkt->length;\n+\n+\treturn 1;\n+}\n+\n+static void\n+reader_free(void *port)\n+{\n+\tstruct reader *p = port;\n+\tint i;\n+\n+\tif (!p)\n+\t\treturn;\n+\n+\tfor (i = 0; i < p->n_pkts; i++) {\n+\t\tstruct rte_mbuf *pkt = p->pkts[i];\n+\n+\t\trte_pktmbuf_free(pkt);\n+\t}\n+\n+\tfree(p->pkts);\n+\tfree(p);\n+}\n+\n+static void\n+reader_stats_read(void *port, struct rte_swx_port_in_stats *stats)\n+{\n+\tstruct reader *p = port;\n+\n+\tmemcpy(stats, &p->stats, sizeof(p->stats));\n+}\n+\n+/*\n+ * Port ETHDEV Writer\n+ */\n+struct writer {\n+\tstruct {\n+\t\tuint16_t port_id;\n+\t\tuint16_t queue_id;\n+\t\tuint32_t burst_size;\n+\t} params;\n+\tstruct rte_swx_port_out_stats stats;\n+\n+\tstruct rte_mbuf **pkts;\n+\tint n_pkts;\n+};\n+\n+static void *\n+writer_create(void *args)\n+{\n+\tstruct rte_eth_dev_info info;\n+\tstruct rte_swx_port_ethdev_writer_params *params = args;\n+\tstruct writer *p;\n+\tint status;\n+\tuint16_t port_id;\n+\n+\t/* Check input parameters. */\n+\tCHECK(params);\n+\n+\tCHECK(params->dev_name);\n+\tstatus = rte_eth_dev_get_port_by_name(params->dev_name, &port_id);\n+\tCHECK(!status);\n+\n+\tstatus = rte_eth_dev_info_get(port_id, &info);\n+\tCHECK((status == -ENOTSUP) || (params->queue_id < info.nb_tx_queues));\n+\n+\tCHECK(params->burst_size);\n+\n+\t/* Memory allocation. */\n+\tp = calloc(1, sizeof(struct writer));\n+\tCHECK(p);\n+\n+\tp->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));\n+\tif (!p->pkts) {\n+\t\tfree(p);\n+\t\tCHECK(0);\n+\t}\n+\n+\t/* Initialization. */\n+\tp->params.port_id = port_id;\n+\tp->params.queue_id = params->queue_id;\n+\tp->params.burst_size = params->burst_size;\n+\n+\treturn p;\n+}\n+\n+static void\n+__writer_flush(struct writer *p)\n+{\n+\tint n_pkts;\n+\n+\tfor (n_pkts = 0; ; ) {\n+\t\tn_pkts += rte_eth_tx_burst(p->params.port_id,\n+\t\t\t\t\t   p->params.queue_id,\n+\t\t\t\t\t   p->pkts + n_pkts,\n+\t\t\t\t\t   p->n_pkts - n_pkts);\n+\n+\t\tTRACE(\"[Ethdev TX port %u queue %u] %d packets out\\n\",\n+\t\t      (uint32_t)p->params.port_id,\n+\t\t      (uint32_t)p->params.queue_id,\n+\t\t      n_pkts);\n+\n+\t\tif (n_pkts == p->n_pkts)\n+\t\t\tbreak;\n+\t}\n+\n+\tp->n_pkts = 0;\n+}\n+\n+static void\n+writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)\n+{\n+\tstruct writer *p = port;\n+\tstruct rte_mbuf *m = pkt->handle;\n+\n+\tTRACE(\"[Ethdev TX port %u queue %u] Pkt %d (%u bytes at offset %u)\\n\",\n+\t      (uint32_t)p->params.port_id,\n+\t      (uint32_t)p->params.queue_id,\n+\t      p->n_pkts - 1,\n+\t      pkt->length,\n+\t      pkt->offset);\n+\tif (TRACE_LEVEL)\n+\t\trte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);\n+\n+\tm->pkt_len = pkt->length;\n+\tm->data_len = (uint16_t)pkt->length;\n+\tm->data_off = (uint16_t)pkt->offset;\n+\n+\tp->stats.n_pkts++;\n+\tp->stats.n_bytes += pkt->length;\n+\n+\tp->pkts[p->n_pkts++] = m;\n+\tif (p->n_pkts ==  (int)p->params.burst_size)\n+\t\t__writer_flush(p);\n+}\n+\n+static void\n+writer_flush(void *port)\n+{\n+\tstruct writer *p = port;\n+\n+\tif (p->n_pkts)\n+\t\t__writer_flush(p);\n+}\n+\n+static void\n+writer_free(void *port)\n+{\n+\tstruct writer *p = port;\n+\n+\tif (!p)\n+\t\treturn;\n+\n+\twriter_flush(p);\n+\tfree(p->pkts);\n+\tfree(port);\n+}\n+\n+static void\n+writer_stats_read(void *port, struct rte_swx_port_out_stats *stats)\n+{\n+\tstruct writer *p = port;\n+\n+\tmemcpy(stats, &p->stats, sizeof(p->stats));\n+}\n+\n+/*\n+ * Summary of port operations\n+ */\n+struct rte_swx_port_in_ops rte_swx_port_ethdev_reader_ops = {\n+\t.create = reader_create,\n+\t.free = reader_free,\n+\t.pkt_rx = reader_pkt_rx,\n+\t.stats_read = reader_stats_read,\n+};\n+\n+struct rte_swx_port_out_ops rte_swx_port_ethdev_writer_ops = {\n+\t.create = writer_create,\n+\t.free = writer_free,\n+\t.pkt_tx = writer_pkt_tx,\n+\t.flush = writer_flush,\n+\t.stats_read = writer_stats_read,\n+};\ndiff --git a/lib/librte_port/rte_swx_port_ethdev.h b/lib/librte_port/rte_swx_port_ethdev.h\nnew file mode 100644\nindex 000000000..cbc2d7b21\n--- /dev/null\n+++ b/lib/librte_port/rte_swx_port_ethdev.h\n@@ -0,0 +1,54 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#ifndef __INCLUDE_RTE_SWX_PORT_ETHDEV_H__\n+#define __INCLUDE_RTE_SWX_PORT_ETHDEV_H__\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+/**\n+ * @file\n+ * RTE SWX Ethernet Device Input and Output Ports\n+ */\n+\n+#include <stdint.h>\n+\n+#include \"rte_swx_port.h\"\n+\n+/** Ethernet device input port (reader) creation parameters. */\n+struct rte_swx_port_ethdev_reader_params {\n+\t/** Name of a valid and fully configured Ethernet device. */\n+\tconst char *dev_name;\n+\n+\t/** Ethernet device receive queue ID. */\n+\tuint16_t queue_id;\n+\n+\t/** Ethernet device receive burst size. */\n+\tuint32_t burst_size;\n+};\n+\n+/** Ethernet device reader operations. */\n+extern struct rte_swx_port_in_ops rte_swx_port_ethdev_reader_ops;\n+\n+/** Ethernet device output port (writer) creation parameters. */\n+struct rte_swx_port_ethdev_writer_params {\n+\t/** Name of a valid and fully configured Ethernet device. */\n+\tconst char *dev_name;\n+\n+\t/** Ethernet device transmit queue ID. */\n+\tuint16_t queue_id;\n+\n+\t/** Ethernet device transmit burst size. */\n+\tuint32_t burst_size;\n+};\n+\n+/** Ethernet device writer operations. */\n+extern struct rte_swx_port_out_ops rte_swx_port_ethdev_writer_ops;\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif\n",
    "prefixes": [
        "v3",
        "33/41"
    ]
}