get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 61240,
    "url": "http://patches.dpdk.org/api/patches/61240/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1571130263-120863-8-git-send-email-orika@mellanox.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": "<1571130263-120863-8-git-send-email-orika@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1571130263-120863-8-git-send-email-orika@mellanox.com",
    "date": "2019-10-15T09:04:15",
    "name": "[v3,07/14] app/testpmd: add hairpin support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "ff1f66fd908f5a4b86c505cef8be8181421b213f",
    "submitter": {
        "id": 795,
        "url": "http://patches.dpdk.org/api/people/795/?format=api",
        "name": "Ori Kam",
        "email": "orika@mellanox.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1571130263-120863-8-git-send-email-orika@mellanox.com/mbox/",
    "series": [
        {
            "id": 6855,
            "url": "http://patches.dpdk.org/api/series/6855/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=6855",
            "date": "2019-10-15T09:04:08",
            "name": "add hairpin feature",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/6855/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/61240/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/61240/checks/",
    "tags": {},
    "related": [],
    "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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A74B31E55F;\n\tTue, 15 Oct 2019 11:06:06 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n\tby dpdk.org (Postfix) with ESMTP id 0CDE01E54B\n\tfor <dev@dpdk.org>; Tue, 15 Oct 2019 11:06:04 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n\torika@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 15 Oct 2019 11:05:59 +0200",
            "from pegasus04.mtr.labs.mlnx. (pegasus04.mtr.labs.mlnx\n\t[10.210.16.126])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x9F94hci029891;\n\tTue, 15 Oct 2019 12:05:59 +0300"
        ],
        "From": "Ori Kam <orika@mellanox.com>",
        "To": "Wenzhuo Lu <wenzhuo.lu@intel.com>, Jingjing Wu <jingjing.wu@intel.com>, \n\tBernard Iremonger <bernard.iremonger@intel.com>",
        "Cc": "dev@dpdk.org, orika@mellanox.com, stephen@networkplumber.org",
        "Date": "Tue, 15 Oct 2019 09:04:15 +0000",
        "Message-Id": "<1571130263-120863-8-git-send-email-orika@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1571130263-120863-1-git-send-email-orika@mellanox.com>",
        "References": "<1569479349-36962-1-git-send-email-orika@mellanox.com>\n\t<1571130263-120863-1-git-send-email-orika@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v3 07/14] app/testpmd: add hairpin support",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This commit introduce the hairpin queues to the testpmd.\nthe hairpin queue is configured using --hairpinq=<n>\nthe hairpin queue adds n queue objects for both the total number\nof TX queues and RX queues.\nThe connection between the queues are 1 to 1, first Rx hairpin queue\nwill be connected to the first Tx hairpin queue\n\nSigned-off-by: Ori Kam <orika@mellanox.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n\n---\n app/test-pmd/parameters.c |  28 ++++++++++++\n app/test-pmd/testpmd.c    | 109 +++++++++++++++++++++++++++++++++++++++++++++-\n app/test-pmd/testpmd.h    |   3 ++\n 3 files changed, 138 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c\nindex 6c78dca..6246129 100644\n--- a/app/test-pmd/parameters.c\n+++ b/app/test-pmd/parameters.c\n@@ -147,6 +147,8 @@\n \tprintf(\"  --rxd=N: set the number of descriptors in RX rings to N.\\n\");\n \tprintf(\"  --txq=N: set the number of TX queues per port to N.\\n\");\n \tprintf(\"  --txd=N: set the number of descriptors in TX rings to N.\\n\");\n+\tprintf(\"  --hairpinq=N: set the number of hairpin queues per port to \"\n+\t       \"N.\\n\");\n \tprintf(\"  --burst=N: set the number of packets per burst to N.\\n\");\n \tprintf(\"  --mbcache=N: set the cache of mbuf memory pool to N.\\n\");\n \tprintf(\"  --rxpt=N: set prefetch threshold register of RX rings to N.\\n\");\n@@ -618,6 +620,7 @@\n \t\t{ \"txq\",\t\t\t1, 0, 0 },\n \t\t{ \"rxd\",\t\t\t1, 0, 0 },\n \t\t{ \"txd\",\t\t\t1, 0, 0 },\n+\t\t{ \"hairpinq\",\t\t\t1, 0, 0 },\n \t\t{ \"burst\",\t\t\t1, 0, 0 },\n \t\t{ \"mbcache\",\t\t\t1, 0, 0 },\n \t\t{ \"txpt\",\t\t\t1, 0, 0 },\n@@ -1036,6 +1039,31 @@\n \t\t\t\t\t\t  \" >= 0 && <= %u\\n\", n,\n \t\t\t\t\t\t  get_allowed_max_nb_txq(&pid));\n \t\t\t}\n+\t\t\tif (!strcmp(lgopts[opt_idx].name, \"hairpinq\")) {\n+\t\t\t\tn = atoi(optarg);\n+\t\t\t\tif (n >= 0 &&\n+\t\t\t\t    check_nb_hairpinq((queueid_t)n) == 0)\n+\t\t\t\t\tnb_hairpinq = (queueid_t) n;\n+\t\t\t\telse\n+\t\t\t\t\trte_exit(EXIT_FAILURE, \"txq %d invalid - must be\"\n+\t\t\t\t\t\t  \" >= 0 && <= %u\\n\", n,\n+\t\t\t\t\t\t  get_allowed_max_nb_hairpinq\n+\t\t\t\t\t\t  (&pid));\n+\t\t\t\tif ((n + nb_txq) < 0 ||\n+\t\t\t\t    check_nb_txq((queueid_t)(n + nb_txq)) != 0)\n+\t\t\t\t\trte_exit(EXIT_FAILURE, \"txq + hairpinq \"\n+\t\t\t\t\t\t \"%d invalid - must be\"\n+\t\t\t\t\t\t  \" >= 0 && <= %u\\n\",\n+\t\t\t\t\t\t  n + nb_txq,\n+\t\t\t\t\t\t  get_allowed_max_nb_txq(&pid));\n+\t\t\t\tif ((n + nb_rxq) < 0 ||\n+\t\t\t\t    check_nb_rxq((queueid_t)(n + nb_rxq)) != 0)\n+\t\t\t\t\trte_exit(EXIT_FAILURE, \"rxq + hairpinq \"\n+\t\t\t\t\t\t \"%d invalid - must be\"\n+\t\t\t\t\t\t  \" >= 0 && <= %u\\n\",\n+\t\t\t\t\t\t  n + nb_rxq,\n+\t\t\t\t\t\t  get_allowed_max_nb_rxq(&pid));\n+\t\t\t}\n \t\t\tif (!nb_rxq && !nb_txq) {\n \t\t\t\trte_exit(EXIT_FAILURE, \"Either rx or tx queues should \"\n \t\t\t\t\t\t\"be non-zero\\n\");\ndiff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c\nindex 5701f31..8290e22 100644\n--- a/app/test-pmd/testpmd.c\n+++ b/app/test-pmd/testpmd.c\n@@ -235,6 +235,7 @@ struct fwd_engine * fwd_engines[] = {\n /*\n  * Configurable number of RX/TX queues.\n  */\n+queueid_t nb_hairpinq; /**< Number of hairpin queues per port. */\n queueid_t nb_rxq = 1; /**< Number of RX queues per port. */\n queueid_t nb_txq = 1; /**< Number of TX queues per port. */\n \n@@ -1103,6 +1104,53 @@ struct extmem_param {\n \treturn 0;\n }\n \n+/*\n+ * Get the allowed maximum number of hairpin queues.\n+ * *pid return the port id which has minimal value of\n+ * max_hairpin_queues in all ports.\n+ */\n+queueid_t\n+get_allowed_max_nb_hairpinq(portid_t *pid)\n+{\n+\tqueueid_t allowed_max_hairpinq = MAX_QUEUE_ID;\n+\tportid_t pi;\n+\tstruct rte_eth_hairpin_cap cap;\n+\n+\tRTE_ETH_FOREACH_DEV(pi) {\n+\t\tif (rte_eth_dev_hairpin_capability_get(pi, &cap) != 0) {\n+\t\t\t*pid = pi;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tif (cap.max_n_queues < allowed_max_hairpinq) {\n+\t\t\tallowed_max_hairpinq = cap.max_n_queues;\n+\t\t\t*pid = pi;\n+\t\t}\n+\t}\n+\treturn allowed_max_hairpinq;\n+}\n+\n+/*\n+ * Check input hairpin is valid or not.\n+ * If input hairpin is not greater than any of maximum number\n+ * of hairpin queues of all ports, it is valid.\n+ * if valid, return 0, else return -1\n+ */\n+int\n+check_nb_hairpinq(queueid_t hairpinq)\n+{\n+\tqueueid_t allowed_max_hairpinq;\n+\tportid_t pid = 0;\n+\n+\tallowed_max_hairpinq = get_allowed_max_nb_hairpinq(&pid);\n+\tif (hairpinq > allowed_max_hairpinq) {\n+\t\tprintf(\"Fail: input hairpin (%u) can't be greater \"\n+\t\t       \"than max_hairpin_queues (%u) of port %u\\n\",\n+\t\t       hairpinq, allowed_max_hairpinq, pid);\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n static void\n init_config(void)\n {\n@@ -2064,6 +2112,11 @@ struct extmem_param {\n \tqueueid_t qi;\n \tstruct rte_port *port;\n \tstruct rte_ether_addr mac_addr;\n+\tstruct rte_eth_hairpin_conf hairpin_conf = {\n+\t\t.peer_n = 1,\n+\t};\n+\tint i;\n+\tstruct rte_eth_hairpin_cap cap;\n \n \tif (port_id_is_invalid(pid, ENABLED_WARN))\n \t\treturn 0;\n@@ -2096,9 +2149,16 @@ struct extmem_param {\n \t\t\tconfigure_rxtx_dump_callbacks(0);\n \t\t\tprintf(\"Configuring Port %d (socket %u)\\n\", pi,\n \t\t\t\t\tport->socket_id);\n+\t\t\tif (nb_hairpinq > 0 &&\n+\t\t\t    rte_eth_dev_hairpin_capability_get(pi, &cap)) {\n+\t\t\t\tprintf(\"Port %d doesn't support hairpin \"\n+\t\t\t\t       \"queues\\n\", pi);\n+\t\t\t\treturn -1;\n+\t\t\t}\n \t\t\t/* configure port */\n-\t\t\tdiag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,\n-\t\t\t\t\t\t&(port->dev_conf));\n+\t\t\tdiag = rte_eth_dev_configure(pi, nb_rxq + nb_hairpinq,\n+\t\t\t\t\t\t     nb_txq + nb_hairpinq,\n+\t\t\t\t\t\t     &(port->dev_conf));\n \t\t\tif (diag != 0) {\n \t\t\t\tif (rte_atomic16_cmpset(&(port->port_status),\n \t\t\t\tRTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)\n@@ -2191,6 +2251,51 @@ struct extmem_param {\n \t\t\t\tport->need_reconfig_queues = 1;\n \t\t\t\treturn -1;\n \t\t\t}\n+\t\t\t/* setup hairpin queues */\n+\t\t\ti = 0;\n+\t\t\tfor (qi = nb_txq; qi < nb_hairpinq + nb_txq; qi++) {\n+\t\t\t\thairpin_conf.peers[0].port = pi;\n+\t\t\t\thairpin_conf.peers[0].queue = i + nb_rxq;\n+\t\t\t\tdiag = rte_eth_tx_hairpin_queue_setup\n+\t\t\t\t\t(pi, qi, nb_txd, &hairpin_conf);\n+\t\t\t\ti++;\n+\t\t\t\tif (diag == 0)\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\t/* Fail to setup rx queue, return */\n+\t\t\t\tif (rte_atomic16_cmpset(&(port->port_status),\n+\t\t\t\t\t\t\tRTE_PORT_HANDLING,\n+\t\t\t\t\t\t\tRTE_PORT_STOPPED) == 0)\n+\t\t\t\t\tprintf(\"Port %d can not be set back \"\n+\t\t\t\t\t\t\t\"to stopped\\n\", pi);\n+\t\t\t\tprintf(\"Fail to configure port %d hairpin \"\n+\t\t\t\t       \"queues\\n\", pi);\n+\t\t\t\t/* try to reconfigure queues next time */\n+\t\t\t\tport->need_reconfig_queues = 1;\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\ti = 0;\n+\t\t\tfor (qi = nb_rxq; qi < nb_hairpinq + nb_rxq; qi++) {\n+\t\t\t\thairpin_conf.peers[0].port = pi;\n+\t\t\t\thairpin_conf.peers[0].queue = i + nb_txq;\n+\t\t\t\tdiag = rte_eth_rx_hairpin_queue_setup\n+\t\t\t\t\t(pi, qi, nb_rxd, &hairpin_conf);\n+\t\t\t\ti++;\n+\t\t\t\tif (diag == 0)\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\t/* Fail to setup rx queue, return */\n+\t\t\t\tif (rte_atomic16_cmpset(&(port->port_status),\n+\t\t\t\t\t\t\tRTE_PORT_HANDLING,\n+\t\t\t\t\t\t\tRTE_PORT_STOPPED) == 0)\n+\t\t\t\t\tprintf(\"Port %d can not be set back \"\n+\t\t\t\t\t\t\t\"to stopped\\n\", pi);\n+\t\t\t\tprintf(\"Fail to configure port %d hairpin \"\n+\t\t\t\t       \"queues\\n\", pi);\n+\t\t\t\t/* try to reconfigure queues next time */\n+\t\t\t\tport->need_reconfig_queues = 1;\n+\t\t\t\treturn -1;\n+\t\t\t}\n \t\t}\n \t\tconfigure_rxtx_dump_callbacks(verbose_level);\n \t\t/* start port */\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex f8ebe71..0682c11 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -383,6 +383,7 @@ struct queue_stats_mappings {\n \n extern uint64_t rss_hf;\n \n+extern queueid_t nb_hairpinq;\n extern queueid_t nb_rxq;\n extern queueid_t nb_txq;\n \n@@ -854,6 +855,8 @@ enum print_warning {\n int check_nb_rxq(queueid_t rxq);\n queueid_t get_allowed_max_nb_txq(portid_t *pid);\n int check_nb_txq(queueid_t txq);\n+queueid_t get_allowed_max_nb_hairpinq(portid_t *pid);\n+int check_nb_hairpinq(queueid_t hairpinq);\n \n uint16_t dump_rx_pkts(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],\n \t\t      uint16_t nb_pkts, __rte_unused uint16_t max_pkts,\n",
    "prefixes": [
        "v3",
        "07/14"
    ]
}