Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/928370/?format=api
{ "id": 928370, "url": "http://patchwork.ozlabs.org/api/patches/928370/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180612151835.86792.93718.stgit@ahduyck-green-test.jf.intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20180612151835.86792.93718.stgit@ahduyck-green-test.jf.intel.com>", "list_archive_url": null, "date": "2018-06-12T15:18:35", "name": "[jkirsher/next-queue,v2,2/7] net: Add support for subordinate device traffic classes", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "43ba8576588d273d9663fad3a177eb722301e314", "submitter": { "id": 251, "url": "http://patchwork.ozlabs.org/api/people/251/?format=api", "name": "Duyck, Alexander H", "email": "alexander.h.duyck@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180612151835.86792.93718.stgit@ahduyck-green-test.jf.intel.com/mbox/", "series": [ { "id": 49759, "url": "http://patchwork.ozlabs.org/api/series/49759/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=49759", "date": "2018-06-12T15:18:25", "name": "Add support for L2 Fwd Offload w/o ndo_select_queue", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/49759/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/928370/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/928370/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.138; helo=whitealder.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com" ], "Received": [ "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 414tz83Jhkz9s1R\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed, 13 Jun 2018 01:27:00 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id F107D89B81;\n\tTue, 12 Jun 2018 15:26:58 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id tKZ1XzXVpOaD; Tue, 12 Jun 2018 15:26:56 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 39D4689B78;\n\tTue, 12 Jun 2018 15:26:56 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id 478F41C0D68\n\tfor <intel-wired-lan@osuosl.org>;\n\tTue, 12 Jun 2018 15:26:53 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 66D9E89D61\n\tfor <intel-wired-lan@osuosl.org>;\n\tTue, 12 Jun 2018 15:26:43 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id A+btZWAXTe3q for <intel-wired-lan@osuosl.org>;\n\tTue, 12 Jun 2018 15:26:42 +0000 (UTC)", "from mga12.intel.com (mga12.intel.com [192.55.52.136])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id A0D8089D4B\n\tfor <intel-wired-lan@osuosl.org>;\n\tTue, 12 Jun 2018 15:26:42 +0000 (UTC)", "from orsmga004.jf.intel.com ([10.7.209.38])\n\tby fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t12 Jun 2018 08:26:42 -0700", "from ahduyck-green-test.jf.intel.com ([10.166.244.179])\n\tby orsmga004.jf.intel.com with ESMTP; 12 Jun 2018 08:26:41 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.51,215,1526367600\"; d=\"scan'208\";a=\"207440866\"", "From": "Alexander Duyck <alexander.h.duyck@intel.com>", "To": "intel-wired-lan@osuosl.org, jeffrey.t.kirsher@intel.com,\n\tnetdev@vger.kernel.org", "Date": "Tue, 12 Jun 2018 11:18:35 -0400", "Message-ID": "<20180612151835.86792.93718.stgit@ahduyck-green-test.jf.intel.com>", "In-Reply-To": "<20180612151322.86792.97587.stgit@ahduyck-green-test.jf.intel.com>", "References": "<20180612151322.86792.97587.stgit@ahduyck-green-test.jf.intel.com>", "User-Agent": "StGit/0.17.1-dirty", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [jkirsher/next-queue PATCH v2 2/7] net: Add\n\tsupport for subordinate device traffic classes", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.24", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "This patch is meant to provide the basic tools needed to allow us to create\nsubordinate device traffic classes. The general idea here is to allow\nsubdividing the queues of a device into queue groups accessible through an\nupper device such as a macvlan.\n\nThe idea here is to enforce the idea that an upper device has to be a\nsingle queue device, ideally with IFF_NO_QUQUE set. With that being the\ncase we can pretty much guarantee that the tc_to_txq mappings and XPS maps\nfor the upper device are unused. As such we could reuse those in order to\nsupport subdividing the lower device and distributing those queues between\nthe subordinate devices.\n\nIn order to distinguish between a regular set of traffic classes and if a\ndevice is carrying subordinate traffic classes I changed num_tc from a u8\nto a s16 value and use the negative values to represent the suboordinate\npool values. So starting at -1 and running to -32768 we can encode those as\npool values, and the existing values of 0 to 15 can be maintained.\n\nSigned-off-by: Alexander Duyck <alexander.h.duyck@intel.com>\n---\n include/linux/netdevice.h | 16 ++++++++\n net/core/dev.c | 89 +++++++++++++++++++++++++++++++++++++++++++++\n net/core/net-sysfs.c | 21 ++++++++++-\n 3 files changed, 124 insertions(+), 2 deletions(-)", "diff": "diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h\nindex 3ec9850..41b4660 100644\n--- a/include/linux/netdevice.h\n+++ b/include/linux/netdevice.h\n@@ -569,6 +569,9 @@ struct netdev_queue {\n \t * (/sys/class/net/DEV/Q/trans_timeout)\n \t */\n \tunsigned long\t\ttrans_timeout;\n+\n+\t/* Suboordinate device that the queue has been assigned to */\n+\tstruct net_device\t*sb_dev;\n /*\n * write-mostly part\n */\n@@ -1978,7 +1981,7 @@ struct net_device {\n #ifdef CONFIG_DCB\n \tconst struct dcbnl_rtnl_ops *dcbnl_ops;\n #endif\n-\tu8\t\t\tnum_tc;\n+\ts16\t\t\tnum_tc;\n \tstruct netdev_tc_txq\ttc_to_txq[TC_MAX_QUEUE];\n \tu8\t\t\tprio_tc_map[TC_BITMASK + 1];\n \n@@ -2032,6 +2035,17 @@ int netdev_get_num_tc(struct net_device *dev)\n \treturn dev->num_tc;\n }\n \n+void netdev_unbind_sb_channel(struct net_device *dev,\n+\t\t\t struct net_device *sb_dev);\n+int netdev_bind_sb_channel_queue(struct net_device *dev,\n+\t\t\t\t struct net_device *sb_dev,\n+\t\t\t\t u8 tc, u16 count, u16 offset);\n+int netdev_set_sb_channel(struct net_device *dev, u16 channel);\n+static inline int netdev_get_sb_channel(struct net_device *dev)\n+{\n+\treturn max_t(int, -dev->num_tc, 0);\n+}\n+\n static inline\n struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev,\n \t\t\t\t\t unsigned int index)\ndiff --git a/net/core/dev.c b/net/core/dev.c\nindex 6e18242..27fe4f2 100644\n--- a/net/core/dev.c\n+++ b/net/core/dev.c\n@@ -2068,11 +2068,13 @@ int netdev_txq_to_tc(struct net_device *dev, unsigned int txq)\n \t\tstruct netdev_tc_txq *tc = &dev->tc_to_txq[0];\n \t\tint i;\n \n+\t\t/* walk through the TCs and see if it falls into any of them */\n \t\tfor (i = 0; i < TC_MAX_QUEUE; i++, tc++) {\n \t\t\tif ((txq - tc->offset) < tc->count)\n \t\t\t\treturn i;\n \t\t}\n \n+\t\t/* didn't find it, just return -1 to indicate no match */\n \t\treturn -1;\n \t}\n \n@@ -2215,7 +2217,14 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,\n \tbool active = false;\n \n \tif (dev->num_tc) {\n+\t\t/* Do not allow XPS on subordinate device directly */\n \t\tnum_tc = dev->num_tc;\n+\t\tif (num_tc < 0)\n+\t\t\treturn -EINVAL;\n+\n+\t\t/* If queue belongs to subordinate dev use its map */\n+\t\tdev = netdev_get_tx_queue(dev, index)->sb_dev ? : dev;\n+\n \t\ttc = netdev_txq_to_tc(dev, index);\n \t\tif (tc < 0)\n \t\t\treturn -EINVAL;\n@@ -2366,11 +2375,25 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,\n EXPORT_SYMBOL(netif_set_xps_queue);\n \n #endif\n+static void netdev_unbind_all_sb_channels(struct net_device *dev)\n+{\n+\tstruct netdev_queue *txq = &dev->_tx[dev->num_tx_queues];\n+\n+\t/* Unbind any subordinate channels */\n+\twhile (txq-- != &dev->_tx[0]) {\n+\t\tif (txq->sb_dev)\n+\t\t\tnetdev_unbind_sb_channel(dev, txq->sb_dev);\n+\t}\n+}\n+\n void netdev_reset_tc(struct net_device *dev)\n {\n #ifdef CONFIG_XPS\n \tnetif_reset_xps_queues_gt(dev, 0);\n #endif\n+\tnetdev_unbind_all_sb_channels(dev);\n+\n+\t/* Reset TC configuration of device */\n \tdev->num_tc = 0;\n \tmemset(dev->tc_to_txq, 0, sizeof(dev->tc_to_txq));\n \tmemset(dev->prio_tc_map, 0, sizeof(dev->prio_tc_map));\n@@ -2399,11 +2422,77 @@ int netdev_set_num_tc(struct net_device *dev, u8 num_tc)\n #ifdef CONFIG_XPS\n \tnetif_reset_xps_queues_gt(dev, 0);\n #endif\n+\tnetdev_unbind_all_sb_channels(dev);\n+\n \tdev->num_tc = num_tc;\n \treturn 0;\n }\n EXPORT_SYMBOL(netdev_set_num_tc);\n \n+void netdev_unbind_sb_channel(struct net_device *dev,\n+\t\t\t struct net_device *sb_dev)\n+{\n+\tstruct netdev_queue *txq = &dev->_tx[dev->num_tx_queues];\n+\n+#ifdef CONFIG_XPS\n+\tnetif_reset_xps_queues_gt(sb_dev, 0);\n+#endif\n+\tmemset(sb_dev->tc_to_txq, 0, sizeof(sb_dev->tc_to_txq));\n+\tmemset(sb_dev->prio_tc_map, 0, sizeof(sb_dev->prio_tc_map));\n+\n+\twhile (txq-- != &dev->_tx[0]) {\n+\t\tif (txq->sb_dev == sb_dev)\n+\t\t\ttxq->sb_dev = NULL;\n+\t}\n+}\n+EXPORT_SYMBOL(netdev_unbind_sb_channel);\n+\n+int netdev_bind_sb_channel_queue(struct net_device *dev,\n+\t\t\t\t struct net_device *sb_dev,\n+\t\t\t\t u8 tc, u16 count, u16 offset)\n+{\n+\t/* Make certain the sb_dev and dev are already configured */\n+\tif (sb_dev->num_tc >= 0 || tc >= dev->num_tc)\n+\t\treturn -EINVAL;\n+\n+\t/* We cannot hand out queues we don't have */\n+\tif ((offset + count) > dev->real_num_tx_queues)\n+\t\treturn -EINVAL;\n+\n+\t/* Record the mapping */\n+\tsb_dev->tc_to_txq[tc].count = count;\n+\tsb_dev->tc_to_txq[tc].offset = offset;\n+\n+\t/* Provide a way for Tx queue to find the tc_to_txq map or\n+\t * XPS map for itself.\n+\t */\n+\twhile (count--)\n+\t\tnetdev_get_tx_queue(dev, count + offset)->sb_dev = sb_dev;\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL(netdev_bind_sb_channel_queue);\n+\n+int netdev_set_sb_channel(struct net_device *dev, u16 channel)\n+{\n+\t/* Do not use a multiqueue device to represent a subordinate channel */\n+\tif (netif_is_multiqueue(dev))\n+\t\treturn -ENODEV;\n+\n+\t/* We allow channels 1 - 32767 to be used for subordinate channels.\n+\t * Channel 0 is meant to be \"native\" mode and used only to represent\n+\t * the main root device. We allow writing 0 to reset the device back\n+\t * to normal mode after being used as a subordinate channel.\n+\t */\n+\tif (channel > S16_MAX)\n+\t\treturn -EINVAL;\n+\n+\tdev->num_tc = -channel;\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL(netdev_set_sb_channel);\n+\n /*\n * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues\n * greater than real_num_tx_queues stale skbs on the qdisc must be flushed.\ndiff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c\nindex 335c6a4..bd067b1 100644\n--- a/net/core/net-sysfs.c\n+++ b/net/core/net-sysfs.c\n@@ -1054,11 +1054,23 @@ static ssize_t traffic_class_show(struct netdev_queue *queue,\n \t\treturn -ENOENT;\n \n \tindex = get_netdev_queue_index(queue);\n+\n+\t/* If queue belongs to subordinate dev use its tc mapping */\n+\tdev = netdev_get_tx_queue(dev, index)->sb_dev ? : dev;\n+\n \ttc = netdev_txq_to_tc(dev, index);\n \tif (tc < 0)\n \t\treturn -EINVAL;\n \n-\treturn sprintf(buf, \"%u\\n\", tc);\n+\t/* We can report the traffic class one of two ways:\n+\t * Subordinate device traffic classes are reported with the traffic\n+\t * class first, and then the subordinate class so for example TC0 on\n+\t * subordinate device 2 will be reported as \"0-2\". If the queue\n+\t * belongs to the root device it will be reported with just the\n+\t * traffic class, so just \"0\" for TC 0 for example.\n+\t */\n+\treturn dev->num_tc < 0 ? sprintf(buf, \"%u%d\\n\", tc, dev->num_tc) :\n+\t\t\t\t sprintf(buf, \"%u\\n\", tc);\n }\n \n #ifdef CONFIG_XPS\n@@ -1225,7 +1237,14 @@ static ssize_t xps_cpus_show(struct netdev_queue *queue,\n \tindex = get_netdev_queue_index(queue);\n \n \tif (dev->num_tc) {\n+\t\t/* Do not allow XPS on subordinate device directly */\n \t\tnum_tc = dev->num_tc;\n+\t\tif (num_tc < 0)\n+\t\t\treturn -EINVAL;\n+\n+\t\t/* If queue belongs to subordinate dev use its map */\n+\t\tdev = netdev_get_tx_queue(dev, index)->sb_dev ? : dev;\n+\n \t\ttc = netdev_txq_to_tc(dev, index);\n \t\tif (tc < 0)\n \t\t\treturn -EINVAL;\n", "prefixes": [ "jkirsher/next-queue", "v2", "2/7" ] }