get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 21811,
    "url": "http://patches.dpdk.org/api/patches/21811/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20170315180226.5999-3-bmcfall@redhat.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20170315180226.5999-3-bmcfall@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20170315180226.5999-3-bmcfall@redhat.com",
    "date": "2017-03-15T18:02:25",
    "name": "[dpdk-dev,v7,2/3] net/e1000: e1000 igb support to free consumed buffers",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0ad2298233dc8736fb760e3786b251fcbb7e3d99",
    "submitter": {
        "id": 629,
        "url": "http://patches.dpdk.org/api/people/629/?format=api",
        "name": "Billy McFall",
        "email": "bmcfall@redhat.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20170315180226.5999-3-bmcfall@redhat.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/21811/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/21811/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 1AAB11396;\n\tWed, 15 Mar 2017 19:04:10 +0100 (CET)",
            "from mx1.redhat.com (mx1.redhat.com [209.132.183.28])\n\tby dpdk.org (Postfix) with ESMTP id 1E858133F\n\tfor <dev@dpdk.org>; Wed, 15 Mar 2017 19:04:08 +0100 (CET)",
            "from int-mx13.intmail.prod.int.phx2.redhat.com\n\t(int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 6532E64D9D;\n\tWed, 15 Mar 2017 18:04:08 +0000 (UTC)",
            "from localhost.localdomain.com (ovpn-122-11.rdu2.redhat.com\n\t[10.10.122.11] (may be forged))\n\tby int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with\n\tESMTP id v2FI2TVC027652; Wed, 15 Mar 2017 14:04:06 -0400"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com 6532E64D9D",
        "Authentication-Results": [
            "ext-mx09.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com",
            "ext-mx09.extmail.prod.ext.phx2.redhat.com;\n\tspf=pass smtp.mailfrom=bmcfall@redhat.com"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 mx1.redhat.com 6532E64D9D",
        "From": "Billy McFall <bmcfall@redhat.com>",
        "To": "thomas.monjalon@6wind.com, wenzhuo.lu@intel.com, olivier.matz@6wind.com",
        "Cc": "dev@dpdk.org, Billy McFall <bmcfall@redhat.com>",
        "Date": "Wed, 15 Mar 2017 14:02:25 -0400",
        "Message-Id": "<20170315180226.5999-3-bmcfall@redhat.com>",
        "In-Reply-To": "<20170315180226.5999-1-bmcfall@redhat.com>",
        "References": "<20170309205119.28170-1-bmcfall@redhat.com>\n\t<20170315180226.5999-1-bmcfall@redhat.com>",
        "X-Scanned-By": "MIMEDefang 2.68 on 10.5.11.26",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.38]); Wed, 15 Mar 2017 18:04:08 +0000 (UTC)",
        "Subject": "[dpdk-dev] [PATCH v7 2/3] net/e1000: e1000 igb support to free\n\tconsumed buffers",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add support to the e1000 igb driver for the new API to force free\nconsumed buffers on Tx ring. This API is independent of the tx_rs_thresh\nsetting. With this API, buffers should be free even if tx_rs_thresh is\nnot met.\n\ne1000 igb driver does not implement a tx_rs_thresh to free mbufs, it\nfrees a slot in the ring as needed. However, it could be implemented at\nsome future date.\n\nSigned-off-by: Billy McFall <bmcfall@redhat.com>\nAcked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>\n---\n doc/guides/nics/features/e1000.ini |   1 +\n drivers/net/e1000/e1000_ethdev.h   |   2 +\n drivers/net/e1000/igb_ethdev.c     |   1 +\n drivers/net/e1000/igb_rxtx.c       | 126 +++++++++++++++++++++++++++++++++++++\n 4 files changed, 130 insertions(+)",
    "diff": "diff --git a/doc/guides/nics/features/e1000.ini b/doc/guides/nics/features/e1000.ini\nindex 7f6d55c..3aed7d7 100644\n--- a/doc/guides/nics/features/e1000.ini\n+++ b/doc/guides/nics/features/e1000.ini\n@@ -7,6 +7,7 @@\n Link status          = Y\n Link status event    = Y\n Rx interrupt         = Y\n+Free Tx mbuf on demand = Y\n MTU update           = Y\n Jumbo frame          = Y\n Scattered Rx         = Y\ndiff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h\nindex 81a6dbb..39b2f43 100644\n--- a/drivers/net/e1000/e1000_ethdev.h\n+++ b/drivers/net/e1000/e1000_ethdev.h\n@@ -315,6 +315,8 @@ int eth_igb_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,\n \t\tuint16_t nb_tx_desc, unsigned int socket_id,\n \t\tconst struct rte_eth_txconf *tx_conf);\n \n+int eth_igb_tx_done_cleanup(void *txq, uint32_t free_cnt);\n+\n int eth_igb_rx_init(struct rte_eth_dev *dev);\n \n void eth_igb_tx_init(struct rte_eth_dev *dev);\ndiff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c\nindex a112b38..71d05a9 100644\n--- a/drivers/net/e1000/igb_ethdev.c\n+++ b/drivers/net/e1000/igb_ethdev.c\n@@ -408,6 +408,7 @@ static const struct eth_dev_ops eth_igb_ops = {\n \t.rx_descriptor_done   = eth_igb_rx_descriptor_done,\n \t.tx_queue_setup       = eth_igb_tx_queue_setup,\n \t.tx_queue_release     = eth_igb_tx_queue_release,\n+\t.tx_done_cleanup      = eth_igb_tx_done_cleanup,\n \t.dev_led_on           = eth_igb_led_on,\n \t.dev_led_off          = eth_igb_led_off,\n \t.flow_ctrl_get        = eth_igb_flow_ctrl_get,\ndiff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c\nindex 1bb4d85..cba3704 100644\n--- a/drivers/net/e1000/igb_rxtx.c\n+++ b/drivers/net/e1000/igb_rxtx.c\n@@ -1283,6 +1283,132 @@ eth_igb_tx_queue_release(void *txq)\n \tigb_tx_queue_release(txq);\n }\n \n+static int\n+igb_tx_done_cleanup(struct igb_tx_queue *txq, uint32_t free_cnt)\n+{\n+\tstruct igb_tx_entry *sw_ring;\n+\tvolatile union e1000_adv_tx_desc *txr;\n+\tuint16_t tx_first; /* First segment analyzed. */\n+\tuint16_t tx_id;    /* Current segment being processed. */\n+\tuint16_t tx_last;  /* Last segment in the current packet. */\n+\tuint16_t tx_next;  /* First segment of the next packet. */\n+\tint count;\n+\n+\tif (txq != NULL) {\n+\t\tcount = 0;\n+\t\tsw_ring = txq->sw_ring;\n+\t\ttxr = txq->tx_ring;\n+\n+\t\t/*\n+\t\t * tx_tail is the last sent packet on the sw_ring. Goto the end\n+\t\t * of that packet (the last segment in the packet chain) and\n+\t\t * then the next segment will be the start of the oldest segment\n+\t\t * in the sw_ring. This is the first packet that will be\n+\t\t * attempted to be freed.\n+\t\t */\n+\n+\t\t/* Get last segment in most recently added packet. */\n+\t\ttx_first = sw_ring[txq->tx_tail].last_id;\n+\n+\t\t/* Get the next segment, which is the oldest segment in ring. */\n+\t\ttx_first = sw_ring[tx_first].next_id;\n+\n+\t\t/* Set the current index to the first. */\n+\t\ttx_id = tx_first;\n+\n+\t\t/*\n+\t\t * Loop through each packet. For each packet, verify that an\n+\t\t * mbuf exists and that the last segment is free. If so, free\n+\t\t * it and move on.\n+\t\t */\n+\t\twhile (1) {\n+\t\t\ttx_last = sw_ring[tx_id].last_id;\n+\n+\t\t\tif (sw_ring[tx_last].mbuf) {\n+\t\t\t\tif (txr[tx_last].wb.status &\n+\t\t\t\t\t\tE1000_TXD_STAT_DD) {\n+\t\t\t\t\t/*\n+\t\t\t\t\t * Increment the number of packets\n+\t\t\t\t\t * freed.\n+\t\t\t\t\t */\n+\t\t\t\t\tcount++;\n+\n+\t\t\t\t\t/* Get the start of the next packet. */\n+\t\t\t\t\ttx_next = sw_ring[tx_last].next_id;\n+\n+\t\t\t\t\t/*\n+\t\t\t\t\t * Loop through all segments in a\n+\t\t\t\t\t * packet.\n+\t\t\t\t\t */\n+\t\t\t\t\tdo {\n+\t\t\t\t\t\trte_pktmbuf_free_seg(sw_ring[tx_id].mbuf);\n+\t\t\t\t\t\tsw_ring[tx_id].mbuf = NULL;\n+\t\t\t\t\t\tsw_ring[tx_id].last_id = tx_id;\n+\n+\t\t\t\t\t\t/* Move to next segemnt. */\n+\t\t\t\t\t\ttx_id = sw_ring[tx_id].next_id;\n+\n+\t\t\t\t\t} while (tx_id != tx_next);\n+\n+\t\t\t\t\tif (unlikely(count == (int)free_cnt))\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t} else\n+\t\t\t\t\t/*\n+\t\t\t\t\t * mbuf still in use, nothing left to\n+\t\t\t\t\t * free.\n+\t\t\t\t\t */\n+\t\t\t\t\tbreak;\n+\t\t\t} else {\n+\t\t\t\t/*\n+\t\t\t\t * There are multiple reasons to be here:\n+\t\t\t\t * 1) All the packets on the ring have been\n+\t\t\t\t *    freed - tx_id is equal to tx_first\n+\t\t\t\t *    and some packets have been freed.\n+\t\t\t\t *    - Done, exit\n+\t\t\t\t * 2) Interfaces has not sent a rings worth of\n+\t\t\t\t *    packets yet, so the segment after tail is\n+\t\t\t\t *    still empty. Or a previous call to this\n+\t\t\t\t *    function freed some of the segments but\n+\t\t\t\t *    not all so there is a hole in the list.\n+\t\t\t\t *    Hopefully this is a rare case.\n+\t\t\t\t *    - Walk the list and find the next mbuf. If\n+\t\t\t\t *      there isn't one, then done.\n+\t\t\t\t */\n+\t\t\t\tif (likely((tx_id == tx_first) && (count != 0)))\n+\t\t\t\t\tbreak;\n+\n+\t\t\t\t/*\n+\t\t\t\t * Walk the list and find the next mbuf, if any.\n+\t\t\t\t */\n+\t\t\t\tdo {\n+\t\t\t\t\t/* Move to next segemnt. */\n+\t\t\t\t\ttx_id = sw_ring[tx_id].next_id;\n+\n+\t\t\t\t\tif (sw_ring[tx_id].mbuf)\n+\t\t\t\t\t\tbreak;\n+\n+\t\t\t\t} while (tx_id != tx_first);\n+\n+\t\t\t\t/*\n+\t\t\t\t * Determine why previous loop bailed. If there\n+\t\t\t\t * is not an mbuf, done.\n+\t\t\t\t */\n+\t\t\t\tif (sw_ring[tx_id].mbuf == NULL)\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t} else\n+\t\tcount = -ENODEV;\n+\n+\treturn count;\n+}\n+\n+int\n+eth_igb_tx_done_cleanup(void *txq, uint32_t free_cnt)\n+{\n+\treturn igb_tx_done_cleanup(txq, free_cnt);\n+}\n+\n static void\n igb_reset_tx_queue_stat(struct igb_tx_queue *txq)\n {\n",
    "prefixes": [
        "dpdk-dev",
        "v7",
        "2/3"
    ]
}