Show a patch.

GET /api/patches/347/
Content-Type: application/json
Vary: Accept

    "id": 347,
    "url": "",
    "web_url": "",
    "project": {
        "id": 1,
        "url": "",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "",
        "list_email": "",
        "web_url": "",
        "scm_url": "git://",
        "webscm_url": ""
    "msgid": "<>",
    "date": "2014-09-11T13:15:44",
    "name": "[dpdk-dev,v2,10/13] mbuf: split mbuf across two cache lines.",
    "commit_ref": "",
    "pull_url": "",
    "state": "accepted",
    "archived": true,
    "hash": "d0059e2e6bf0d4a41cf90bf793479a7e5cc94906",
    "submitter": {
        "id": 20,
        "url": "",
        "name": "Bruce Richardson",
        "email": ""
    "delegate": null,
    "mbox": "",
    "series": [],
    "comments": "",
    "check": "pending",
    "checks": "",
    "tags": {},
    "headers": {
        "Return-Path": "<>",
        "References": "<>\r\n\t<>",
        "X-Mailman-Version": "2.1.15",
        "X-IronPort-AV": "E=Sophos;i=\"5.04,505,1406617200\"; d=\"scan'208\";a=\"601443242\"",
        "Date": "Thu, 11 Sep 2014 14:15:44 +0100",
        "List-Help": "<>",
        "X-BeenThere": "",
        "Message-Id": "<>",
        "X-Original-To": "",
        "Received": [
            "from [] (localhost [IPv6:::1])\r\n\tby (Postfix) with ESMTP id 39460B3AC;\r\n\tThu, 11 Sep 2014 15:11:31 +0200 (CEST)",
            "from ( [])\r\n\tby (Postfix) with ESMTP id 181DF68A7\r\n\tfor <>; Thu, 11 Sep 2014 15:11:22 +0200 (CEST)",
            "from ([])\r\n\tby with ESMTP; 11 Sep 2014 06:09:45 -0700",
            "from ([])\r\n\tby with ESMTP; 11 Sep 2014 06:15:51 -0700",
            "from (\r\n\t[])\r\n\tby (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\r\n\ts8BDFnBG002155; Thu, 11 Sep 2014 14:15:49 +0100",
            "from (localhost [])\r\n\tby with ESMTP id s8BDFnM0023675;\r\n\tThu, 11 Sep 2014 14:15:49 +0100",
            "(from bricha3@localhost)\r\n\tby with  id s8BDFnAe023671;\r\n\tThu, 11 Sep 2014 14:15:49 +0100"
        "List-Post": "<>",
        "Subject": "[dpdk-dev] [PATCH v2 10/13] mbuf: split mbuf across two cache lines.",
        "Sender": "\"dev\" <>",
        "X-Mailer": "git-send-email",
        "Precedence": "list",
        "From": "Bruce Richardson <>",
        "List-Archive": "<>",
        "X-ExtLoop1": "1",
        "List-Subscribe": "<>,\r\n\t<>",
        "List-Id": "patches and discussions about DPDK <>",
        "Delivered-To": "",
        "In-Reply-To": "<>",
        "List-Unsubscribe": "<>,\r\n\t<>",
        "To": "",
        "Errors-To": ""
    "content": "This change splits the mbuf in two to move the pool and next pointers to\nthe second cache line. This frees up 16 bytes in first cache line.\n\nThe reason for this change is that we believe that there is no possible\nway that we can ever fit all the fields we need to fit into a 64-byte\nmbuf, and so we need to start looking at a 128-byte mbuf instead. Examples\nof new fields that need to fit in, include -\n* 32-bits more for filter information for support for the new filters in\n  the i40e driver (and possibly other future drivers)\n* an additional 2-4 bytes for storing info on a second vlan tag to allow\n  drivers to support double Vlan/QinQ\n* 4-bytes for storing a sequence number to enable out of order packet\n  processing and subsequent packet reordering\nas well as potentially a number of other fields or splitting out fields\nthat are superimposed over each other right now, e.g. for the qos scheduler.\nWe also want to allow space for use by other non-Intel NIC drivers that may\nbe open-sourced to in the future too, where they support fields\nand offloads that currently supported hardware doesn't.\n\nIf we accept the fact of a 2-cache-line mbuf, then the issue becomes\nhow to rework things so that we spread our fields over the two\ncache lines while causing the lowest slow-down possible. The general\napproach that we are looking to take is to focus the first cache\nline on fields that are updated on RX , so that receive only deals\nwith one cache line. The second cache line can be used for application\ndata and information that will only be used on the TX leg. This would\nallow us to work on the first cache line in RX as now, and have the\nsecond cache line being prefetched in the background so that it is\navailable when necessary. Hardware prefetches should help us out\nhere. We also may move rarely used, or slow-path RX fields e.g. such\nas those for chained mbufs with jumbo frames, to the second\ncache line, depending upon the performance impact and bytes savings\nachieved.\n\nUpdated in V2:\n* Expanded commit description to include contents of a previous mail\n  describing some of the logic behind expanding mbuf to two cache lines\n* Update kni mbuf structure\n\nSigned-off-by: Bruce Richardson <>\n---\n app/test/test_mbuf.c                                          | 2 +-\n lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h | 6 +++---\n lib/librte_mbuf/rte_mbuf.h                                    | 3 ++-\n 3 files changed, 6 insertions(+), 5 deletions(-)",
    "diff": "diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c\r\nindex 1b25481..66bcbc5 100644\r\n--- a/app/test/test_mbuf.c\r\n+++ b/app/test/test_mbuf.c\r\n@@ -782,7 +782,7 @@ test_failing_mbuf_sanity_check(void)\r\n static int\r\n test_mbuf(void)\r\n {\r\n-\tRTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != 64);\r\n+\tRTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != CACHE_LINE_SIZE * 2);\r\n \r\n \t/* create pktmbuf pool if it does not exist */\r\n \tif (pktmbuf_pool == NULL) {\r\ndiff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h\r\nindex ab022bd..25ed672 100644\r\n--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h\r\n+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h\r\n@@ -108,7 +108,7 @@ struct rte_kni_fifo {\r\n  * Padding is necessary to assure the offsets of these fields\r\n  */\r\n struct rte_kni_mbuf {\r\n-\tvoid *buf_addr;\r\n+\tvoid *buf_addr __attribute__((__aligned__(64)));\r\n \tchar pad0[10];\r\n \tuint16_t data_off;      /**< Start address of data in segment buffer. */\r\n \tchar pad1[4];\r\n@@ -117,9 +117,9 @@ struct rte_kni_mbuf {\r\n \tuint16_t data_len;      /**< Amount of data in segment buffer. */\r\n \tuint32_t pkt_len;       /**< Total pkt len: sum of all segment data_len. */\r\n \tchar pad3[8];\r\n-\tvoid *pool;\r\n+\tvoid *pool __attribute__((__aligned__(64)));\r\n \tvoid *next;\r\n-} __attribute__((__aligned__(64)));\r\n+};\r\n \r\n /*\r\n  * Struct used to create a KNI device. Passed to the kernel in IOCTL call\r\ndiff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h\r\nindex 34900d4..508021b 100644\r\n--- a/lib/librte_mbuf/rte_mbuf.h\r\n+++ b/lib/librte_mbuf/rte_mbuf.h\r\n@@ -176,7 +176,8 @@ struct rte_mbuf {\r\n \t\tuint32_t sched;   /**< Hierarchical scheduler */\r\n \t} hash;                   /**< hash information */\r\n \r\n-\t/* fields only used in slow path or on TX */\r\n+\t/* second cache line - fields only used in slow path or on TX */\r\n+\tMARKER cacheline1 __rte_cache_aligned;\r\n \tstruct rte_mempool *pool; /**< Pool from which mbuf was allocated. */\r\n \tstruct rte_mbuf *next;    /**< Next segment of scattered packet. */\r\n \r\n",
    "prefixes": [