get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 810973,
    "url": "http://patchwork.ozlabs.org/api/patches/810973/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/150478222784.24794.2140314459685193340.stgit@anamdev.jf.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": "<150478222784.24794.2140314459685193340.stgit@anamdev.jf.intel.com>",
    "list_archive_url": null,
    "date": "2017-09-07T11:03:47",
    "name": "[RFC,iproute2,v2] tc/mqprio: Offload mode and shaper options in mqprio",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "15abe61c4f9a09d6624bb1b1654a32df736c752b",
    "submitter": {
        "id": 68504,
        "url": "http://patchwork.ozlabs.org/api/people/68504/?format=api",
        "name": "Nambiar, Amritha",
        "email": "amritha.nambiar@intel.com"
    },
    "delegate": {
        "id": 389,
        "url": "http://patchwork.ozlabs.org/api/users/389/?format=api",
        "username": "shemminger",
        "first_name": "stephen",
        "last_name": "hemminger",
        "email": "shemminger@vyatta.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/150478222784.24794.2140314459685193340.stgit@anamdev.jf.intel.com/mbox/",
    "series": [
        {
            "id": 1980,
            "url": "http://patchwork.ozlabs.org/api/series/1980/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=1980",
            "date": "2017-09-07T11:03:47",
            "name": "[RFC,iproute2,v2] tc/mqprio: Offload mode and shaper options in mqprio",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/1980/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/810973/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/810973/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 3xnyK502xpz9s81\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu,  7 Sep 2017 21:04:56 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1754887AbdIGLEy (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tThu, 7 Sep 2017 07:04:54 -0400",
            "from mga11.intel.com ([192.55.52.93]:61588 \"EHLO mga11.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1753927AbdIGLEx (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tThu, 7 Sep 2017 07:04:53 -0400",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t07 Sep 2017 04:04:52 -0700",
            "from anamdev.jf.intel.com ([10.166.29.110])\n\tby fmsmga006.fm.intel.com with ESMTP; 07 Sep 2017 04:04:52 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.42,357,1500966000\"; d=\"scan'208\";a=\"149198405\"",
        "Subject": "[RFC,\n\tiproute2 PATCH v2] tc/mqprio: Offload mode and shaper options in\n\tmqprio",
        "From": "Amritha Nambiar <amritha.nambiar@intel.com>",
        "To": "stephen@networkplumber.org, netdev@vger.kernel.org",
        "Cc": "alexander.h.duyck@intel.com, amritha.nambiar@intel.com",
        "Date": "Thu, 07 Sep 2017 04:03:47 -0700",
        "Message-ID": "<150478222784.24794.2140314459685193340.stgit@anamdev.jf.intel.com>",
        "User-Agent": "StGit/0.17.1-dirty",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "7bit",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "Adds new mqprio options for 'mode' and 'shaper'. The mode\noption can take values for offload modes such as 'dcb' (default),\n'channel' with the 'hw' option set to 1. The 'shaper' option is\nto support HW shapers ('dcb' default) and takes the value\n'bw_rlimit' for bandwidth rate limiting. The parameters to the\nbw_rlimit shaper are minimum and maximum bandwidth rates.\nNew HW shapers in future can be supported through the shaper\nattribute.\n\n# tc qdisc add dev eth0 root mqprio num_tc 2  map 0 0 0 0 1 1 1 1\\\n  queues 4@0 4@4 hw 1 mode channel shaper bw_rlimit\\\n  min_rate 1Gbit 2Gbit max_rate 4Gbit 5Gbit\n\n# tc qdisc show dev eth0\n\nqdisc mqprio 804a: root  tc 2 map 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0\n             queues:(0:3) (4:7)\n             mode:channel\n             shaper:bw_rlimit   min_rate:1Gbit 2Gbit   max_rate:4Gbit 5Gbit\n\nSigned-off-by: Amritha Nambiar <amritha.nambiar@intel.com>\n---\n include/linux/pkt_sched.h |   32 ++++++++\n tc/q_mqprio.c             |  191 +++++++++++++++++++++++++++++++++++++++++++--\n 2 files changed, 216 insertions(+), 7 deletions(-)",
    "diff": "diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h\nindex 099bf55..e95b5c9 100644\n--- a/include/linux/pkt_sched.h\n+++ b/include/linux/pkt_sched.h\n@@ -625,6 +625,22 @@ enum {\n \n #define TC_MQPRIO_HW_OFFLOAD_MAX (__TC_MQPRIO_HW_OFFLOAD_MAX - 1)\n \n+enum {\n+\tTC_MQPRIO_MODE_DCB,\n+\tTC_MQPRIO_MODE_CHANNEL,\n+\t__TC_MQPRIO_MODE_MAX\n+};\n+\n+#define __TC_MQPRIO_MODE_MAX (__TC_MQPRIO_MODE_MAX - 1)\n+\n+enum {\n+\tTC_MQPRIO_SHAPER_DCB,\n+\tTC_MQPRIO_SHAPER_BW_RATE,\t/* Add new shapers below */\n+\t__TC_MQPRIO_SHAPER_MAX\n+};\n+\n+#define __TC_MQPRIO_SHAPER_MAX (__TC_MQPRIO_SHAPER_MAX - 1)\n+\n struct tc_mqprio_qopt {\n \t__u8\tnum_tc;\n \t__u8\tprio_tc_map[TC_QOPT_BITMASK + 1];\n@@ -633,6 +649,22 @@ struct tc_mqprio_qopt {\n \t__u16\toffset[TC_QOPT_MAX_QUEUE];\n };\n \n+#define TC_MQPRIO_F_MODE\t\t0x1\n+#define TC_MQPRIO_F_SHAPER\t\t0x2\n+#define TC_MQPRIO_F_MIN_RATE\t\t0x4\n+#define TC_MQPRIO_F_MAX_RATE\t\t0x8\n+\n+enum {\n+\tTCA_MQPRIO_UNSPEC,\n+\tTCA_MQPRIO_MODE,\n+\tTCA_MQPRIO_SHAPER,\n+\tTCA_MQPRIO_MIN_RATE64,\n+\tTCA_MQPRIO_MAX_RATE64,\n+\t__TCA_MQPRIO_MAX,\n+};\n+\n+#define TCA_MQPRIO_MAX (__TCA_MQPRIO_MAX - 1)\n+\n /* SFB */\n \n enum {\ndiff --git a/tc/q_mqprio.c b/tc/q_mqprio.c\nindex d6718fb..5fec63d 100644\n--- a/tc/q_mqprio.c\n+++ b/tc/q_mqprio.c\n@@ -27,6 +27,10 @@ static void explain(void)\n \tfprintf(stderr, \"Usage: ... mqprio [num_tc NUMBER] [map P0 P1 ...]\\n\");\n \tfprintf(stderr, \"                  [queues count1@offset1 count2@offset2 ...] \");\n \tfprintf(stderr, \"[hw 1|0]\\n\");\n+\tfprintf(stderr, \"                  [mode dcb|channel]\\n\");\n+\tfprintf(stderr, \"                  [shaper bw_rlimit SHAPER_PARAMS]\\n\"\n+\t\t\"Where: SHAPER_PARAMS := { min_rate MIN_RATE1 MIN_RATE2 ...|\\n\"\n+\t\t\"                          max_rate MAX_RATE1 MAX_RATE2 ... }\\n\");\n }\n \n static int mqprio_parse_opt(struct qdisc_util *qu, int argc,\n@@ -40,6 +44,12 @@ static int mqprio_parse_opt(struct qdisc_util *qu, int argc,\n \t\t.count = { },\n \t\t.offset = { },\n \t};\n+\t__u64 min_rate64[TC_QOPT_MAX_QUEUE] = {0};\n+\t__u64 max_rate64[TC_QOPT_MAX_QUEUE] = {0};\n+\t__u16 shaper = TC_MQPRIO_SHAPER_DCB;\n+\t__u16 mode = TC_MQPRIO_MODE_DCB;\n+\tstruct rtattr *tail;\n+\t__u32 flags = 0;\n \n \twhile (argc > 0) {\n \t\tidx = 0;\n@@ -92,6 +102,68 @@ static int mqprio_parse_opt(struct qdisc_util *qu, int argc,\n \t\t\t\treturn -1;\n \t\t\t}\n \t\t\tidx++;\n+\t\t} else if (opt.hw && strcmp(*argv, \"mode\") == 0) {\n+\t\t\tNEXT_ARG();\n+\t\t\tif (matches(*argv, \"dcb\") == 0) {\n+\t\t\t\tmode = TC_MQPRIO_MODE_DCB;\n+\t\t\t} else if (matches(*argv, \"channel\") == 0) {\n+\t\t\t\tmode = TC_MQPRIO_MODE_CHANNEL;\n+\t\t\t}  else {\n+\t\t\t\tfprintf(stderr, \"Illegal mode (%s)\\n\",\n+\t\t\t\t\t*argv);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tif (mode != TC_MQPRIO_MODE_DCB)\n+\t\t\t\tflags |= TC_MQPRIO_F_MODE;\n+\t\t\tidx++;\n+\t\t} else if (opt.hw && strcmp(*argv, \"shaper\") == 0) {\n+\t\t\tNEXT_ARG();\n+\t\t\tif (matches(*argv, \"dcb\") == 0) {\n+\t\t\t\tshaper = TC_MQPRIO_SHAPER_DCB;\n+\t\t\t} else if (matches(*argv, \"bw_rlimit\") == 0) {\n+\t\t\t\tshaper = TC_MQPRIO_SHAPER_BW_RATE;\n+\t\t\t\tif (!NEXT_ARG_OK()) {\n+\t\t\t\t\tfprintf(stderr, \"Incomplete shaper arguments\\n\");\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\n+\t\t\t}  else {\n+\t\t\t\tfprintf(stderr, \"Illegal shaper (%s)\\n\",\n+\t\t\t\t\t*argv);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tif (shaper != TC_MQPRIO_SHAPER_DCB)\n+\t\t\t\tflags |= TC_MQPRIO_F_SHAPER;\n+\t\t\tidx++;\n+\t\t} else if ((shaper == TC_MQPRIO_SHAPER_BW_RATE) &&\n+\t\t\t   strcmp(*argv, \"min_rate\") == 0) {\n+\t\t\twhile (idx < TC_QOPT_MAX_QUEUE && NEXT_ARG_OK()) {\n+\t\t\t\tNEXT_ARG();\n+\t\t\t\tif (get_rate64(&min_rate64[idx], *argv)) {\n+\t\t\t\t\tPREV_ARG();\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tidx++;\n+\t\t\t}\n+\t\t\tif ((idx < opt.num_tc) && !NEXT_ARG_OK()) {\n+\t\t\t\tfprintf(stderr, \"Incomplete arguments, min_rate values expected\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tflags |= TC_MQPRIO_F_MIN_RATE;\n+\t\t} else if ((shaper == TC_MQPRIO_SHAPER_BW_RATE) &&\n+\t\t\t   strcmp(*argv, \"max_rate\") == 0) {\n+\t\t\twhile (idx < TC_QOPT_MAX_QUEUE && NEXT_ARG_OK()) {\n+\t\t\t\tNEXT_ARG();\n+\t\t\t\tif (get_rate64(&max_rate64[idx], *argv)) {\n+\t\t\t\t\tPREV_ARG();\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tidx++;\n+\t\t\t}\n+\t\t\tif ((idx < opt.num_tc) && !NEXT_ARG_OK()) {\n+\t\t\t\tfprintf(stderr, \"Incomplete arguments, max_rate values expected\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tflags |= TC_MQPRIO_F_MAX_RATE;\n \t\t} else if (strcmp(*argv, \"help\") == 0) {\n \t\t\texplain();\n \t\t\treturn -1;\n@@ -102,27 +174,132 @@ static int mqprio_parse_opt(struct qdisc_util *qu, int argc,\n \t\targc--; argv++;\n \t}\n \n+\ttail = NLMSG_TAIL(n);\n \taddattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));\n+\n+\tif (flags & TC_MQPRIO_F_MODE)\n+\t\taddattr_l(n, 1024, TCA_MQPRIO_MODE,\n+\t\t\t  &mode, sizeof(mode));\n+\tif (flags & TC_MQPRIO_F_SHAPER)\n+\t\taddattr_l(n, 1024, TCA_MQPRIO_SHAPER,\n+\t\t\t  &shaper, sizeof(shaper));\n+\n+\tif (flags & TC_MQPRIO_F_MIN_RATE) {\n+\t\tstruct rtattr *start;\n+\n+\t\tstart = addattr_nest(n, 1024,\n+\t\t\t\t     TCA_MQPRIO_MIN_RATE64 | NLA_F_NESTED);\n+\n+\t\tfor (idx = 0; idx < TC_QOPT_MAX_QUEUE; idx++)\n+\t\t\taddattr_l(n, 1024, TCA_MQPRIO_MIN_RATE64,\n+\t\t\t\t  &min_rate64[idx], sizeof(min_rate64[idx]));\n+\n+\t\taddattr_nest_end(n, start);\n+\t}\n+\n+\tif (flags & TC_MQPRIO_F_MAX_RATE) {\n+\t\tstruct rtattr *start;\n+\n+\t\tstart = addattr_nest(n, 1024,\n+\t\t\t\t     TCA_MQPRIO_MAX_RATE64 | NLA_F_NESTED);\n+\n+\t\tfor (idx = 0; idx < TC_QOPT_MAX_QUEUE; idx++)\n+\t\t\taddattr_l(n, 1024, TCA_MQPRIO_MAX_RATE64,\n+\t\t\t\t  &max_rate64[idx], sizeof(max_rate64[idx]));\n+\n+\t\taddattr_nest_end(n, start);\n+\t}\n+\n+\ttail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;\n+\n \treturn 0;\n }\n \n static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)\n {\n \tint i;\n-\tstruct tc_mqprio_qopt *qopt;\n+\tstruct tc_mqprio_qopt qopt;\n+\t__u64 min_rate64[TC_QOPT_MAX_QUEUE] = {0};\n+\t__u64 max_rate64[TC_QOPT_MAX_QUEUE] = {0};\n+\tint len = RTA_PAYLOAD(opt) - RTA_ALIGN(sizeof(qopt));\n+\n+\tSPRINT_BUF(b1);\n \n \tif (opt == NULL)\n \t\treturn 0;\n \n-\tqopt = RTA_DATA(opt);\n+\tif (len < 0) {\n+\t\tfprintf(stderr, \"options size error\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tmemcpy(&qopt, RTA_DATA(opt), RTA_ALIGN(sizeof(qopt)));\n \n-\tfprintf(f, \" tc %u map \", qopt->num_tc);\n+\tfprintf(f, \" tc %u map \", qopt.num_tc);\n \tfor (i = 0; i <= TC_PRIO_MAX; i++)\n-\t\tfprintf(f, \"%u \", qopt->prio_tc_map[i]);\n+\t\tfprintf(f, \"%u \", qopt.prio_tc_map[i]);\n \tfprintf(f, \"\\n             queues:\");\n-\tfor (i = 0; i < qopt->num_tc; i++)\n-\t\tfprintf(f, \"(%u:%u) \", qopt->offset[i],\n-\t\t\tqopt->offset[i] + qopt->count[i] - 1);\n+\tfor (i = 0; i < qopt.num_tc; i++)\n+\t\tfprintf(f, \"(%u:%u) \", qopt.offset[i],\n+\t\t\tqopt.offset[i] + qopt.count[i] - 1);\n+\n+\tif (len > 0) {\n+\t\tstruct rtattr *tb[TCA_MQPRIO_MAX + 1];\n+\n+\t\tparse_rtattr(tb, TCA_MQPRIO_MAX,\n+\t\t\t     RTA_DATA(opt) + RTA_ALIGN(sizeof(qopt)),\n+\t\t\t     len);\n+\n+\t\tif (tb[TCA_MQPRIO_MODE]) {\n+\t\t\t__u16 *mode = RTA_DATA(tb[TCA_MQPRIO_MODE]);\n+\n+\t\t\tif (*mode == TC_MQPRIO_MODE_CHANNEL)\n+\t\t\t\tfprintf(f, \"\\n             mode:channel\");\n+\t\t} else {\n+\t\t\tfprintf(f, \"\\n             mode:dcb\");\n+\t\t}\n+\n+\t\tif (tb[TCA_MQPRIO_SHAPER]) {\n+\t\t\t__u16 *shaper = RTA_DATA(tb[TCA_MQPRIO_SHAPER]);\n+\n+\t\t\tif (*shaper == TC_MQPRIO_SHAPER_BW_RATE)\n+\t\t\t\tfprintf(f, \"\\n             shaper:bw_rlimit\");\n+\t\t} else {\n+\t\t\tfprintf(f, \"\\n             shaper:dcb\");\n+\t\t}\n+\n+\t\tif (tb[TCA_MQPRIO_MIN_RATE64]) {\n+\t\t\tstruct rtattr *r;\n+\t\t\tint rem = RTA_PAYLOAD(tb[TCA_MQPRIO_MIN_RATE64]);\n+\t\t\t__u64 *min = min_rate64;\n+\n+\t\t\tfor (r = RTA_DATA(tb[TCA_MQPRIO_MIN_RATE64]);\n+\t\t\t     RTA_OK(r, rem); r = RTA_NEXT(r, rem)) {\n+\t\t\t\tif (r->rta_type != TCA_MQPRIO_MIN_RATE64)\n+\t\t\t\t\treturn -1;\n+\t\t\t\t*(min++) = rta_getattr_u64(r);\n+\t\t\t}\n+\t\t\tfprintf(f, \"\tmin_rate:\");\n+\t\t\tfor (i = 0; i < qopt.num_tc; i++)\n+\t\t\t\tfprintf(f, \"%s \", sprint_rate(min_rate64[i], b1));\n+\t\t}\n+\n+\t\tif (tb[TCA_MQPRIO_MAX_RATE64]) {\n+\t\t\tstruct rtattr *r;\n+\t\t\tint rem = RTA_PAYLOAD(tb[TCA_MQPRIO_MAX_RATE64]);\n+\t\t\t__u64 *max = max_rate64;\n+\n+\t\t\tfor (r = RTA_DATA(tb[TCA_MQPRIO_MAX_RATE64]);\n+\t\t\t     RTA_OK(r, rem); r = RTA_NEXT(r, rem)) {\n+\t\t\t\tif (r->rta_type != TCA_MQPRIO_MAX_RATE64)\n+\t\t\t\t\treturn -1;\n+\t\t\t\t*(max++) = rta_getattr_u64(r);\n+\t\t\t}\n+\t\t\tfprintf(f, \"\tmax_rate:\");\n+\t\t\tfor (i = 0; i < qopt.num_tc; i++)\n+\t\t\t\tfprintf(f, \"%s \", sprint_rate(max_rate64[i], b1));\n+\t\t}\n+\t}\n \treturn 0;\n }\n \n",
    "prefixes": [
        "RFC",
        "iproute2",
        "v2"
    ]
}