On 9/13/21 9:56 AM, Xu, Rosen wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Anoob Joseph <ano...@marvell.com>
>> Sent: Wednesday, September 08, 2021 18:30
>> To: Yigit, Ferruh <ferruh.yi...@intel.com>; Xu, Rosen <rosen...@intel.com>;
>> Andrew Rybchenko <arybche...@solarflare.com>
>> Cc: Nicolau, Radu <radu.nico...@intel.com>; Doherty, Declan
>> <declan.dohe...@intel.com>; hemant.agra...@nxp.com;
>> ma...@nvidia.com; Ananyev, Konstantin <konstantin.anan...@intel.com>;
>> tho...@monjalon.net; Ankur Dwivedi <adwiv...@marvell.com>;
>> andrew.rybche...@oktetlabs.ru; Akhil Goyal <gak...@marvell.com>;
>> dev@dpdk.org
>> Subject: RE: [EXT] Re: [PATCH] RFC: ethdev: add reassembly offload
>>
>> Hi Ferruh, Rosen, Andrew,
>>
>> Please see inline.
>>
>> Thanks,
>> Anoob
>>
>>> Subject: [EXT] Re: [PATCH] RFC: ethdev: add reassembly offload
>>>
>>> External Email
>>>
>>> ----------------------------------------------------------------------
>>> On 8/23/2021 11:02 AM, Akhil Goyal wrote:
>>>> Reassembly is a costly operation if it is done in software, however,
>>>> if it is offloaded to HW, it can considerably save application cycles.
>>>> The operation becomes even more costlier if IP fragmants are
>>>> encrypted.
>>>>
>>>> To resolve above two issues, a new offload
>>> DEV_RX_OFFLOAD_REASSEMBLY
>>>> is introduced in ethdev for devices which can attempt reassembly of
>>>> packets in hardware.
>>>> rte_eth_dev_info is added with the reassembly capabilities which a
>>>> device can support.
>>>> Now, if IP fragments are encrypted, reassembly can also be attempted
>>>> while doing inline IPsec processing.
>>>> This is controlled by a flag in rte_security_ipsec_sa_options to
>>>> enable reassembly of encrypted IP fragments in the inline path.
>>>>
>>>> The resulting reassembled packet would be a typical segmented mbuf
>>>> in case of success.
>>>>
>>>> And if reassembly of fragments is failed or is incomplete (if
>>>> fragments do not come before the reass_timeout), the mbuf is updated
>>>> with an ol_flag PKT_RX_REASSEMBLY_INCOMPLETE and mbuf is returned
>>> as
>>>> is. Now application may decide the fate of the packet to wait more
>>>> for fragments to come or drop.
>>>>
>>>> Signed-off-by: Akhil Goyal <gak...@marvell.com>
>>>> ---
>>>>  lib/ethdev/rte_ethdev.c     |  1 +
>>>>  lib/ethdev/rte_ethdev.h     | 18 +++++++++++++++++-
>>>>  lib/mbuf/rte_mbuf_core.h    |  3 ++-
>>>>  lib/security/rte_security.h | 10 ++++++++++
>>>>  4 files changed, 30 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index
>>>> 9d95cd11e1..1ab3a093cf 100644
>>>> --- a/lib/ethdev/rte_ethdev.c
>>>> +++ b/lib/ethdev/rte_ethdev.c
>>>> @@ -119,6 +119,7 @@ static const struct {
>>>>    RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER),
>>>>    RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND),
>>>>    RTE_RX_OFFLOAD_BIT2STR(JUMBO_FRAME),
>>>> +  RTE_RX_OFFLOAD_BIT2STR(REASSEMBLY),
>>>>    RTE_RX_OFFLOAD_BIT2STR(SCATTER),
>>>>    RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP),
>>>>    RTE_RX_OFFLOAD_BIT2STR(SECURITY),
>>>> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index
>>>> d2b27c351f..e89a4dc1eb 100644
>>>> --- a/lib/ethdev/rte_ethdev.h
>>>> +++ b/lib/ethdev/rte_ethdev.h
>>>> @@ -1360,6 +1360,7 @@ struct rte_eth_conf {
>>>>  #define DEV_RX_OFFLOAD_VLAN_FILTER        0x00000200
>>>>  #define DEV_RX_OFFLOAD_VLAN_EXTEND        0x00000400
>>>>  #define DEV_RX_OFFLOAD_JUMBO_FRAME        0x00000800
>>>> +#define DEV_RX_OFFLOAD_REASSEMBLY 0x00001000
>>>
>>> previous '0x00001000' was 'DEV_RX_OFFLOAD_CRC_STRIP', it has been
>> long
>>> that offload has been removed, but not sure if it cause any problem to
>>> re- use it.
>>>
>>>>  #define DEV_RX_OFFLOAD_SCATTER            0x00002000
>>>>  /**
>>>>   * Timestamp is set by the driver in
>>> RTE_MBUF_DYNFIELD_TIMESTAMP_NAME
>>>> @@ -1477,6 +1478,20 @@ struct rte_eth_dev_portconf {
>>>>   */
>>>>  #define RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID
>>>     (UINT16_MAX)
>>>>
>>>> +/**
>>>> + * Reassembly capabilities that a device can support.
>>>> + * The device which can support reassembly offload should set
>>>> + * DEV_RX_OFFLOAD_REASSEMBLY
>>>> + */
>>>> +struct rte_eth_reass_capa {
>>>> +  /** Maximum time in ns that a fragment can wait for further
>>> fragments */
>>>> +  uint64_t reass_timeout;
>>>> +  /** Maximum number of fragments that device can reassemble */
>>>> +  uint16_t max_frags;
>>>> +  /** Reserved for future capabilities */
>>>> +  uint16_t reserved[3];
>>>> +};
>>>> +
>>>
>>> I wonder if there is any other hardware around supports reassembly
>>> offload, it would be good to get more feedback on the capabilities list.
>>>
>>>>  /**
>>>>   * Ethernet device associated switch information
>>>>   */
>>>> @@ -1582,8 +1597,9 @@ struct rte_eth_dev_info {
>>>>     * embedded managed interconnect/switch.
>>>>     */
>>>>    struct rte_eth_switch_info switch_info;
>>>> +  /* Reassembly capabilities of a device for reassembly offload */
>>>> +  struct rte_eth_reass_capa reass_capa;
>>>>
>>>> -  uint64_t reserved_64s[2]; /**< Reserved for future fields */
>>>
>>> Reserved fields were added to be able to update the struct without
>>> breaking the ABI, so that a critical change doesn't have to wait until
>>> next ABI break release.
>>> Since this is ABI break release, we can keep the reserved field and
>>> add the new struct. Or this can be an opportunity to get rid of the reserved
>> field.
>>>
>>> Personally I have no objection to get rid of the reserved field, but
>>> better to agree on this explicitly.
>>>
>>>>    void *reserved_ptrs[2];   /**< Reserved for future fields */
>>>>  };
>>>>
>>>> diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
>>>> index
>>>> bb38d7f581..cea25c87f7 100644
>>>> --- a/lib/mbuf/rte_mbuf_core.h
>>>> +++ b/lib/mbuf/rte_mbuf_core.h
>>>> @@ -200,10 +200,11 @@ extern "C" {
>>>>  #define PKT_RX_OUTER_L4_CKSUM_BAD (1ULL << 21)
>>>>  #define PKT_RX_OUTER_L4_CKSUM_GOOD        (1ULL << 22)
>>>>  #define PKT_RX_OUTER_L4_CKSUM_INVALID     ((1ULL << 21) | (1ULL
>>> << 22))
>>>> +#define PKT_RX_REASSEMBLY_INCOMPLETE      (1ULL << 23)
>>>>
>>>
>>> Similar comment with Andrew's, what is the expectation from
>>> application if this flag exists? Can we drop it to simplify the logic in the
>> application?
>>
>> [Anoob] There can be few cases where hardware/NIC attempts inline
>> reassembly but it fails to complete it
>>
>> 1. Number of fragments is larger than what is supported by the hardware 2.
>> Hardware reassembly resources are exhausted (due to limited reassembly
>> contexts etc) 3. Reassembly errors such as overlapping fragments 4. Wait
>> time exhausted (or reassembly timeout)
>>
>> In such cases, application would be required to retrieve the original
>> fragments so that it can attempt reassembly in software. The incomplete flag
>> is useful for 2 purposes basically, 1. Application would need to retrieve the
>> time the fragment has already spend in hardware reassembly so that
>> software reassembly attempt can compensate for it. Otherwise, reassembly
>> timeout across hardware + software will not be accurate 

Could you clarify how application will find out the time spent
in HW.

>> 2. Retrieve original
>> fragments. With this proposal, an incomplete reassembly would result in a
>> chained mbuf but the segments need not be consecutive. To explain bit more,
>>
>> Suppose we have a packet that is fragmented into 3 fragments, and fragment
>> 3 & fragment 1 arrives in that order. Fragment 2 didn't arrive and hardware
>> ultimately pushes it. In that case, application would be receiving a
>> chained/segmented mbuf with fragment 1 & fragment 3 chained.
>>
>> Now, this chained mbuf can't be treated like a regular chained mbuf. Each
>> fragment would have its IP hdr and there are fragments missing in between.
>> The only thing application is expected to do is, retrieve fragments, push it 
>> to
>> s/w reassembly.

It sounds like it conflicts with SCATTER and BUFFER_SPLIT
offloads which allow to return chained mbuf's. Don't know
if it is good or bad, but anyway it must be documented.

> 
> What you mentioned is error identification. But actually a negotiation about 
> max frame size is needed before datagrams tx/rx.

It sounds like it is OK for informational purposes, but
right now I don't understand how it could be used by the
application. Application still has to support reassembly
in SW regardless of the information.

>>>
>>>>  /* add new RX flags here, don't forget to update PKT_FIRST_FREE */
>>>>
>>>> -#define PKT_FIRST_FREE (1ULL << 23)
>>>> +#define PKT_FIRST_FREE (1ULL << 24)
>>>>  #define PKT_LAST_FREE (1ULL << 40)
>>>>
>>>>  /* add new TX flags here, don't forget to update PKT_LAST_FREE  */
>>>> diff --git a/lib/security/rte_security.h
>>>> b/lib/security/rte_security.h index 88d31de0a6..364eeb5cd4 100644
>>>> --- a/lib/security/rte_security.h
>>>> +++ b/lib/security/rte_security.h
>>>> @@ -181,6 +181,16 @@ struct rte_security_ipsec_sa_options {
>>>>     * * 0: Disable per session security statistics collection for this SA.
>>>>     */
>>>>    uint32_t stats : 1;
>>>> +
>>>> +  /** Enable reassembly on incoming packets.
>>>> +   *
>>>> +   * * 1: Enable driver to try reassembly of encrypted IP packets for
>>>> +   *      this SA, if supported by the driver. This feature will work
>>>> +   *      only if rx_offload DEV_RX_OFFLOAD_REASSEMBLY is set in
>>>> +   *      inline ethernet device.
>>>> +   * * 0: Disable reassembly of packets (default).
>>>> +   */
>>>> +  uint32_t reass_en : 1;
>>>>  };
>>>>
>>>>  /** IPSec security association direction */
>>>>
> 

Reply via email to