Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/826672/?format=api
{ "id": 826672, "url": "http://patchwork.ozlabs.org/api/patches/826672/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20171017010128.22141-5-vinicius.gomes@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": "<20171017010128.22141-5-vinicius.gomes@intel.com>", "list_archive_url": null, "date": "2017-10-17T01:01:26", "name": "[next-queue,v9,4/6] net/sched: Introduce Credit Based Shaper (CBS) qdisc", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "c2c025d7210e8a203da7511baed28692f5f134fe", "submitter": { "id": 72272, "url": "http://patchwork.ozlabs.org/api/people/72272/?format=api", "name": "Vinicius Costa Gomes", "email": "vinicius.gomes@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/20171017010128.22141-5-vinicius.gomes@intel.com/mbox/", "series": [ { "id": 8543, "url": "http://patchwork.ozlabs.org/api/series/8543/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=8543", "date": "2017-10-17T01:01:23", "name": "TSN: Add qdisc based config interface for CBS", "version": 9, "mbox": "http://patchwork.ozlabs.org/series/8543/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/826672/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/826672/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.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>)", "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 3yGH2n0wG6z9sP1\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 17 Oct 2017 12:01:52 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 5A742865EB;\n\tTue, 17 Oct 2017 01:01:51 +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 iNj5aFiJ6WQu; Tue, 17 Oct 2017 01:01:49 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 2D6B38654B;\n\tTue, 17 Oct 2017 01:01:49 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id DD62D1CEF32\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 17 Oct 2017 01:01:46 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id D4D4C86C4B\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 17 Oct 2017 01:01:46 +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 S4oDStEHlEv0 for <intel-wired-lan@lists.osuosl.org>;\n\tTue, 17 Oct 2017 01:01:45 +0000 (UTC)", "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id 8AFF886D1D\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 17 Oct 2017 01:01:44 +0000 (UTC)", "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t16 Oct 2017 18:01:44 -0700", "from ellie.jf.intel.com (HELO localhost.localdomain)\n\t([10.24.13.70])\n\tby fmsmga002.fm.intel.com with ESMTP; 16 Oct 2017 18:01:43 -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-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos; i=\"5.43,389,1503385200\"; d=\"scan'208\";\n\ta=\"1231539041\"", "From": "Vinicius Costa Gomes <vinicius.gomes@intel.com>", "To": "netdev@vger.kernel.org,\n\tintel-wired-lan@lists.osuosl.org", "Date": "Mon, 16 Oct 2017 18:01:26 -0700", "Message-Id": "<20171017010128.22141-5-vinicius.gomes@intel.com>", "X-Mailer": "git-send-email 2.14.2", "In-Reply-To": "<20171017010128.22141-1-vinicius.gomes@intel.com>", "References": "<20171017010128.22141-1-vinicius.gomes@intel.com>", "Cc": "rodney.cummings@ni.com, andre.guedes@intel.com, jiri@resnulli.us,\n\tivan.briano@intel.com, richardcochran@gmail.com, henrik@austad.us,\n\tjhs@mojatatu.com, levipearson@gmail.com, boon.leong.ong@intel.com,\n\txiyou.wangcong@gmail.com, jesus.sanchez-palencia@intel.com", "Subject": "[Intel-wired-lan] [next-queue PATCH v9 4/6] net/sched: Introduce\n\tCredit Based Shaper (CBS) qdisc", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.18-1", "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>", "MIME-Version": "1.0", "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 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\nOnly a simple software implementation is added for now.\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/uapi/linux/pkt_sched.h | 19 +++\n net/sched/Kconfig | 11 ++\n net/sched/Makefile | 1 +\n net/sched/sch_cbs.c | 293 +++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 324 insertions(+)\n create mode 100644 net/sched/sch_cbs.c", "diff": "diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h\nindex 099bf5528fed..25b6ab82a586 100644\n--- a/include/uapi/linux/pkt_sched.h\n+++ b/include/uapi/linux/pkt_sched.h\n@@ -871,4 +871,23 @@ struct tc_pie_xstats {\n \t__u32 maxq; /* maximum queue size */\n \t__u32 ecn_mark; /* packets marked with ecn*/\n };\n+\n+/* CBS */\n+struct tc_cbs_qopt {\n+\t__u8 offload;\n+\t__u8 _pad[3];\n+\t__s32 hicredit;\n+\t__s32 locredit;\n+\t__s32 idleslope;\n+\t__s32 sendslope;\n+};\n+\n+enum {\n+\tTCA_CBS_UNSPEC,\n+\tTCA_CBS_PARMS,\n+\t__TCA_CBS_MAX,\n+};\n+\n+#define TCA_CBS_MAX (__TCA_CBS_MAX - 1)\n+\n #endif\ndiff --git a/net/sched/Kconfig b/net/sched/Kconfig\nindex e70ed26485a2..c03d86a7775e 100644\n--- a/net/sched/Kconfig\n+++ b/net/sched/Kconfig\n@@ -172,6 +172,17 @@ 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+\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..c0102b589494\n--- /dev/null\n+++ b/net/sched/sch_cbs.c\n@@ -0,0 +1,293 @@\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+#define BYTES_PER_KBIT (1000LL / 8)\n+\n+struct cbs_sched_data {\n+\ts64 port_rate; /* in bytes/s */\n+\ts64 last; /* timestamp in ns */\n+\ts64 credits; /* in bytes */\n+\ts32 locredit; /* in bytes */\n+\ts32 hicredit; /* in bytes */\n+\ts64 sendslope; /* in bytes/s */\n+\ts64 idleslope; /* in bytes/s */\n+\tstruct qdisc_watchdog watchdog;\n+\tint (*enqueue)(struct sk_buff *skb, struct Qdisc *sch);\n+\tstruct sk_buff *(*dequeue)(struct Qdisc *sch);\n+};\n+\n+static int cbs_enqueue_soft(struct sk_buff *skb, struct Qdisc *sch)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\tif (sch->q.qlen == 0 && q->credits > 0) {\n+\t\t/* We need to stop accumulating credits when there's\n+\t\t * no enqueued packets and q->credits is positive.\n+\t\t */\n+\t\tq->credits = 0;\n+\t\tq->last = ktime_get_ns();\n+\t}\n+\n+\treturn qdisc_enqueue_tail(skb, sch);\n+}\n+\n+static int cbs_enqueue(struct sk_buff *skb, struct Qdisc *sch,\n+\t\t struct sk_buff **to_free)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\treturn q->enqueue(skb, sch);\n+}\n+\n+/* timediff is in ns, slope is in bytes/s */\n+static s64 timediff_to_credits(s64 timediff, s64 slope)\n+{\n+\treturn div64_s64(timediff * slope, NSEC_PER_SEC);\n+}\n+\n+static s64 delay_from_credits(s64 credits, s64 slope)\n+{\n+\tif (unlikely(slope == 0))\n+\t\treturn S64_MAX;\n+\n+\treturn div64_s64(-credits * NSEC_PER_SEC, slope);\n+}\n+\n+static s64 credits_from_len(unsigned int len, s64 slope, s64 port_rate)\n+{\n+\tif (unlikely(port_rate == 0))\n+\t\treturn S64_MAX;\n+\n+\treturn div64_s64(len * slope, port_rate);\n+}\n+\n+static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\ts64 now = ktime_get_ns();\n+\tstruct sk_buff *skb;\n+\ts64 credits;\n+\tint len;\n+\n+\tif (q->credits < 0) {\n+\t\tcredits = timediff_to_credits(now - q->last, q->idleslope);\n+\n+\t\tcredits = q->credits + credits;\n+\t\tq->credits = min_t(s64, credits, q->hicredit);\n+\n+\t\tif (q->credits < 0) {\n+\t\t\ts64 delay;\n+\n+\t\t\tdelay = delay_from_credits(q->credits, q->idleslope);\n+\t\t\tqdisc_watchdog_schedule_ns(&q->watchdog, now + delay);\n+\n+\t\t\tq->last = now;\n+\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\tskb = qdisc_dequeue_head(sch);\n+\tif (!skb)\n+\t\treturn NULL;\n+\n+\tlen = qdisc_pkt_len(skb);\n+\n+\t/* As sendslope is a negative number, this will decrease the\n+\t * amount of q->credits.\n+\t */\n+\tcredits = credits_from_len(len, q->sendslope, q->port_rate);\n+\tcredits += q->credits;\n+\n+\tq->credits = max_t(s64, credits, q->locredit);\n+\tq->last = now;\n+\n+\treturn skb;\n+}\n+\n+static struct sk_buff *cbs_dequeue(struct Qdisc *sch)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\treturn q->dequeue(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 net_device *dev = qdisc_dev(sch);\n+\tstruct nlattr *tb[TCA_CBS_MAX + 1];\n+\tstruct ethtool_link_ksettings ecmd;\n+\tstruct tc_cbs_qopt *qopt;\n+\ts64 link_speed;\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+\tif (!tb[TCA_CBS_PARMS])\n+\t\treturn -EINVAL;\n+\n+\tqopt = nla_data(tb[TCA_CBS_PARMS]);\n+\n+\tif (qopt->offload)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (!__ethtool_get_link_ksettings(dev, &ecmd))\n+\t\tlink_speed = ecmd.base.speed;\n+\telse\n+\t\tlink_speed = SPEED_1000;\n+\n+\tq->port_rate = link_speed * 1000 * BYTES_PER_KBIT;\n+\n+\tq->enqueue = cbs_enqueue_soft;\n+\tq->dequeue = cbs_dequeue_soft;\n+\n+\tq->hicredit = qopt->hicredit;\n+\tq->locredit = qopt->locredit;\n+\tq->idleslope = qopt->idleslope * BYTES_PER_KBIT;\n+\tq->sendslope = qopt->sendslope * BYTES_PER_KBIT;\n+\n+\treturn 0;\n+}\n+\n+static int cbs_init(struct Qdisc *sch, struct nlattr *opt)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\tif (!opt)\n+\t\treturn -EINVAL;\n+\n+\tqdisc_watchdog_init(&q->watchdog, sch);\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+\n+\tqdisc_watchdog_cancel(&q->watchdog);\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 tc_cbs_qopt opt = { };\n+\tstruct nlattr *nest;\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 / BYTES_PER_KBIT;\n+\topt.idleslope = q->idleslope / BYTES_PER_KBIT;\n+\topt.offload = 0;\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.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=\tcbs_dequeue,\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", "v9", "4/6" ] }