[dpdk-dev,v3,1/5] gso: add Generic Segmentation Offload API framework

Message ID 1505184211-36728-2-git-send-email-jiayu.hu@intel.com
State Superseded, archived
Headers show

Checks

Context Check Description
checkpatch success coding style OK
Intel-compilation success Compilation OK

Commit Message

Jiayu Hu Sept. 12, 2017, 2:43 a.m.
Generic Segmentation Offload (GSO) is a SW technique to split large
packets into small ones. Akin to TSO, GSO enables applications to
operate on large packets, thus reducing per-packet processing overhead.

To enable more flexibility to applications, DPDK GSO is implemented
as a standalone library. Applications explicitly use the GSO library
to segment packets. This patch introduces the GSO API framework to DPDK.

The GSO library provides a segmentation API, rte_gso_segment(), for
applications. It splits an input packet into small ones in each
invocation. The GSO library refers to these small packets generated
by rte_gso_segment() as GSO segments. Each of the newly-created GSO
segments is organized as a two-segment MBUF, where the first segment is a
standard MBUF, which stores a copy of packet header, and the second is an
indirect MBUF which points to a section of data in the input packet.
rte_gso_segment() reduces the refcnt of the input packet by 1. Therefore,
when all GSO segments are freed, the input packet is freed automatically.
Additionally, since each GSO segment has multiple MBUFs (i.e. 2 MBUFs),
the driver of the interface which the GSO segments are sent to should
support to transmit multi-segment packets.

Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
---
 config/common_base                 |   5 ++
 lib/Makefile                       |   2 +
 lib/librte_gso/Makefile            |  49 ++++++++++++++
 lib/librte_gso/rte_gso.c           |  50 ++++++++++++++
 lib/librte_gso/rte_gso.h           | 133 +++++++++++++++++++++++++++++++++++++
 lib/librte_gso/rte_gso_version.map |   7 ++
 mk/rte.app.mk                      |   1 +
 7 files changed, 247 insertions(+)
 create mode 100644 lib/librte_gso/Makefile
 create mode 100644 lib/librte_gso/rte_gso.c
 create mode 100644 lib/librte_gso/rte_gso.h
 create mode 100644 lib/librte_gso/rte_gso_version.map

Comments

Ananyev, Konstantin Sept. 12, 2017, 10:36 a.m.
Hi Jiayu,
Few comments from be inline.
Konstantin

> diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c
> new file mode 100644
> index 0000000..dda50ee
> --- /dev/null
> +++ b/lib/librte_gso/rte_gso.c
> @@ -0,0 +1,50 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <errno.h>
> +
> +#include "rte_gso.h"
> +
> +int
> +rte_gso_segment(struct rte_mbuf *pkt,
> +		struct rte_gso_ctx gso_ctx __rte_unused,

No need to pass parameter by value here.
struct rte_gso_ctx *gso_ctx would do.
Even better - const struct rte_gso_ctx *, in case it doesn't need to need
to be updated inside that function.  

> +		struct rte_mbuf **pkts_out,
> +		uint16_t nb_pkts_out)
> +{
> +	if (pkt == NULL || pkts_out == NULL || nb_pkts_out < 1)
> +		return -EINVAL;
> +
> +	pkts_out[0] = pkt;
> +
> +	return 1;
> +}
> diff --git a/lib/librte_gso/rte_gso.h b/lib/librte_gso/rte_gso.h
> new file mode 100644
> index 0000000..db757d6
> --- /dev/null
> +++ b/lib/librte_gso/rte_gso.h
> @@ -0,0 +1,133 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _RTE_GSO_H_
> +#define _RTE_GSO_H_
> +
> +/**
> + * @file
> + * Interface to GSO library
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdint.h>
> +#include <rte_mbuf.h>
> +
> +/* GSO IP id flags for the IPv4 header */
> +#define RTE_GSO_IPID_FIXED (1 << 0)
> +/**< Use fixed IP ids for output GSO segments */
> +#define RTE_GSO_IPID_INCREASE (1 << 1)
> +/**< Use incremental IP ids for output GSO segments */

As values above are mutually exclusive, I think you don't need both flags.
Just one seems enough.


> +
> +/**
> + * GSO context structure.
> + */
> +struct rte_gso_ctx {
> +	struct rte_mempool *direct_pool;
> +	/**< MBUF pool for allocating direct buffers, which are used
> +	 * to store packet headers for GSO segments.
> +	 */
> +	struct rte_mempool *indirect_pool;
> +	/**< MBUF pool for allocating indirect buffers, which are used
> +	 * to locate packet payloads for GSO segments. The indirect
> +	 * buffer doesn't contain any data, but simply points to an
> +	 * offset within the packet to segment.
> +	 */
> +	uint32_t gso_types;
> +	/**< packet types to perform GSO. For example, if applications
> +	 * want to segment TCP/IPv4 packets, may set (RTE_PTYPE_L2_ETHER |
> +	 * RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP) to gso_types.


Actually after another thought - it probably should be no ptype mask, but mask
of rte_ethdev DEV_TX_OFFLOAD_*_TSO flags that are used to advertise real HW TSO offloads.
Let say for GSO that supports TSO over IPv4 it would be:
PKT_TX_TCP_SEG | PKT_TX_IPV4.
That would allow user to use GSO and TSO in a transparent way,
plus ptype is not actually a proper bitmask, but a set of enums,
so it not always possible to distinguish what ptype is supported just by bitmask.
Sorry for causing confusion here.

> +	 */
> +	uint16_t gso_size;
> +	/**< maximum size of an output GSO segment, including packet
> +	 * header and payload, measured in bytes.
> +	 */
> +	uint8_t ipid_flag;

I'd suggest uint32_t flags (or even uint64_t).
Who knows what extra flags we'll need in future here.

> +	/**< flag to indicate GSO uses fixed or incremental IP ids for
> +	 * IPv4 headers of output GSO segments.
> +	 */
> +};
> +
> +/**
> + * Segmentation function, which supports processing of both single- and
> + * multi- segment packets.
> + *
> + * Note that we refer to the packets that are segmented from the input
> + * packet as 'GSO segments'. rte_gso_segment() assumes the input packet
> + * has correct checksums, and it doesn't update checksums for output
> + * GSO segments. Additionally, it doesn't process IP fragment packets.
> + *
> + * Each of the newly-created GSO segments is organized as a two-segment
> + * MBUF, where the first segment is a standard MBUF, which stores a copy
> + * of packet header, and the second is an indirect MBUF which points to
> + * a section of data in the input packet. Since each GSO segment has
> + * multiple MBUFs (i.e. 2 MBUFs), the driver of the interface which the
> + * GSO segments are sent to should support to transmit multi-segment
> + * packets.
> + *
> + * If the input packet is GSOed, its mbuf refcnt reduces by 1. Therefore,
> + * when all GSO segments are freed, the input packet is freed automatically.
> + *
> + * If the memory space in pkts_out or MBUF pools is insufficient, this
> + * function fails, and it returns (-1) * errno. Otherwise, GSO successes,
> + * and this function returns the number of output GSO segments filled in
> + * pkts_out.
> + *
> + * @param pkt
> + *  The packet mbuf to segment.
> + * @param ctx
> + *  GSO context object.
> + * @param pkts_out
> + *  Pointer array used to store the MBUF addresses of output GSO
> + *  segments, when rte_gso_segment() successes.
> + * @param nb_pkts_out
> + *  The max number of items that pkts_out can keep.
> + *
> + * @return
> + *  - The number of GSO segments filled in pkts_out on success.
> + *  - Return -ENOMEM if run out of memory in MBUF pools.
> + *  - Return -EINVAL for invalid parameters.
> + */
> +int rte_gso_segment(struct rte_mbuf *pkt,
> +		struct rte_gso_ctx ctx,
> +		struct rte_mbuf **pkts_out,
> +		uint16_t nb_pkts_out);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_GSO_H_ */
Jiayu Hu Sept. 13, 2017, 2:11 a.m.
Hi Konstantin,

Thanks for your quick feedbacks. Replies are inline.

Thanks,
Jiayu

On Tue, Sep 12, 2017 at 06:36:41PM +0800, Ananyev, Konstantin wrote:
> Hi Jiayu,
> Few comments from be inline.
> Konstantin
> 
> > diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c
> > new file mode 100644
> > index 0000000..dda50ee
> > --- /dev/null
> > +++ b/lib/librte_gso/rte_gso.c
> > @@ -0,0 +1,50 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> > + *   All rights reserved.
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of Intel Corporation nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *
> > + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#include <errno.h>
> > +
> > +#include "rte_gso.h"
> > +
> > +int
> > +rte_gso_segment(struct rte_mbuf *pkt,
> > +		struct rte_gso_ctx gso_ctx __rte_unused,
> 
> No need to pass parameter by value here.
> struct rte_gso_ctx *gso_ctx would do.
> Even better - const struct rte_gso_ctx *, in case it doesn't need to need
> to be updated inside that function.  

Yes, agree. I will use rte_gso_ctx *gso_ctx instead.

> 
> > +		struct rte_mbuf **pkts_out,
> > +		uint16_t nb_pkts_out)
> > +{
> > +	if (pkt == NULL || pkts_out == NULL || nb_pkts_out < 1)
> > +		return -EINVAL;
> > +
> > +	pkts_out[0] = pkt;
> > +
> > +	return 1;
> > +}
> > diff --git a/lib/librte_gso/rte_gso.h b/lib/librte_gso/rte_gso.h
> > new file mode 100644
> > index 0000000..db757d6
> > --- /dev/null
> > +++ b/lib/librte_gso/rte_gso.h
> > @@ -0,0 +1,133 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> > + *   All rights reserved.
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of Intel Corporation nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *
> > + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#ifndef _RTE_GSO_H_
> > +#define _RTE_GSO_H_
> > +
> > +/**
> > + * @file
> > + * Interface to GSO library
> > + */
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +#include <stdint.h>
> > +#include <rte_mbuf.h>
> > +
> > +/* GSO IP id flags for the IPv4 header */
> > +#define RTE_GSO_IPID_FIXED (1 << 0)
> > +/**< Use fixed IP ids for output GSO segments */
> > +#define RTE_GSO_IPID_INCREASE (1 << 1)
> > +/**< Use incremental IP ids for output GSO segments */
> 
> As values above are mutually exclusive, I think you don't need both flags.
> Just one seems enough.

Agree, I will remove RTE_GSO_IPID_INCREASE.

> 
> 
> > +
> > +/**
> > + * GSO context structure.
> > + */
> > +struct rte_gso_ctx {
> > +	struct rte_mempool *direct_pool;
> > +	/**< MBUF pool for allocating direct buffers, which are used
> > +	 * to store packet headers for GSO segments.
> > +	 */
> > +	struct rte_mempool *indirect_pool;
> > +	/**< MBUF pool for allocating indirect buffers, which are used
> > +	 * to locate packet payloads for GSO segments. The indirect
> > +	 * buffer doesn't contain any data, but simply points to an
> > +	 * offset within the packet to segment.
> > +	 */
> > +	uint32_t gso_types;
> > +	/**< packet types to perform GSO. For example, if applications
> > +	 * want to segment TCP/IPv4 packets, may set (RTE_PTYPE_L2_ETHER |
> > +	 * RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP) to gso_types.
> 
> 
> Actually after another thought - it probably should be no ptype mask, but mask
> of rte_ethdev DEV_TX_OFFLOAD_*_TSO flags that are used to advertise real HW TSO offloads.
> Let say for GSO that supports TSO over IPv4 it would be:
> PKT_TX_TCP_SEG | PKT_TX_IPV4.
> That would allow user to use GSO and TSO in a transparent way,
> plus ptype is not actually a proper bitmask, but a set of enums,
> so it not always possible to distinguish what ptype is supported just by bitmask.
> Sorry for causing confusion here.

Yes, agree. Reusing packet_type indeed introduces lots of macros to applications.
DEV_TX_OFFLOAD_*_TSO is a better choice, and it can also make HW offload and SW
offload consistent.

> 
> > +	 */
> > +	uint16_t gso_size;
> > +	/**< maximum size of an output GSO segment, including packet
> > +	 * header and payload, measured in bytes.
> > +	 */
> > +	uint8_t ipid_flag;
> 
> I'd suggest uint32_t flags (or even uint64_t).
> Who knows what extra flags we'll need in future here.

Make sense. I will use uint64_t.

> 
> > +	/**< flag to indicate GSO uses fixed or incremental IP ids for
> > +	 * IPv4 headers of output GSO segments.
> > +	 */
> > +};
> > +
> > +/**
> > + * Segmentation function, which supports processing of both single- and
> > + * multi- segment packets.
> > + *
> > + * Note that we refer to the packets that are segmented from the input
> > + * packet as 'GSO segments'. rte_gso_segment() assumes the input packet
> > + * has correct checksums, and it doesn't update checksums for output
> > + * GSO segments. Additionally, it doesn't process IP fragment packets.
> > + *
> > + * Each of the newly-created GSO segments is organized as a two-segment
> > + * MBUF, where the first segment is a standard MBUF, which stores a copy
> > + * of packet header, and the second is an indirect MBUF which points to
> > + * a section of data in the input packet. Since each GSO segment has
> > + * multiple MBUFs (i.e. 2 MBUFs), the driver of the interface which the
> > + * GSO segments are sent to should support to transmit multi-segment
> > + * packets.
> > + *
> > + * If the input packet is GSOed, its mbuf refcnt reduces by 1. Therefore,
> > + * when all GSO segments are freed, the input packet is freed automatically.
> > + *
> > + * If the memory space in pkts_out or MBUF pools is insufficient, this
> > + * function fails, and it returns (-1) * errno. Otherwise, GSO successes,
> > + * and this function returns the number of output GSO segments filled in
> > + * pkts_out.
> > + *
> > + * @param pkt
> > + *  The packet mbuf to segment.
> > + * @param ctx
> > + *  GSO context object.
> > + * @param pkts_out
> > + *  Pointer array used to store the MBUF addresses of output GSO
> > + *  segments, when rte_gso_segment() successes.
> > + * @param nb_pkts_out
> > + *  The max number of items that pkts_out can keep.
> > + *
> > + * @return
> > + *  - The number of GSO segments filled in pkts_out on success.
> > + *  - Return -ENOMEM if run out of memory in MBUF pools.
> > + *  - Return -EINVAL for invalid parameters.
> > + */
> > +int rte_gso_segment(struct rte_mbuf *pkt,
> > +		struct rte_gso_ctx ctx,
> > +		struct rte_mbuf **pkts_out,
> > +		uint16_t nb_pkts_out);
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* _RTE_GSO_H_ */
Ferruh Yigit Sept. 14, 2017, 6:33 p.m.
On 9/12/2017 3:43 AM, Jiayu Hu wrote:
> Generic Segmentation Offload (GSO) is a SW technique to split large
> packets into small ones. Akin to TSO, GSO enables applications to
> operate on large packets, thus reducing per-packet processing overhead.
> 
> To enable more flexibility to applications, DPDK GSO is implemented
> as a standalone library. Applications explicitly use the GSO library
> to segment packets. This patch introduces the GSO API framework to DPDK.
> 
> The GSO library provides a segmentation API, rte_gso_segment(), for
> applications. It splits an input packet into small ones in each
> invocation. The GSO library refers to these small packets generated
> by rte_gso_segment() as GSO segments. Each of the newly-created GSO
> segments is organized as a two-segment MBUF, where the first segment is a
> standard MBUF, which stores a copy of packet header, and the second is an
> indirect MBUF which points to a section of data in the input packet.
> rte_gso_segment() reduces the refcnt of the input packet by 1. Therefore,
> when all GSO segments are freed, the input packet is freed automatically.
> Additionally, since each GSO segment has multiple MBUFs (i.e. 2 MBUFs),
> the driver of the interface which the GSO segments are sent to should
> support to transmit multi-segment packets.
> 
> Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
> Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
> ---
>  config/common_base                 |   5 ++
>  lib/Makefile                       |   2 +
>  lib/librte_gso/Makefile            |  49 ++++++++++++++
>  lib/librte_gso/rte_gso.c           |  50 ++++++++++++++
>  lib/librte_gso/rte_gso.h           | 133 +++++++++++++++++++++++++++++++++++++
>  lib/librte_gso/rte_gso_version.map |   7 ++
>  mk/rte.app.mk                      |   1 +

Can you please update documentation for new library:

- library documentation "doc/guides/prog_guide/xxx.rst"
- api documentation: doc/api/doxy-api.conf, doc/api/doxy-api-index.md
- release notes update to announce new library
- release notes, "Shared Library Versions" section with new library.

<...>
Jiayu Hu Sept. 15, 2017, 1:12 a.m.
Hi Ferruh,

> -----Original Message-----

> From: Yigit, Ferruh

> Sent: Friday, September 15, 2017 2:33 AM

> To: Hu, Jiayu <jiayu.hu@intel.com>; dev@dpdk.org

> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Kavanagh, Mark

> B <mark.b.kavanagh@intel.com>; Tan, Jianfeng <jianfeng.tan@intel.com>

> Subject: Re: [dpdk-dev] [PATCH v3 1/5] gso: add Generic Segmentation

> Offload API framework

> 

> On 9/12/2017 3:43 AM, Jiayu Hu wrote:

> > Generic Segmentation Offload (GSO) is a SW technique to split large

> > packets into small ones. Akin to TSO, GSO enables applications to

> > operate on large packets, thus reducing per-packet processing overhead.

> >

> > To enable more flexibility to applications, DPDK GSO is implemented

> > as a standalone library. Applications explicitly use the GSO library

> > to segment packets. This patch introduces the GSO API framework to DPDK.

> >

> > The GSO library provides a segmentation API, rte_gso_segment(), for

> > applications. It splits an input packet into small ones in each

> > invocation. The GSO library refers to these small packets generated

> > by rte_gso_segment() as GSO segments. Each of the newly-created GSO

> > segments is organized as a two-segment MBUF, where the first segment is

> a

> > standard MBUF, which stores a copy of packet header, and the second is an

> > indirect MBUF which points to a section of data in the input packet.

> > rte_gso_segment() reduces the refcnt of the input packet by 1. Therefore,

> > when all GSO segments are freed, the input packet is freed automatically.

> > Additionally, since each GSO segment has multiple MBUFs (i.e. 2 MBUFs),

> > the driver of the interface which the GSO segments are sent to should

> > support to transmit multi-segment packets.

> >

> > Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>

> > Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>

> > ---

> >  config/common_base                 |   5 ++

> >  lib/Makefile                       |   2 +

> >  lib/librte_gso/Makefile            |  49 ++++++++++++++

> >  lib/librte_gso/rte_gso.c           |  50 ++++++++++++++

> >  lib/librte_gso/rte_gso.h           | 133

> +++++++++++++++++++++++++++++++++++++

> >  lib/librte_gso/rte_gso_version.map |   7 ++

> >  mk/rte.app.mk                      |   1 +

> 

> Can you please update documentation for new library:

> 

> - library documentation "doc/guides/prog_guide/xxx.rst"

> - api documentation: doc/api/doxy-api.conf, doc/api/doxy-api-index.md

> - release notes update to announce new library

> - release notes, "Shared Library Versions" section with new library.


Thanks for your reminder. I will update them sooner.

Jiayu
> 

> <...>

Patch hide | download patch | download mbox

diff --git a/config/common_base b/config/common_base
index 5e97a08..603e340 100644
--- a/config/common_base
+++ b/config/common_base
@@ -652,6 +652,11 @@  CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
 CONFIG_RTE_LIBRTE_GRO=y
 
 #
+# Compile GSO library
+#
+CONFIG_RTE_LIBRTE_GSO=y
+
+#
 # Compile librte_meter
 #
 CONFIG_RTE_LIBRTE_METER=y
diff --git a/lib/Makefile b/lib/Makefile
index 86caba1..3d123f4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -108,6 +108,8 @@  DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
 DEPDIRS-librte_reorder := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
 DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_GSO) += librte_gso
+DEPDIRS-librte_gso := librte_eal librte_mbuf librte_ether librte_net
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_gso/Makefile b/lib/librte_gso/Makefile
new file mode 100644
index 0000000..aeaacbc
--- /dev/null
+++ b/lib/librte_gso/Makefile
@@ -0,0 +1,49 @@ 
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_gso.a
+
+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+
+EXPORT_MAP := rte_gso_version.map
+
+LIBABIVER := 1
+
+#source files
+SRCS-$(CONFIG_RTE_LIBRTE_GSO) += rte_gso.c
+
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_GSO)-include += rte_gso.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c
new file mode 100644
index 0000000..dda50ee
--- /dev/null
+++ b/lib/librte_gso/rte_gso.c
@@ -0,0 +1,50 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include "rte_gso.h"
+
+int
+rte_gso_segment(struct rte_mbuf *pkt,
+		struct rte_gso_ctx gso_ctx __rte_unused,
+		struct rte_mbuf **pkts_out,
+		uint16_t nb_pkts_out)
+{
+	if (pkt == NULL || pkts_out == NULL || nb_pkts_out < 1)
+		return -EINVAL;
+
+	pkts_out[0] = pkt;
+
+	return 1;
+}
diff --git a/lib/librte_gso/rte_gso.h b/lib/librte_gso/rte_gso.h
new file mode 100644
index 0000000..db757d6
--- /dev/null
+++ b/lib/librte_gso/rte_gso.h
@@ -0,0 +1,133 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_GSO_H_
+#define _RTE_GSO_H_
+
+/**
+ * @file
+ * Interface to GSO library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <rte_mbuf.h>
+
+/* GSO IP id flags for the IPv4 header */
+#define RTE_GSO_IPID_FIXED (1 << 0)
+/**< Use fixed IP ids for output GSO segments */
+#define RTE_GSO_IPID_INCREASE (1 << 1)
+/**< Use incremental IP ids for output GSO segments */
+
+/**
+ * GSO context structure.
+ */
+struct rte_gso_ctx {
+	struct rte_mempool *direct_pool;
+	/**< MBUF pool for allocating direct buffers, which are used
+	 * to store packet headers for GSO segments.
+	 */
+	struct rte_mempool *indirect_pool;
+	/**< MBUF pool for allocating indirect buffers, which are used
+	 * to locate packet payloads for GSO segments. The indirect
+	 * buffer doesn't contain any data, but simply points to an
+	 * offset within the packet to segment.
+	 */
+	uint32_t gso_types;
+	/**< packet types to perform GSO. For example, if applications
+	 * want to segment TCP/IPv4 packets, may set (RTE_PTYPE_L2_ETHER |
+	 * RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP) to gso_types.
+	 */
+	uint16_t gso_size;
+	/**< maximum size of an output GSO segment, including packet
+	 * header and payload, measured in bytes.
+	 */
+	uint8_t ipid_flag;
+	/**< flag to indicate GSO uses fixed or incremental IP ids for
+	 * IPv4 headers of output GSO segments.
+	 */
+};
+
+/**
+ * Segmentation function, which supports processing of both single- and
+ * multi- segment packets.
+ *
+ * Note that we refer to the packets that are segmented from the input
+ * packet as 'GSO segments'. rte_gso_segment() assumes the input packet
+ * has correct checksums, and it doesn't update checksums for output
+ * GSO segments. Additionally, it doesn't process IP fragment packets.
+ *
+ * Each of the newly-created GSO segments is organized as a two-segment
+ * MBUF, where the first segment is a standard MBUF, which stores a copy
+ * of packet header, and the second is an indirect MBUF which points to
+ * a section of data in the input packet. Since each GSO segment has
+ * multiple MBUFs (i.e. 2 MBUFs), the driver of the interface which the
+ * GSO segments are sent to should support to transmit multi-segment
+ * packets.
+ *
+ * If the input packet is GSOed, its mbuf refcnt reduces by 1. Therefore,
+ * when all GSO segments are freed, the input packet is freed automatically.
+ *
+ * If the memory space in pkts_out or MBUF pools is insufficient, this
+ * function fails, and it returns (-1) * errno. Otherwise, GSO successes,
+ * and this function returns the number of output GSO segments filled in
+ * pkts_out.
+ *
+ * @param pkt
+ *  The packet mbuf to segment.
+ * @param ctx
+ *  GSO context object.
+ * @param pkts_out
+ *  Pointer array used to store the MBUF addresses of output GSO
+ *  segments, when rte_gso_segment() successes.
+ * @param nb_pkts_out
+ *  The max number of items that pkts_out can keep.
+ *
+ * @return
+ *  - The number of GSO segments filled in pkts_out on success.
+ *  - Return -ENOMEM if run out of memory in MBUF pools.
+ *  - Return -EINVAL for invalid parameters.
+ */
+int rte_gso_segment(struct rte_mbuf *pkt,
+		struct rte_gso_ctx ctx,
+		struct rte_mbuf **pkts_out,
+		uint16_t nb_pkts_out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_GSO_H_ */
diff --git a/lib/librte_gso/rte_gso_version.map b/lib/librte_gso/rte_gso_version.map
new file mode 100644
index 0000000..e1fd453
--- /dev/null
+++ b/lib/librte_gso/rte_gso_version.map
@@ -0,0 +1,7 @@ 
+DPDK_17.11 {
+	global:
+
+	rte_gso_segment;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..d4c9873 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -66,6 +66,7 @@  _LDLIBS-$(CONFIG_RTE_LIBRTE_PDUMP)          += -lrte_pdump
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR)    += -lrte_distributor
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG)        += -lrte_ip_frag
 _LDLIBS-$(CONFIG_RTE_LIBRTE_GRO)            += -lrte_gro
+_LDLIBS-$(CONFIG_RTE_LIBRTE_GSO)            += -lrte_gso
 _LDLIBS-$(CONFIG_RTE_LIBRTE_METER)          += -lrte_meter
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
 _LDLIBS-$(CONFIG_RTE_LIBRTE_LPM)            += -lrte_lpm