Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/818859/?format=api
{ "id": 818859, "url": "http://patchwork.ozlabs.org/api/patches/818859/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170926233916.11774-3-vinicius.gomes@intel.com/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api", "name": "Linux network development", "link_name": "netdev", "list_id": "netdev.vger.kernel.org", "list_email": "netdev@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20170926233916.11774-3-vinicius.gomes@intel.com>", "list_archive_url": null, "date": "2017-09-26T23:39:15", "name": "[next-queue,2/3] net/sched: Introduce Credit Based Shaper (CBS) qdisc", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": true, "hash": "c8308435c6eff3d5ac733601fd251b98e82b45a5", "submitter": { "id": 72272, "url": "http://patchwork.ozlabs.org/api/people/72272/?format=api", "name": "Vinicius Costa Gomes", "email": "vinicius.gomes@intel.com" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/20170926233916.11774-3-vinicius.gomes@intel.com/mbox/", "series": [ { "id": 5244, "url": "http://patchwork.ozlabs.org/api/series/5244/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=5244", "date": "2017-09-26T23:39:14", "name": "TSN: Add qdisc based config interface for CBS", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/5244/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/818859/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/818859/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y1y9C2CFbz9t4b\n\tfor <patchwork-incoming@ozlabs.org>;\n\tWed, 27 Sep 2017 09:39:43 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1032681AbdIZXjk (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tTue, 26 Sep 2017 19:39:40 -0400", "from mga01.intel.com ([192.55.52.88]:52876 \"EHLO mga01.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1031407AbdIZXjf (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tTue, 26 Sep 2017 19:39:35 -0400", "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t26 Sep 2017 16:39:33 -0700", "from ellie.jf.intel.com (HELO localhost.localdomain)\n\t([10.24.13.43])\n\tby orsmga001.jf.intel.com with ESMTP; 26 Sep 2017 16:39:33 -0700" ], "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.42,442,1500966000\"; d=\"scan'208\";a=\"1176126582\"", "From": "Vinicius Costa Gomes <vinicius.gomes@intel.com>", "To": "netdev@vger.kernel.org, intel-wired-lan@lists.osuosl.org", "Cc": "Vinicius Costa Gomes <vinicius.gomes@intel.com>, jhs@mojatatu.com,\n\txiyou.wangcong@gmail.com, jiri@resnulli.us, andre.guedes@intel.com,\n\tivan.briano@intel.com, jesus.sanchez-palencia@intel.com,\n\tboon.leong.ong@intel.com, richardcochran@gmail.com, henrik@austad.us", "Subject": "[next-queue PATCH 2/3] net/sched: Introduce Credit Based Shaper\n\t(CBS) qdisc", "Date": "Tue, 26 Sep 2017 16:39:15 -0700", "Message-Id": "<20170926233916.11774-3-vinicius.gomes@intel.com>", "X-Mailer": "git-send-email 2.14.2", "In-Reply-To": "<20170926233916.11774-1-vinicius.gomes@intel.com>", "References": "<20170926233916.11774-1-vinicius.gomes@intel.com>", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "This queueing discipline implements the shaper algorithm defined by\nthe 802.1Q-2014 Section 8.6.8.2 and detailed in Annex L.\n\nIt's primary usage is to apply some bandwidth reservation to user\ndefined traffic classes, which are mapped to different queues via the\nmqprio qdisc.\n\nInitially, it only supports offloading the traffic shaping work to\nsupporting controllers.\n\nLater, when a software implementation is added, the current dependency\non being installed \"under\" mqprio can be lifted.\n\nSigned-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>\nSigned-off-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>\n---\n include/linux/netdevice.h | 1 +\n include/net/pkt_sched.h | 9 ++\n net/sched/Kconfig | 12 +++\n net/sched/Makefile | 1 +\n net/sched/sch_cbs.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 252 insertions(+)\n create mode 100644 net/sched/sch_cbs.c", "diff": "diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h\nindex f535779d9dc1..5d6fb06fd80f 100644\n--- a/include/linux/netdevice.h\n+++ b/include/linux/netdevice.h\n@@ -775,6 +775,7 @@ enum tc_setup_type {\n \tTC_SETUP_CLSFLOWER,\n \tTC_SETUP_CLSMATCHALL,\n \tTC_SETUP_CLSBPF,\n+\tTC_SETUP_CBS,\n };\n \n /* These structures hold the attributes of xdp state that are being passed\ndiff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h\nindex 259bc191ba59..7c597b050b36 100644\n--- a/include/net/pkt_sched.h\n+++ b/include/net/pkt_sched.h\n@@ -146,4 +146,13 @@ static inline bool is_classid_clsact_egress(u32 classid)\n \t TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_EGRESS);\n }\n \n+struct tc_cbs_qopt_offload {\n+\tu8 enable;\n+\ts32 queue;\n+\ts32 hicredit;\n+\ts32 locredit;\n+\ts32 idleslope;\n+\ts32 sendslope;\n+};\n+\n #endif\ndiff --git a/net/sched/Kconfig b/net/sched/Kconfig\nindex e70ed26485a2..2dd24d231243 100644\n--- a/net/sched/Kconfig\n+++ b/net/sched/Kconfig\n@@ -172,6 +172,18 @@ config NET_SCH_TBF\n \t To compile this code as a module, choose M here: the\n \t module will be called sch_tbf.\n \n+config NET_SCH_CBS\n+\ttristate \"Credit Based Shaper (CBS)\"\n+\tdepends on NET_SCH_MQPRIO\n+\t---help---\n+\t Say Y here if you want to use the Credit Based Shaper (CBS) packet\n+\t scheduling algorithm.\n+\n+\t See the top of <file:net/sched/sch_cbs.c> for more details.\n+\n+\t To compile this code as a module, choose M here: the\n+\t module will be called sch_cbs.\n+\n config NET_SCH_GRED\n \ttristate \"Generic Random Early Detection (GRED)\"\n \t---help---\ndiff --git a/net/sched/Makefile b/net/sched/Makefile\nindex 7b915d226de7..80c8f92d162d 100644\n--- a/net/sched/Makefile\n+++ b/net/sched/Makefile\n@@ -52,6 +52,7 @@ obj-$(CONFIG_NET_SCH_FQ_CODEL)\t+= sch_fq_codel.o\n obj-$(CONFIG_NET_SCH_FQ)\t+= sch_fq.o\n obj-$(CONFIG_NET_SCH_HHF)\t+= sch_hhf.o\n obj-$(CONFIG_NET_SCH_PIE)\t+= sch_pie.o\n+obj-$(CONFIG_NET_SCH_CBS)\t+= sch_cbs.o\n \n obj-$(CONFIG_NET_CLS_U32)\t+= cls_u32.o\n obj-$(CONFIG_NET_CLS_ROUTE4)\t+= cls_route.o\ndiff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c\nnew file mode 100644\nindex 000000000000..6e1b7272d685\n--- /dev/null\n+++ b/net/sched/sch_cbs.c\n@@ -0,0 +1,229 @@\n+/*\n+ * net/sched/sch_cbs.c\tCredit Based Shaper\n+ *\n+ *\t\tThis program is free software; you can redistribute it and/or\n+ *\t\tmodify it under the terms of the GNU General Public License\n+ *\t\tas published by the Free Software Foundation; either version\n+ *\t\t2 of the License, or (at your option) any later version.\n+ *\n+ * Authors:\tVinicius Costa Gomes <vinicius.gomes@intel.com>\n+ *\n+ */\n+\n+/* Credit Based Shaper (CBS)\n+ =========================\n+\n+ This is a simple rate-limiting shaper aimed at TSN applications on\n+ systems with known traffic workloads.\n+\n+ Its algorithm is defined by the IEEE 802.1Q-2014 Specification,\n+ Section 8.6.8.2, and explained in more detail in the Annex L of the\n+ same specification.\n+\n+ There are four tunables to be considered:\n+\n+\t'idleslope': Idleslope is the rate of credits that is\n+\taccumulated (in kilobits per second) when there is at least\n+\tone packet waiting for transmission. Packets are transmitted\n+\twhen the current value of credits is equal or greater than\n+\tzero. When there is no packet to be transmitted the amount of\n+\tcredits is set to zero. This is the main tunable of the CBS\n+\talgorithm.\n+\n+\t'sendslope':\n+\tSendslope is the rate of credits that is depleted (it should be a\n+\tnegative number of kilobits per second) when a transmission is\n+\tocurring. It can be calculated as follows, (IEEE 802.1Q-2014 Section\n+\t8.6.8.2 item g):\n+\n+\tsendslope = idleslope - port_transmit_rate\n+\n+\t'hicredit': Hicredit defines the maximum amount of credits (in\n+\tbytes) that can be accumulated. Hicredit depends on the\n+\tcharacteristics of interfering traffic,\n+\t'max_interference_size' is the maximum size of any burst of\n+\ttraffic that can delay the transmission of a frame that is\n+\tavailable for transmission for this traffic class, (IEEE\n+\t802.1Q-2014 Annex L, Equation L-3):\n+\n+\thicredit = max_interference_size * (idleslope / port_transmit_rate)\n+\n+\t'locredit': Locredit is the minimum amount of credits that can\n+\tbe reached. It is a function of the traffic flowing through\n+\tthis qdisc (IEEE 802.1Q-2014 Annex L, Equation L-2):\n+\n+\tlocredit = max_frame_size * (sendslope / port_transmit_rate)\n+*/\n+\n+#include <linux/module.h>\n+#include <linux/types.h>\n+#include <linux/kernel.h>\n+#include <linux/string.h>\n+#include <linux/errno.h>\n+#include <linux/skbuff.h>\n+#include <net/netlink.h>\n+#include <net/sch_generic.h>\n+#include <net/pkt_sched.h>\n+\n+struct cbs_sched_data {\n+\ts32 queue;\n+\ts32 locredit;\n+\ts32 hicredit;\n+\ts32 sendslope;\n+\ts32 idleslope;\n+};\n+\n+static int cbs_enqueue(struct sk_buff *skb, struct Qdisc *sch,\n+\t\t struct sk_buff **to_free)\n+{\n+\treturn qdisc_enqueue_tail(skb, sch);\n+}\n+\n+static const struct nla_policy cbs_policy[TCA_CBS_MAX + 1] = {\n+\t[TCA_CBS_PARMS]\t= { .len = sizeof(struct tc_cbs_qopt) },\n+};\n+\n+static int cbs_change(struct Qdisc *sch, struct nlattr *opt)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\tstruct tc_cbs_qopt_offload cbs = { };\n+\tstruct nlattr *tb[TCA_CBS_MAX + 1];\n+\tconst struct net_device_ops *ops;\n+\tstruct tc_cbs_qopt *qopt;\n+\tstruct net_device *dev;\n+\tint err;\n+\n+\terr = nla_parse_nested(tb, TCA_CBS_MAX, opt, cbs_policy, NULL);\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\terr = -EINVAL;\n+\tif (!tb[TCA_CBS_PARMS])\n+\t\tgoto done;\n+\n+\tqopt = nla_data(tb[TCA_CBS_PARMS]);\n+\n+\tdev = qdisc_dev(sch);\n+\tops = dev->netdev_ops;\n+\n+\tcbs.queue = q->queue;\n+\tcbs.enable = 1;\n+\tcbs.hicredit = qopt->hicredit;\n+\tcbs.locredit = qopt->locredit;\n+\tcbs.idleslope = qopt->idleslope;\n+\tcbs.sendslope = qopt->sendslope;\n+\n+\terr = -EOPNOTSUPP;\n+\tif (!ops->ndo_setup_tc)\n+\t\tgoto done;\n+\n+\terr = ops->ndo_setup_tc(dev, TC_SETUP_CBS, &cbs);\n+\tif (err < 0)\n+\t\tgoto done;\n+\n+\tq->hicredit = cbs.hicredit;\n+\tq->locredit = cbs.locredit;\n+\tq->idleslope = cbs.idleslope;\n+\tq->sendslope = cbs.sendslope;\n+\n+done:\n+\treturn err;\n+}\n+\n+static int cbs_init(struct Qdisc *sch, struct nlattr *opt)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\tstruct net_device *dev = qdisc_dev(sch);\n+\n+\tif (!opt)\n+\t\treturn -EINVAL;\n+\n+\t/* FIXME: this means that we can only install this qdisc\n+\t * \"under\" mqprio. Do we need a more generic way to retrieve\n+\t * the queue, or do we pass the netdev_queue to the driver?\n+\t */\n+\tq->queue = TC_H_MIN(sch->parent) - 1 - netdev_get_num_tc(dev);\n+\n+\treturn cbs_change(sch, opt);\n+}\n+\n+static void cbs_destroy(struct Qdisc *sch)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\tstruct tc_cbs_qopt_offload cbs = { };\n+\tconst struct net_device_ops *ops;\n+\tstruct net_device *dev;\n+\tint err;\n+\n+\tq->hicredit = 0;\n+\tq->locredit = 0;\n+\tq->idleslope = 0;\n+\tq->sendslope = 0;\n+\n+\tdev = qdisc_dev(sch);\n+\tops = dev->netdev_ops;\n+\n+\tif (!ops->ndo_setup_tc)\n+\t\treturn;\n+\n+\tcbs.queue = q->queue;\n+\tcbs.enable = 0;\n+\n+\terr = ops->ndo_setup_tc(dev, TC_SETUP_CBS, &cbs);\n+\tif (err < 0)\n+\t\tpr_warn(\"Couldn't reset queue %d to default values\\n\",\n+\t\t\tcbs.queue);\n+}\n+\n+static int cbs_dump(struct Qdisc *sch, struct sk_buff *skb)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\tstruct nlattr *nest;\n+\tstruct tc_cbs_qopt opt;\n+\n+\tnest = nla_nest_start(skb, TCA_OPTIONS);\n+\tif (!nest)\n+\t\tgoto nla_put_failure;\n+\n+\topt.hicredit = q->hicredit;\n+\topt.locredit = q->locredit;\n+\topt.sendslope = q->sendslope;\n+\topt.idleslope = q->idleslope;\n+\n+\tif (nla_put(skb, TCA_CBS_PARMS, sizeof(opt), &opt))\n+\t\tgoto nla_put_failure;\n+\n+\treturn nla_nest_end(skb, nest);\n+\n+nla_put_failure:\n+\tnla_nest_cancel(skb, nest);\n+\treturn -1;\n+}\n+\n+static struct Qdisc_ops cbs_qdisc_ops __read_mostly = {\n+\t.next\t\t=\tNULL,\n+\t.id\t\t=\t\"cbs\",\n+\t.priv_size\t=\tsizeof(struct cbs_sched_data),\n+\t.enqueue\t=\tcbs_enqueue,\n+\t.dequeue\t=\tqdisc_dequeue_head,\n+\t.peek\t\t=\tqdisc_peek_dequeued,\n+\t.init\t\t=\tcbs_init,\n+\t.reset\t\t=\tqdisc_reset_queue,\n+\t.destroy\t=\tcbs_destroy,\n+\t.change\t\t=\tcbs_change,\n+\t.dump\t\t=\tcbs_dump,\n+\t.owner\t\t=\tTHIS_MODULE,\n+};\n+\n+static int __init cbs_module_init(void)\n+{\n+\treturn register_qdisc(&cbs_qdisc_ops);\n+}\n+\n+static void __exit cbs_module_exit(void)\n+{\n+\tunregister_qdisc(&cbs_qdisc_ops);\n+}\n+module_init(cbs_module_init)\n+module_exit(cbs_module_exit)\n+MODULE_LICENSE(\"GPL\");\n", "prefixes": [ "next-queue", "2/3" ] }