get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 808506,
    "url": "http://patchwork.ozlabs.org/api/patches/808506/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170901012625.14838-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": "<20170901012625.14838-3-vinicius.gomes@intel.com>",
    "list_archive_url": null,
    "date": "2017-09-01T01:26:22",
    "name": "[RFC,net-next,2/5] net/sched: Introduce Credit Based Shaper (CBS) qdisc",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "651a0424fad72d6b8c8aff45c6cd48c041d225b0",
    "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/20170901012625.14838-3-vinicius.gomes@intel.com/mbox/",
    "series": [
        {
            "id": 935,
            "url": "http://patchwork.ozlabs.org/api/series/935/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=935",
            "date": "2017-09-01T01:26:20",
            "name": "TSN: Add qdisc-based config interfaces for traffic shapers",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/935/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/808506/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/808506/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 3xk1mW70J1z9s7M\n\tfor <patchwork-incoming@ozlabs.org>;\n\tFri,  1 Sep 2017 11:26:35 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751349AbdIAB0d (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tThu, 31 Aug 2017 21:26:33 -0400",
            "from mga02.intel.com ([134.134.136.20]:54382 \"EHLO mga02.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751227AbdIAB0a (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tThu, 31 Aug 2017 21:26:30 -0400",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t31 Aug 2017 18:26:28 -0700",
            "from ellie.jf.intel.com (HELO localhost.localdomain)\n\t([10.24.8.207])\n\tby fmsmga006.fm.intel.com with ESMTP; 31 Aug 2017 18:26:28 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.41,456,1498546800\"; d=\"scan'208\";a=\"146934274\"",
        "From": "Vinicius Costa Gomes <vinicius.gomes@intel.com>",
        "To": "netdev@vger.kernel.org",
        "Cc": "Vinicius Costa Gomes <vinicius.gomes@intel.com>, jhs@mojatatu.com,\n\txiyou.wangcong@gmail.com, jiri@resnulli.us,\n\tintel-wired-lan@lists.osuosl.org, andre.guedes@intel.com,\n\tivan.briano@intel.com, jesus.sanchez-palencia@intel.com,\n\tboon.leong.ong@intel.com, richardcochran@gmail.com",
        "Subject": "[RFC net-next 2/5] net/sched: Introduce Credit Based Shaper (CBS)\n\tqdisc",
        "Date": "Thu, 31 Aug 2017 18:26:22 -0700",
        "Message-Id": "<20170901012625.14838-3-vinicius.gomes@intel.com>",
        "X-Mailer": "git-send-email 2.14.1",
        "In-Reply-To": "<20170901012625.14838-1-vinicius.gomes@intel.com>",
        "References": "<20170901012625.14838-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 net/sched/Kconfig         |  11 ++\n net/sched/Makefile        |   1 +\n net/sched/sch_cbs.c       | 286 ++++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 299 insertions(+)\n create mode 100644 net/sched/sch_cbs.c",
    "diff": "diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h\nindex 35de8312e0b5..dd9a2ecd0c03 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/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..1c86a9e14150\n--- /dev/null\n+++ b/net/sched/sch_cbs.c\n@@ -0,0 +1,286 @@\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:\tVininicius Costa Gomes <vinicius.gomes@intel.com>\n+ *\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+\tstruct Qdisc *qdisc; /* Inner qdisc, default - pfifo queue */\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+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\tint ret;\n+\n+\tret = qdisc_enqueue(skb, q->qdisc, to_free);\n+\tif (ret != NET_XMIT_SUCCESS) {\n+\t\tif (net_xmit_drop_count(ret))\n+\t\t\tqdisc_qstats_drop(sch);\n+\t\treturn ret;\n+\t}\n+\n+\tqdisc_qstats_backlog_inc(sch, skb);\n+\tsch->q.qlen++;\n+\treturn NET_XMIT_SUCCESS;\n+}\n+\n+static struct sk_buff *cbs_dequeue(struct Qdisc *sch)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\tstruct sk_buff *skb;\n+\n+\tskb = q->qdisc->ops->peek(q->qdisc);\n+\tif (skb) {\n+\t\tskb = qdisc_dequeue_peeked(q->qdisc);\n+\t\tif (unlikely(!skb))\n+\t\t\treturn NULL;\n+\n+\t\tqdisc_qstats_backlog_dec(sch, skb);\n+\t\tsch->q.qlen--;\n+\t\tqdisc_bstats_update(sch, skb);\n+\n+\t\treturn skb;\n+\t}\n+\treturn NULL;\n+}\n+\n+static void cbs_reset(struct Qdisc *sch)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\tqdisc_reset(q->qdisc);\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+\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+\tcbs.queue = TC_H_MIN(sch->parent) - 1 - netdev_get_num_tc(dev);\n+\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 = -ENOTSUPP;\n+\tif (!ops->ndo_setup_tc)\n+\t\tgoto done;\n+\n+\terr = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CBS, &cbs);\n+\tif (err < 0)\n+\t\tgoto done;\n+\n+\tq->queue = cbs.queue;\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+\n+\tif (!opt)\n+\t\treturn -EINVAL;\n+\n+\tq->qdisc = fifo_create_dflt(sch, &pfifo_qdisc_ops, 1024);\n+\tqdisc_hash_add(q->qdisc, true);\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+\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+\n+\tcbs.queue = q->queue;\n+\tcbs.enable = 0;\n+\n+\terr = dev->netdev_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+\tqdisc_destroy(q->qdisc);\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+\tsch->qstats.backlog = q->qdisc->qstats.backlog;\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 int cbs_dump_class(struct Qdisc *sch, unsigned long cl,\n+\t\t\t  struct sk_buff *skb, struct tcmsg *tcm)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\ttcm->tcm_handle |= TC_H_MIN(1);\n+\ttcm->tcm_info = q->qdisc->handle;\n+\n+\treturn 0;\n+}\n+\n+static int cbs_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,\n+\t\t     struct Qdisc **old)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\tif (!new)\n+\t\tnew = &noop_qdisc;\n+\n+\t*old = qdisc_replace(sch, new, &q->qdisc);\n+\treturn 0;\n+}\n+\n+static struct Qdisc *cbs_leaf(struct Qdisc *sch, unsigned long arg)\n+{\n+\tstruct cbs_sched_data *q = qdisc_priv(sch);\n+\n+\treturn q->qdisc;\n+}\n+\n+static unsigned long cbs_find(struct Qdisc *sch, u32 classid)\n+{\n+\treturn 1;\n+}\n+\n+static int cbs_delete(struct Qdisc *sch, unsigned long arg)\n+{\n+\treturn 0;\n+}\n+\n+static void cbs_walk(struct Qdisc *sch, struct qdisc_walker *walker)\n+{\n+\tif (!walker->stop) {\n+\t\tif (walker->count >= walker->skip)\n+\t\t\tif (walker->fn(sch, 1, walker) < 0) {\n+\t\t\t\twalker->stop = 1;\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\twalker->count++;\n+\t}\n+}\n+\n+static const struct Qdisc_class_ops cbs_class_ops = {\n+\t.graft\t\t=\tcbs_graft,\n+\t.leaf\t\t=\tcbs_leaf,\n+\t.find\t\t=\tcbs_find,\n+\t.delete\t\t=\tcbs_delete,\n+\t.walk\t\t=\tcbs_walk,\n+\t.dump\t\t=\tcbs_dump_class,\n+};\n+\n+static struct Qdisc_ops cbs_qdisc_ops __read_mostly = {\n+\t.next\t\t=\tNULL,\n+\t.cl_ops\t\t=\t&cbs_class_ops,\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=\tcbs_reset,\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": [
        "RFC",
        "net-next",
        "2/5"
    ]
}