From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on0061.outbound.protection.outlook.com [104.47.1.61]) by dpdk.org (Postfix) with ESMTP id 1B2EE1B1B9 for ; Mon, 2 Apr 2018 20:50:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=RrInTk2xAEYNbbiobq+rgbkdsp6CkbEuzNe9RGWd1Y0=; b=dt9DeH8ltl6t0crv6YWC5tBqRACawC+yTXsxcf3RgguMCnOcgCXE59ijQBc2qrOBbanr38QQpGLkpxC2iqzX81e/p9nU+D4Oi54+UaUuTnzjrjbnmZ8ICzkD4aflW3pbmZO4JQkm0+8swKtCKgXc4djbmcwHdmvYDF2sBqX20PQ= Received: from mellanox.com (209.116.155.178) by AM5PR0501MB2036.eurprd05.prod.outlook.com (2603:10a6:203:1a::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.631.10; Mon, 2 Apr 2018 18:50:28 +0000 From: Yongseok Koh To: wenzhuo.lu@intel.com, jingjing.wu@intel.com, adrien.mazarguil@6wind.com, nelio.laranjeiro@6wind.com, olivier.matz@6wind.com Cc: dev@dpdk.org, Yongseok Koh Date: Mon, 2 Apr 2018 11:50:03 -0700 Message-Id: <20180402185008.13073-2-yskoh@mellanox.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180402185008.13073-1-yskoh@mellanox.com> References: <20180310012532.15809-1-yskoh@mellanox.com> <20180402185008.13073-1-yskoh@mellanox.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [209.116.155.178] X-ClientProxiedBy: DM3PR12CA0064.namprd12.prod.outlook.com (2603:10b6:0:56::32) To AM5PR0501MB2036.eurprd05.prod.outlook.com (2603:10a6:203:1a::22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 4e37fc69-c74a-4bbb-a877-08d598ca9b6a X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM5PR0501MB2036; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0501MB2036; 3:SAjlbuvvhuZ8tSKnDwF5AWTrghyLouNAxU12ZpC9H7Uvjx5aH1HJ6yCeBjx4iIDzJJ7qpwVuEasrq26awpIdBCXiKpcQtk6Pn+K7sHLzsFBpufvviyUoesuwhmchoiTXsaGQSJBgndSfEp63o8Tc+02EuKEEE0AFu9KJzFI4dDrUoERRnKC8AU4wgzqzYPK6afk542WO6yvYOwbSqu/CauxiryyO5s27I6ePh0gFQucwPIP4U9Fhshk5kwRMIWKW; 25:plN5hJX9o6qdn8AYKqVDbE9i1NA+SRdHQe/AsFg1SLGBs9p14OTLOUb46MIFd0zvjn7JFnoiwqVlnXNc/AfljctUt/1tFBL4wgFWnNrerJDKlqL9594P7gceouh/+3s/KhFbPrE5l1+Fgey063lDIaB8sYvwuNg2dxr9zRyclRz96efVSgNhl3aYd9lK5IZ1NquD7v/4afL+Z4JLaTk53OL0d9p2xL4V/vjcEWwAMw64YoRCyRJtukZlDvYIWx5LBNpEbpNcK1jMtq6aSmgIu+X45mM9vdzvwq+vHaKoX3N3z3zs71EiYtxphPya+ySCk5TEX4QMo0+bixWeV4BgHQ==; 31:MBxvD/+dmCInSJsWP98NO/6HTERap+EezafB6qCwUXyGZlZIJNa4JTjHH30NEjpQMEiEf3RoXRvhgycPnHDfpcegawbOrFV9GGEhQXLscywRv53Nd++hbqlLf7ypyvxRRW5+LqTNPow4zfyHYVrM4llUEtU9H1osmk1M2ywjt0xlVMpy2Tp1+SoMlJPFwxKqZFcakwaZsXyPBvMAiz+EBHo3Uy0p5xeiUhM7IIpkeNE= X-MS-TrafficTypeDiagnostic: AM5PR0501MB2036: X-LD-Processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr X-Microsoft-Exchange-Diagnostics: 1; AM5PR0501MB2036; 20:euBx5NL5HOG6SOkE4MRg9OpRjPXsy0bIfFyHIbdaJINhryGLA0sTeFjdjvlU8i79fXwq8V6rNa7nEnRw9+GGKnTHBcMWcOURfxI862hJkTJEbh++vLqDZJFXNxfSpktfO11JXT/7OSaUMG66KGAw4otN0sL13Y6g4KsNbWel2hmHA0oIv9PY27k5H4N4oPWGAcrZ9KqpDdOUGzl5WRB2iRLyb/lbqoU0bm39KjIRF5K79VIAhD9enVRb4e5yO4eKctYSr8XUKzp0rw/cCTFX9FQjF4H7xQcwLMj8el59sw79uh2EOtO3KkRE8Sis3xPYPKD5amiXNfLrY+uEqU9vONlxO1b7eHsfsVmgCVp/rcFIFWS2N1xd3hSlCafGRQwyTdntZyJhwfwV2AtrrqCXFd2oOYqh3dYu8ofimMbrv9FydJiBI1RnRE0j97/Xb/zPzn5Fueo8Hj85k9QFpqr7t624lrapume2wZQJIScyFCiT61ePbbcYp7R45oqhhrfV; 4:urW/1Z/jWFZiscAJo1Dcn2o15XyeWdO8Q//zfLyiu3Si2PyifZAWaINH5taSwdZ/tb4y41EFZMfPpNpKTjfbdRuz42X04y6lQnLPugDgMgO9u6U2ESwZIkmV9ISgCajMe8fqjKFfGWh7P6bBfYYfpuI4GR4nld8QtJLyQYRNu+ywpslMV9VQ9WBm5Wtsvb62Q4cKqpdzZNZiEoVGx3AYG5/I9z4PblMk07erQoI0rFNHh3hyd9eL4rUAlt4a54lksdPsGFD0/RDEiU7nVs46XQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93001095)(3231221)(944501327)(52105095)(3002001)(6055026)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123560045)(20161123558120)(6072148)(201708071742011); SRVR:AM5PR0501MB2036; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0501MB2036; X-Forefront-PRVS: 0630013541 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(39380400002)(39860400002)(366004)(396003)(346002)(376002)(189003)(199004)(25786009)(106356001)(7696005)(81166006)(956004)(5660300001)(76176011)(16526019)(26005)(8936002)(186003)(51416003)(478600001)(47776003)(69596002)(66066001)(50466002)(105586002)(476003)(5890100001)(316002)(486005)(446003)(6346003)(21086003)(81156014)(52116002)(8676002)(16586007)(86362001)(2616005)(50226002)(68736007)(386003)(59450400001)(11346002)(486005)(107886003)(3846002)(1076002)(2906002)(6116002)(55016002)(36756003)(7736002)(53936002)(4326008)(48376002)(97736004)(305945005)(6666003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0501MB2036; H:mellanox.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=yskoh@mellanox.com; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0501MB2036; 23:RSiTHGie9axVApB3JKUcD6RRubugYCHIJlFGXjZ?= =?us-ascii?Q?dgmdbi8AX8H4sBRI3/UhPtGJyzfYpqBgA31XH08wPDY+kSw+BJ8Aagqhe88x?= =?us-ascii?Q?1D/TJNkTJWqs4WeJLVmkMdVp4mUeCD9yPdFAW/tjEs4bdDIP4hLTEM7Oztym?= =?us-ascii?Q?CvWcRMmkJN32iv2Qbbbr+IHGR1vrtneG+z7SHi2XaJEetckLEXV4hLRBAtWy?= =?us-ascii?Q?2NgP2RtvVng1u44CwWyhe5tImhxsy8d4LvT4rllCUZ1spzHddP2AVaucOZZX?= =?us-ascii?Q?wzOh8yXENuNQMGb6LOuJ32uqbsN+daOXRg6topZZLfg6YOwJFgcHz2lNoamU?= =?us-ascii?Q?wldCOTrLFer1DCI7hxZv6lQ1lw4SO9RJ99rWfAH6g3wH1bxgYCiWy3egn8ur?= =?us-ascii?Q?lyatMFEg9Oe7i5K3mlBU82HN840wLIZgWuin0woFwrB8sPUV6IGmBgilXtGV?= =?us-ascii?Q?PT4Jj0fFwkvNHoEeqLTPVZJLmKDhHXJviPsptKs4dgSu/h6mrXRnR2HM0s71?= =?us-ascii?Q?yOl4sq721TU1vcIfEGWLqH8cJs32Tr7t6tJNmJfwLzo+F4cUSZntOh/Jd7Fr?= =?us-ascii?Q?TU/JlInOVR/iZwffoWeaSLHuFT00YSBS79hvTQPb28ATp6re0fIs8jXg2Nci?= =?us-ascii?Q?tVNlxdEGg69c6Ii4n8skMDjxrisEJa0dZevT/3Vg7akjAIBuS9Iprr5lQOTS?= =?us-ascii?Q?67hF7A6Qn2ywtBq22AVmvE9cJSYVsR7JmGhpFe2M7ENRcreyLpHoQxhzSzxd?= =?us-ascii?Q?ZRelRLhEm6QRR5TK/b+MviH+cxxaQKAfDSjWgdSDX8KjVhcPQB3MMstjRgLc?= =?us-ascii?Q?+ZT9wz6F2D+/k+S5gIL50exjNlD8zTqg2Ti3NjeeyXn2bEqdA+mCLlXDI5St?= =?us-ascii?Q?cpTsg7ZT1ILXZZtBoW7P/ZZ1xrlLjdqr+rxSI+ERnud1ZBIrPp/10MQ8RcDj?= =?us-ascii?Q?2XGKcup2WPcmSHUJ2Hf/EW6wjt0svSxOwLyqpQ98WnpRetnh8URsqges31CM?= =?us-ascii?Q?Fm8lhT2h27zUrkKY/cqJeTDXfanjPc1Cy+MXHtl6xpHeJvhrVQiuEYXl2MiZ?= =?us-ascii?Q?xiqHaO5fenYzzLiJ+59S1Sc/L12jx1voWIPQt31f5KcnRmyvdyeADe4mj9Ha?= =?us-ascii?Q?Ll7UOWwiI2XzHXbIIvf4kKs+eaayFsa97Mrursw2oItkEU1gHcOCQ5uv7NDY?= =?us-ascii?Q?YnhmUNW/mHEkawhQNkR1Ut7/+sYR/BaCohQdkeWiuQHCaAc8mF18bZRBq6oi?= =?us-ascii?Q?xagRfbvQnExUMGPSM27H1jqOnX/ACLTvPiKWm7VDU0lm+FnG89yxLHaG0g2r?= =?us-ascii?Q?ygvx72koxEPMP5yLlROSlSlY=3D?= X-Microsoft-Antispam-Message-Info: JptJB5TMUmapBy5jGnlLIIozCOfcef+e2s8RzOUnAvFPUchJoERnA+Q8h1Hg8q3NiFLBSgA3ej0/vI+EriXH3LNS7I4GtOd7xWsdy8l8ZwG1bZjwjk0aPKjLEGw1QPnZansGdAoyVFBZeczT4QN/q2tPKMRmY5mq8bTrArCnP5e/xfkYFA4spuibq+PILMi5 X-Microsoft-Exchange-Diagnostics: 1; AM5PR0501MB2036; 6:ehNSR5cJaWaLhCqcYjqNF3hiDYUrXD4o6VsoMzZKPvxNNPndzClHrO0lyebFOUOVnbnubMx+xa/Jvu2baDTxK36F6JWg+pdAwFVjNJE0c8V/SuFhi/Uy14Qzfkc2zbWS0bOqheQ0Y2t8KCEbzXSPvEAluK5pCfcozwW630G1KgmUCu8AuoNhABNq8qFmjYzXDJr/tCvFjQS5avsW5v7Thos7Y0ua/mNADMkSQB98gs7dCxs7BE8k/iRlWX17tlziOS63MVErUyASgFbayjCdOeRPpT0WCAbK5Tosan+EG2f5JKdn9RNJAGtm4vn70UWX/HlpZTJLVFb8tVHZd6nBgA7pHqN2xFJmeV7xiR+mYRU9SRUxlW/13UAks+YehFMxLyq6qY0srYArQaqNYEGuJfX12C06XbB6nwqX50MTujVRxIvIgUrQyOyH2CjEyaVWwIu9WMM6KxB8Y7Ypwdg3nw==; 5:jtnxF8NVwPCWUv0us4E7tqSjwxTK71gS3qx7qTIo9L8S+vU6azJRpdIPVrZdfSzMHle2dN9r5MVPagi+Q4vO3UHqRwrYwyz4FEbjm/DVNCirWkV1Na/r1RH0zTgS6xoXIaVpXC9Vd677aUlSbwYUwsBsB744BVDUxXOAyY2TMkU=; 24:WBhS3doqsouB3CXkA+/C/Ul2KeDHRJDBYUYGnYGbBlks/yYvTNeV+WEf9HafVe7qL+bmf+p7e8ocum6znvxlDqpLJD0BlVtwNO5/xRiLRjE= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0501MB2036; 7:BweYt6ij3qAowP/E7TpsgdB5W7+ED1JtvYPES1ZItwNTtfXQm6Rt+zu7hFtkUBFK4keTuAWlMhyFqoR0jM4jyvsui61W01SrJYhgMevPIKXj+vAQPNduJsC6fD5H3CvB6ktBICSgnwtLKaTq7r87+eBcBC5lPkEJv7dzytEDmlY1TbYCrT9a+C1yyGYasSofhFD9Oc8ag7+BWBIJvwLEkQIxzvnLLyfRHFW55oP1GzF2NBw5cRH4stj48CP+G2Bx X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Apr 2018 18:50:28.6405 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4e37fc69-c74a-4bbb-a877-08d598ca9b6a X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0501MB2036 Subject: [dpdk-dev] [PATCH v2 1/6] mbuf: add buffer offset field for flexible indirection X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Apr 2018 18:50:31 -0000 When attaching a mbuf, indirect mbuf has to point to start of buffer of direct mbuf. By adding buf_off field to rte_mbuf, this becomes more flexible. Indirect mbuf can point to any part of direct mbuf by calling rte_pktmbuf_attach_at(). Possible use-cases could be: - If a packet has multiple layers of encapsulation, multiple indirect buffers can reference different layers of the encapsulated packet. - A large direct mbuf can even contain multiple packets in series and each packet can be referenced by multiple mbuf indirections. Signed-off-by: Yongseok Koh --- lib/librte_mbuf/rte_mbuf.h | 158 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 62740254d..053db32d0 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -559,6 +559,11 @@ struct rte_mbuf { }; }; + /** Buffer offset of direct mbuf if attached. Indirect mbuf can point to + * any part of direct mbuf. + */ + uint16_t buf_off; + /** Size of the application private data. In case of an indirect * mbuf, it stores the direct mbuf private data size. */ uint16_t priv_size; @@ -671,7 +676,9 @@ rte_mbuf_data_dma_addr_default(const struct rte_mbuf *mb) static inline struct rte_mbuf * rte_mbuf_from_indirect(struct rte_mbuf *mi) { - return (struct rte_mbuf *)RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size); + return (struct rte_mbuf *) + RTE_PTR_SUB(mi->buf_addr, + sizeof(*mi) + mi->priv_size + mi->buf_off); } /** @@ -1281,6 +1288,98 @@ static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool, } /** + * Adjust tailroom of indirect mbuf. If offset is positive, enlarge the + * tailroom of the mbuf. If negative, shrink the tailroom. + * + * If length is out of range, then the function will fail and return -1, + * without modifying the indirect mbuf. + * + * @param mi + * The indirect packet mbuf. + * @param len + * The amount of length to adjust (in bytes). + * @return + * - 0: On success. + * - -1: On error. + */ +static inline int rte_pktmbuf_adj_indirect_tail(struct rte_mbuf *mi, int len) +{ + struct rte_mbuf *md; + uint16_t tailroom; + int delta; + + RTE_ASSERT(RTE_MBUF_INDIRECT(mi)); + + md = rte_mbuf_from_indirect(mi); + if (unlikely(mi->buf_len + len <= 0 || + mi->buf_off + mi->buf_len + len >= md->buf_len)) + return -1; + + mi->buf_len += len; + + tailroom = mi->buf_len - mi->data_off - mi->data_len; + delta = tailroom + len; + if (delta > 0) { + /* Adjust tailroom */ + delta = 0; + } else if (delta + mi->data_len < 0) { + /* No data */ + mi->data_off += delta + mi->data_len; + delta = mi->data_len; + } + mi->data_len += delta; + mi->pkt_len += delta; + return 0; +} + +/** + * Shift buffer reference of indirect mbuf. If offset is positive, push + * the offset of the mbuf. If negative, pull the offset. + * + * Returns a pointer to the start address of the new data area. If offset + * is out of range, then the function will fail and return NULL, without + * modifying the indirect mbuf. + * + * @param mi + * The indirect packet mbuf. + * @param off + * The amount of offset to adjust (in bytes). + * @return + * A pointer to the new start of the data. + */ +static inline char *rte_pktmbuf_adj_indirect_head(struct rte_mbuf *mi, int off) +{ + int delta; + + RTE_ASSERT(RTE_MBUF_INDIRECT(mi)); + + if (unlikely(off >= mi->buf_len || mi->buf_off + off < 0)) + return NULL; + + mi->buf_iova += off; + mi->buf_addr = (char *)mi->buf_addr + off; + mi->buf_len -= off; + mi->buf_off += off; + + delta = off - mi->data_off; + if (delta < 0) { + /* Adjust headroom */ + mi->data_off -= off; + delta = 0; + } else if (delta < mi->data_len) { + /* No headroom */ + mi->data_off = 0; + } else { + /* No data */ + mi->data_off = 0; + delta = mi->data_len; + } + mi->data_len -= delta; + mi->pkt_len -= delta; + return (char *)mi->buf_addr + mi->data_off; +} + +/** * Attach packet mbuf to another packet mbuf. * * After attachment we refer the mbuf we attached as 'indirect', @@ -1315,6 +1414,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m) mi->buf_iova = m->buf_iova; mi->buf_addr = m->buf_addr; mi->buf_len = m->buf_len; + mi->buf_off = 0; mi->data_off = m->data_off; mi->data_len = m->data_len; @@ -1336,6 +1436,62 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m) } /** + * Attach packet mbuf to another packet mbuf pointing by given offset. + * + * After attachment we refer the mbuf we attached as 'indirect', + * while mbuf we attached to as 'direct'. + * + * The indirect mbuf can reference to anywhere in the buffer of the direct + * mbuf by the given offset. And the indirect mbuf is also be trimmed by + * the given buffer length. + * + * As a result, if a direct mbuf has multiple layers of encapsulation, + * multiple indirect buffers can reference different layers of the packet. + * Or, a large direct mbuf can even contain multiple packets in series and + * each packet can be referenced by multiple mbuf indirections. + * + * Returns a pointer to the start address of the new data area. If offset + * or buffer length is out of range, then the function will fail and return + * NULL, without attaching the mbuf. + * + * @param mi + * The indirect packet mbuf. + * @param m + * The packet mbuf we're attaching to. + * @param off + * The amount of offset to push (in bytes). + * @param buf_len + * The buffer length of the indirect mbuf (in bytes). + * @return + * A pointer to the new start of the data. + */ +static inline char *rte_pktmbuf_attach_at(struct rte_mbuf *mi, + struct rte_mbuf *m, uint16_t off, uint16_t buf_len) +{ + struct rte_mbuf *md; + char *ret; + + if (RTE_MBUF_DIRECT(m)) + md = m; + else + md = rte_mbuf_from_indirect(m); + + if (off + buf_len > md->buf_len) + return NULL; + + rte_pktmbuf_attach(mi, m); + + /* Push reference of indirect mbuf */ + ret = rte_pktmbuf_adj_indirect_head(mi, off); + RTE_ASSERT(ret != NULL); + + /* Trim reference of indirect mbuf */ + rte_pktmbuf_adj_indirect_tail(mi, off + buf_len - md->buf_len); + + return ret; +} + +/** * Detach an indirect packet mbuf. * * - restore original mbuf address and length values. -- 2.11.0