get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1225,
    "url": "https://patches.dpdk.org/api/patches/1225/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1415579379-2891-2-git-send-email-huawei.xie@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<1415579379-2891-2-git-send-email-huawei.xie@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1415579379-2891-2-git-send-email-huawei.xie@intel.com",
    "date": "2014-11-10T00:29:38",
    "name": "[dpdk-dev,v2,1/2] examples/vmdq: support new VMDQ API",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "5008ac6aeca6ef3ce5f0451f3b11e55713a677fc",
    "submitter": {
        "id": 16,
        "url": "https://patches.dpdk.org/api/people/16/?format=api",
        "name": "Huawei Xie",
        "email": "huawei.xie@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1415579379-2891-2-git-send-email-huawei.xie@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/1225/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/1225/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 679927F2C;\n\tMon, 10 Nov 2014 01:20:29 +0100 (CET)",
            "from mga09.intel.com (mga09.intel.com [134.134.136.24])\n\tby dpdk.org (Postfix) with ESMTP id 76E424A6E\n\tfor <dev@dpdk.org>; Mon, 10 Nov 2014 01:20:25 +0100 (CET)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby orsmga102.jf.intel.com with ESMTP; 09 Nov 2014 16:28:18 -0800",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby orsmga001.jf.intel.com with ESMTP; 09 Nov 2014 16:30:06 -0800",
            "from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com\n\t[10.239.29.90])\n\tby shvmail01.sh.intel.com with ESMTP id sAA0U4Wg000995;\n\tMon, 10 Nov 2014 08:30:04 +0800",
            "from shecgisg003.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid sAA0U2lu002967; Mon, 10 Nov 2014 08:30:04 +0800",
            "(from hxie5@localhost)\n\tby shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id sAA0U1uU002963; \n\tMon, 10 Nov 2014 08:30:01 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.07,348,1413270000\"; d=\"scan'208\";a=\"605041044\"",
        "From": "Huawei Xie <huawei.xie@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Mon, 10 Nov 2014 08:29:38 +0800",
        "Message-Id": "<1415579379-2891-2-git-send-email-huawei.xie@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "In-Reply-To": "<1415579379-2891-1-git-send-email-huawei.xie@intel.com>",
        "References": "<1415579379-2891-1-git-send-email-huawei.xie@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 1/2] examples/vmdq: support new VMDQ API",
        "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>"
    },
    "content": "This patch supports new VMDQ API in vmdq example.\nBesides, it allows users to specify num_pools different with\nmax_nb_poos, thus the polling thread needn't to poll queues\nof all pools.\n\nDue to i40e implmentation issue, there is no default mac for \nVMDQ pool, so app needs to specify mac address for each pool\nexplicitly.\n\nSigned-off-by: Huawei Xie <huawei.xie@intel.com>\n---\n examples/vmdq/main.c | 169 +++++++++++++++++++++++++++++++--------------------\n 1 file changed, 103 insertions(+), 66 deletions(-)",
    "diff": "diff --git a/examples/vmdq/main.c b/examples/vmdq/main.c\nindex c51e2fb..5a2305f 100644\n--- a/examples/vmdq/main.c\n+++ b/examples/vmdq/main.c\n@@ -144,6 +144,13 @@ const uint16_t vlan_tags[] = {\n \t48, 49, 50, 51, 52, 53, 54, 55,\n \t56, 57, 58, 59, 60, 61, 62, 63,\n };\n+const uint16_t num_vlans = RTE_DIM(vlan_tags);\n+static uint16_t num_pf_queues,  num_vmdq_queues;\n+static uint16_t vmdq_pool_base, vmdq_queue_base;\n+/* pool mac addr template, pool mac addr is like: 52 54 00 12 port# pool# */\n+static struct ether_addr pool_addr_template = {\n+\t.addr_bytes = {0x52, 0x54, 0x00, 0x12, 0x00, 0x00}\n+};\n \n /* ethernet addresses of ports */\n static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];\n@@ -163,22 +170,9 @@ get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_pools)\n \tunsigned i;\n \n \tconf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;\n+\tconf.nb_pool_maps = num_pools;\n \tconf.enable_default_pool = 0;\n \tconf.default_pool = 0; /* set explicit value, even if not used */\n-\tswitch (num_pools) {\n-\t/* For 10G NIC like 82599, 128 is valid for queue number */\n-\tcase MAX_POOL_NUM_10G:\n-\t\tnum_queues = MAX_QUEUE_NUM_10G;\n-\t\tconf.nb_pool_maps = MAX_POOL_MAP_NUM_10G;\n-\t\tbreak;\n-\t/* For 1G NIC like i350, 82580 and 82576, 8 is valid for queue number */\n-\tcase MAX_POOL_NUM_1G:\n-\t\tnum_queues = MAX_QUEUE_NUM_1G;\n-\t\tconf.nb_pool_maps = MAX_POOL_MAP_NUM_1G;\n-\t\tbreak;\n-\tdefault:\n-\t\treturn -1;\n-\t}\n \n \tfor (i = 0; i < conf.nb_pool_maps; i++){\n \t\tconf.pool_map[i].vlan_id = vlan_tags[ i ];\n@@ -192,40 +186,6 @@ get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_pools)\n }\n \n /*\n- * Validate the pool number accrording to the max pool number gotten form dev_info\n- * If the pool number is invalid, give the error message and return -1\n- */\n-static inline int\n-validate_num_pools(uint32_t max_nb_pools)\n-{\n-\tif (num_pools > max_nb_pools) {\n-\t\tprintf(\"invalid number of pools\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\tswitch (max_nb_pools) {\n-\t/* For 10G NIC like 82599, 64 is valid for pool number */\n-\tcase MAX_POOL_NUM_10G:\n-\t\tif (num_pools != MAX_POOL_NUM_10G) {\n-\t\t\tprintf(\"invalid number of pools\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\t\tbreak;\n-\t/* For 1G NIC like i350, 82580 and 82576, 8 is valid for pool number */\n-\tcase MAX_POOL_NUM_1G:\n-\t\tif (num_pools != MAX_POOL_NUM_1G) {\n-\t\t\tprintf(\"invalid number of pools\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\t\tbreak;\n-\tdefault:\n-\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/*\n  * Initialises a given port using global settings and with the rx buffers\n  * coming from the mbuf_pool passed as parameter\n  */\n@@ -235,26 +195,57 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)\n \tstruct rte_eth_dev_info dev_info;\n \tstruct rte_eth_rxconf *rxconf;\n \tstruct rte_eth_conf port_conf;\n-\tuint16_t rxRings, txRings = (uint16_t)rte_lcore_count();\n+\tuint16_t rxRings, txRings;\n \tconst uint16_t rxRingSize = RTE_TEST_RX_DESC_DEFAULT, txRingSize = RTE_TEST_TX_DESC_DEFAULT;\n \tint retval;\n \tuint16_t q;\n+\tuint16_t queues_per_pool;\n \tuint32_t max_nb_pools;\n \n \t/* The max pool number from dev_info will be used to validate the pool number specified in cmd line */\n \trte_eth_dev_info_get (port, &dev_info);\n \tmax_nb_pools = (uint32_t)dev_info.max_vmdq_pools;\n-\tretval = validate_num_pools(max_nb_pools);\n-\tif (retval < 0)\n-\t\treturn retval;\n-\n-\tretval = get_eth_conf(&port_conf, num_pools);\n+\t/*\n+\t * We allow to process part of VMDQ pools specified by num_pools in\n+\t * command line.\n+\t */\n+\tif (num_pools > max_nb_pools) {\n+\t\tprintf(\"num_pools %d >max_nb_pools %d\\n\",\n+\t\t\tnum_pools, max_nb_pools);\n+\t\treturn -1;\n+\t}\n+\tretval = get_eth_conf(&port_conf, max_nb_pools);\n \tif (retval < 0)\n \t\treturn retval;\n \n+\t/*\n+\t * NIC queues are divided into pf queues and vmdq queues.\n+\t */\n+\t/* There is assumption here all ports have the same configuration! */\n+\tnum_pf_queues = dev_info.max_rx_queues - dev_info.vmdq_queue_num;\n+\tqueues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;\n+\tnum_vmdq_queues = num_pools * queues_per_pool;\n+\tnum_queues = num_pf_queues + num_vmdq_queues;\n+\tvmdq_queue_base = dev_info.vmdq_queue_base;\n+\tvmdq_pool_base  = dev_info.vmdq_pool_base;\n+\n+\tprintf(\"pf queue num: %u, configured vmdq pool num: %u,\"\n+\t\t\" each vmdq pool has %u queues\\n\",\n+\t\tnum_pf_queues, num_pools, queues_per_pool);\n+\tprintf(\"vmdq queue base: %d pool base %d\\n\",\n+\t\tvmdq_queue_base, vmdq_pool_base);\n \tif (port >= rte_eth_dev_count()) return -1;\n \n-\trxRings = (uint16_t)num_queues,\n+\t/*\n+\t * Though in this example, we only receive packets from the first queue\n+\t * of each pool and send packets through first rte_lcore_count() tx\n+\t * queues of vmdq queues, all queues including pf queues are setup.\n+\t * This is because VMDQ queues doesn't always start from zero, and the\n+\t * PMD layer doesn't support selectively initialising part of rx/tx\n+\t * queues.\n+\t */\n+\trxRings = (uint16_t)dev_info.max_rx_queues;\n+\ttxRings = (uint16_t)dev_info.max_tx_queues;\n \tretval = rte_eth_dev_configure(port, rxRings, txRings, &port_conf);\n \tif (retval != 0)\n \t\treturn retval;\n@@ -267,21 +258,27 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)\n \t\t\t\t\trte_eth_dev_socket_id(port),\n \t\t\t\t\trxconf,\n \t\t\t\t\tmbuf_pool);\n-\t\tif (retval < 0)\n+\t\tif (retval < 0) {\n+\t\t\tprintf(\"initialise rx queue %d failed\\n\", q);\n \t\t\treturn retval;\n+\t\t}\n \t}\n \n \tfor (q = 0; q < txRings; q ++) {\n \t\tretval = rte_eth_tx_queue_setup(port, q, txRingSize,\n \t\t\t\t\trte_eth_dev_socket_id(port),\n \t\t\t\t\tNULL);\n-\t\tif (retval < 0)\n+\t\tif (retval < 0) {\n+\t\t\tprintf(\"initialise tx queue %d failed\\n\", q);\n \t\t\treturn retval;\n+\t\t}\n \t}\n \n \tretval  = rte_eth_dev_start(port);\n-\tif (retval < 0)\n+\tif (retval < 0) {\n+\t\tprintf(\"port %d start failed\\n\", port);\n \t\treturn retval;\n+\t}\n \n \trte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);\n \tprintf(\"Port %u MAC: %02\"PRIx8\" %02\"PRIx8\" %02\"PRIx8\n@@ -294,6 +291,29 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)\n \t\t\tvmdq_ports_eth_addr[port].addr_bytes[4],\n \t\t\tvmdq_ports_eth_addr[port].addr_bytes[5]);\n \n+\t/*\n+\t * Set mac for each pool.\n+\t * There is no default mac for the pools in i40.\n+\t * Removes this after i40e fixes this issue.\n+\t */\n+\tfor (q = 0; q < num_pools; q++) {\n+\t\tstruct ether_addr mac;\n+\t\tmac = pool_addr_template;\n+\t\tmac.addr_bytes[4] = port;\n+\t\tmac.addr_bytes[5] = q;\n+\t\tprintf(\"Port %u vmdq pool %u set mac %02x:%02x:%02x:%02x:%02x:%02x\\n\",\n+\t\t\tport, q,\n+\t\t\tmac.addr_bytes[0], mac.addr_bytes[1],\n+\t\t\tmac.addr_bytes[2], mac.addr_bytes[3],\n+\t\t\tmac.addr_bytes[4], mac.addr_bytes[5]);\n+\t\tretval = rte_eth_dev_mac_addr_add(port, &mac,\n+\t\t\t\tq + vmdq_pool_base);\n+\t\tif (retval) {\n+\t\t\tprintf(\"mac addr add failed at pool %d\\n\", q);\n+\t\t\treturn retval;\n+\t\t}\n+\t}\n+\n \treturn 0;\n }\n \n@@ -309,6 +329,11 @@ vmdq_parse_num_pools(const char *q_arg)\n \tif ((q_arg[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n \t\treturn -1;\n \n+\tif (num_pools > num_vlans) {\n+\t\tprintf(\"num_pools %d > num_vlans %d\\n\", num_pools, num_vlans);\n+\t\treturn -1;\n+\t}\n+\n \tnum_pools = n;\n \n \treturn 0;\n@@ -437,7 +462,7 @@ lcore_main(__attribute__((__unused__)) void* dummy)\n \tuint16_t core_id = 0;\n \tuint16_t startQueue, endQueue;\n \tuint16_t q, i, p;\n-\tconst uint16_t remainder = (uint16_t)(num_queues % num_cores);\n+\tconst uint16_t remainder = (uint16_t)(num_vmdq_queues % num_cores);\n \n \tfor (i = 0; i < num_cores; i ++)\n \t\tif (lcore_ids[i] == lcore_id) {\n@@ -447,17 +472,27 @@ lcore_main(__attribute__((__unused__)) void* dummy)\n \n \tif (remainder != 0) {\n \t\tif (core_id < remainder) {\n-\t\t\tstartQueue = (uint16_t)(core_id * (num_queues/num_cores + 1));\n-\t\t\tendQueue = (uint16_t)(startQueue + (num_queues/num_cores) + 1);\n+\t\t\tstartQueue = (uint16_t)(core_id *\n+\t\t\t\t\t(num_vmdq_queues / num_cores + 1));\n+\t\t\tendQueue = (uint16_t)(startQueue +\n+\t\t\t\t\t(num_vmdq_queues / num_cores) + 1);\n \t\t} else {\n-\t\t\tstartQueue = (uint16_t)(core_id * (num_queues/num_cores) + remainder);\n-\t\t\tendQueue = (uint16_t)(startQueue + (num_queues/num_cores));\n+\t\t\tstartQueue = (uint16_t)(core_id *\n+\t\t\t\t\t(num_vmdq_queues / num_cores) +\n+\t\t\t\t\tremainder);\n+\t\t\tendQueue = (uint16_t)(startQueue +\n+\t\t\t\t\t(num_vmdq_queues / num_cores));\n \t\t}\n \t} else {\n-\t\tstartQueue = (uint16_t)(core_id * (num_queues/num_cores));\n-\t\tendQueue = (uint16_t)(startQueue + (num_queues/num_cores));\n+\t\tstartQueue = (uint16_t)(core_id *\n+\t\t\t\t(num_vmdq_queues / num_cores));\n+\t\tendQueue = (uint16_t)(startQueue +\n+\t\t\t\t(num_vmdq_queues / num_cores));\n \t}\n \n+\t/* vmdq queue idx doesn't always start from zero.*/\n+\tstartQueue += vmdq_queue_base;\n+\tendQueue   += vmdq_queue_base;\n \tprintf(\"core %u(lcore %u) reading queues %i-%i\\n\", (unsigned)core_id,\n \t\t(unsigned)lcore_id, startQueue, endQueue - 1);\n \n@@ -490,7 +525,9 @@ lcore_main(__attribute__((__unused__)) void* dummy)\n \t\t\t\t\tupdate_mac_address(buf[i], dport);\n \n \t\t\t\tconst uint16_t txCount = rte_eth_tx_burst(dport,\n-\t\t\t\t\tcore_id, buf, rxCount);\n+\t\t\t\t\tvmdq_queue_base + core_id,\n+\t\t\t\t\tbuf,\n+\t\t\t\t\trxCount);\n \n \t\t\t\tif (txCount != rxCount) {\n \t\t\t\t\tfor (i = txCount; i < rxCount; i++)\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "1/2"
    ]
}