diff mbox

Packet segment API continued

Message ID 1404469916-16180-1-git-send-email-petri.savolainen@linaro.org
State Accepted
Commit 51a41ca3cdb7c66d436cd883ad45706349eeb194
Headers show

Commit Message

Petri Savolainen July 4, 2014, 10:31 a.m. UTC
Replaced segment index with handle. Segment handle is always
coupled with packet handle. Added functions to get segment
handle from index and from current handle (iterate to next seg).
Added segment info function.

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
---
 include/odp_packet.h | 103 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 82 insertions(+), 21 deletions(-)

Comments

Maxim Uvarov July 8, 2014, 8:50 a.m. UTC | #1
Taras, Bala, no objection/review comments? ACK?

Maxim.

On 07/04/2014 02:31 PM, Petri Savolainen wrote:
> Replaced segment index with handle. Segment handle is always
> coupled with packet handle. Added functions to get segment
> handle from index and from current handle (iterate to next seg).
> Added segment info function.
>
> Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
> ---
>   include/odp_packet.h | 103 ++++++++++++++++++++++++++++++++++++++++-----------
>   1 file changed, 82 insertions(+), 21 deletions(-)
>
> diff --git a/include/odp_packet.h b/include/odp_packet.h
> index 8ae6410..ef4be9e 100644
> --- a/include/odp_packet.h
> +++ b/include/odp_packet.h
> @@ -34,6 +34,25 @@ typedef odp_buffer_t odp_packet_t;
>   
>   
>   /**
> + * ODP packet segment handle
> + */
> +typedef int odp_packet_seg_t;
> +
> +/** Invalid packet segment */
> +#define ODP_PACKET_SEG_INVALID -1
> +
> +/**
> + * ODP packet segment info
> + */
> +typedef struct odp_packet_seg_info_t {
> +	void   *addr;      /**< Segment start address */
> +	size_t  size;      /**< Segment maximum data size */
> +	void   *data;      /**< Segment data address */
> +	size_t  data_len;  /**< Segment data length */
> +} odp_packet_seg_info_t;
> +
> +
> +/**
>    * Initialize the packet
>    *
>    * Needs to be called if the user allocates a packet buffer, i.e. the packet
> @@ -242,44 +261,78 @@ int odp_packet_is_segmented(odp_packet_t pkt);
>   int odp_packet_seg_count(odp_packet_t pkt);
>   
>   /**
> + * Get segment by index
> + *
> + * @param pkt   Packet handle
> + * @param index Segment index (0 ... seg_count-1)
> + *
> + * @return Segment handle, or ODP_PACKET_SEG_INVALID on an error
> + */
> +odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int index);
> +
> +/**
> + * Get next segment
> + *
> + * @param pkt   Packet handle
> + * @param seg   Current segment handle
> + *
> + * @return Handle to next segment, or ODP_PACKET_SEG_INVALID on an error
> + */
> +odp_packet_seg_t odp_packet_seg_next(odp_packet_t pkt, odp_packet_seg_t seg);
> +
> +/**
> + * Segment info
> + *
> + * Copies segment parameters into the info structure.
> + *
> + * @param pkt  Packet handle
> + * @param seg  Segment handle
> + * @param info Pointer to segment info structure
> + *
> + * @return 0 if successful, otherwise non-zero
> + */
> +int odp_packet_seg_info(odp_packet_t pkt, odp_packet_seg_t seg,
> +			odp_packet_seg_info_t *info);
> +
> +/**
>    * Segment start address
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
> - * @return Segment start address
> + * @return Segment start address, or NULL on an error
>    */
> -void *odp_packet_seg_addr(odp_packet_t pkt, int seg);
> +void *odp_packet_seg_addr(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment maximum data size
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Segment maximum data size
>    */
> -size_t odp_packet_seg_size(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_size(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment data address
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Segment data address
>    */
> -void *odp_packet_seg_data(odp_packet_t pkt, int seg);
> +void *odp_packet_seg_data(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment data length
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Segment data length
>    */
> -size_t odp_packet_seg_data_len(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment headroom
> @@ -287,11 +340,11 @@ size_t odp_packet_seg_data_len(odp_packet_t pkt, int seg);
>    * seg_headroom = seg_data - seg_addr
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Number of octets from seg_addr to seg_data
>    */
> -size_t odp_packet_seg_headroom(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_headroom(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment tailroom
> @@ -299,73 +352,81 @@ size_t odp_packet_seg_headroom(odp_packet_t pkt, int seg);
>    * seg_tailroom = seg_size - seg_headroom - seg_data_len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Number of octets from end-of-data to end-of-segment
>    */
> -size_t odp_packet_seg_tailroom(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_tailroom(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Push out segment head
>    *
>    * Push out segment data address (away from data) and increase data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data     -= len
>    * seg_data_len += len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to push head (0 ... seg_headroom)
>    *
>    * @return New segment data address, or NULL on an error
>    */
> -void *odp_packet_seg_push_head(odp_packet_t pkt, int seg, size_t len);
> +void *odp_packet_seg_push_head(odp_packet_t pkt, odp_packet_seg_t seg,
> +			       size_t len);
>   
>   /**
>    * Pull in segment head
>    *
>    * Pull in segment data address (towards data) and decrease data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data     += len
>    * seg_data_len -= len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to pull head (0 ... seg_data_len)
>    *
>    * @return New segment data address, or NULL on an error
>    */
> -void *odp_packet_seg_pull_head(odp_packet_t pkt, int seg, size_t len);
> +void *odp_packet_seg_pull_head(odp_packet_t pkt, odp_packet_seg_t seg,
> +			       size_t len);
>   
>   /**
>    * Push out segment tail
>    *
>    * Increase segment data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data_len  += len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to push tail (0 ... seg_tailroom)
>    *
>    * @return New segment data length, or -1 on an error
>    */
> -int odp_packet_seg_push_tail(odp_packet_t pkt, int seg, size_t len);
> +int odp_packet_seg_push_tail(odp_packet_t pkt, odp_packet_seg_t seg,
> +			     size_t len);
>   
>   /**
>    * Pull in segment tail
>    *
>    * Decrease segment data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data_len  -= len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to pull tail (0 ... seg_data_len)
>    *
>    * @return New segment data length, or -1 on an error
>    */
> -int odp_packet_seg_pull_tail(odp_packet_t pkt, int seg, size_t len);
> +int odp_packet_seg_pull_tail(odp_packet_t pkt, odp_packet_seg_t seg,
> +			     size_t len);
>   
>   
>   #ifdef __cplusplus
Balasubramanian Manoharan July 8, 2014, 9:35 a.m. UTC | #2
Hi Maxim,

These APIs have incorporated the comments which were discussed in the
meeting.
There are no additional comments from my side.

Regards,
Bala


On 8 July 2014 14:20, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> Taras, Bala, no objection/review comments? ACK?
>
> Maxim.
>
>
> On 07/04/2014 02:31 PM, Petri Savolainen wrote:
>
>> Replaced segment index with handle. Segment handle is always
>> coupled with packet handle. Added functions to get segment
>> handle from index and from current handle (iterate to next seg).
>> Added segment info function.
>>
>> Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
>> ---
>>   include/odp_packet.h | 103 ++++++++++++++++++++++++++++++
>> ++++++++++-----------
>>   1 file changed, 82 insertions(+), 21 deletions(-)
>>
>> diff --git a/include/odp_packet.h b/include/odp_packet.h
>> index 8ae6410..ef4be9e 100644
>> --- a/include/odp_packet.h
>> +++ b/include/odp_packet.h
>> @@ -34,6 +34,25 @@ typedef odp_buffer_t odp_packet_t;
>>       /**
>> + * ODP packet segment handle
>> + */
>> +typedef int odp_packet_seg_t;
>> +
>> +/** Invalid packet segment */
>> +#define ODP_PACKET_SEG_INVALID -1
>> +
>> +/**
>> + * ODP packet segment info
>> + */
>> +typedef struct odp_packet_seg_info_t {
>> +       void   *addr;      /**< Segment start address */
>> +       size_t  size;      /**< Segment maximum data size */
>> +       void   *data;      /**< Segment data address */
>> +       size_t  data_len;  /**< Segment data length */
>> +} odp_packet_seg_info_t;
>> +
>> +
>> +/**
>>    * Initialize the packet
>>    *
>>    * Needs to be called if the user allocates a packet buffer, i.e. the
>> packet
>> @@ -242,44 +261,78 @@ int odp_packet_is_segmented(odp_packet_t pkt);
>>   int odp_packet_seg_count(odp_packet_t pkt);
>>     /**
>> + * Get segment by index
>> + *
>> + * @param pkt   Packet handle
>> + * @param index Segment index (0 ... seg_count-1)
>> + *
>> + * @return Segment handle, or ODP_PACKET_SEG_INVALID on an error
>> + */
>> +odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int index);
>> +
>> +/**
>> + * Get next segment
>> + *
>> + * @param pkt   Packet handle
>> + * @param seg   Current segment handle
>> + *
>> + * @return Handle to next segment, or ODP_PACKET_SEG_INVALID on an error
>> + */
>> +odp_packet_seg_t odp_packet_seg_next(odp_packet_t pkt, odp_packet_seg_t
>> seg);
>> +
>> +/**
>> + * Segment info
>> + *
>> + * Copies segment parameters into the info structure.
>> + *
>> + * @param pkt  Packet handle
>> + * @param seg  Segment handle
>> + * @param info Pointer to segment info structure
>> + *
>> + * @return 0 if successful, otherwise non-zero
>> + */
>> +int odp_packet_seg_info(odp_packet_t pkt, odp_packet_seg_t seg,
>> +                       odp_packet_seg_info_t *info);
>> +
>> +/**
>>    * Segment start address
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    *
>> - * @return Segment start address
>> + * @return Segment start address, or NULL on an error
>>    */
>> -void *odp_packet_seg_addr(odp_packet_t pkt, int seg);
>> +void *odp_packet_seg_addr(odp_packet_t pkt, odp_packet_seg_t seg);
>>     /**
>>    * Segment maximum data size
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    *
>>    * @return Segment maximum data size
>>    */
>> -size_t odp_packet_seg_size(odp_packet_t pkt, int seg);
>> +size_t odp_packet_seg_size(odp_packet_t pkt, odp_packet_seg_t seg);
>>     /**
>>    * Segment data address
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    *
>>    * @return Segment data address
>>    */
>> -void *odp_packet_seg_data(odp_packet_t pkt, int seg);
>> +void *odp_packet_seg_data(odp_packet_t pkt, odp_packet_seg_t seg);
>>     /**
>>    * Segment data length
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    *
>>    * @return Segment data length
>>    */
>> -size_t odp_packet_seg_data_len(odp_packet_t pkt, int seg);
>> +size_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg);
>>     /**
>>    * Segment headroom
>> @@ -287,11 +340,11 @@ size_t odp_packet_seg_data_len(odp_packet_t pkt,
>> int seg);
>>    * seg_headroom = seg_data - seg_addr
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    *
>>    * @return Number of octets from seg_addr to seg_data
>>    */
>> -size_t odp_packet_seg_headroom(odp_packet_t pkt, int seg);
>> +size_t odp_packet_seg_headroom(odp_packet_t pkt, odp_packet_seg_t seg);
>>     /**
>>    * Segment tailroom
>> @@ -299,73 +352,81 @@ size_t odp_packet_seg_headroom(odp_packet_t pkt,
>> int seg);
>>    * seg_tailroom = seg_size - seg_headroom - seg_data_len
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    *
>>    * @return Number of octets from end-of-data to end-of-segment
>>    */
>> -size_t odp_packet_seg_tailroom(odp_packet_t pkt, int seg);
>> +size_t odp_packet_seg_tailroom(odp_packet_t pkt, odp_packet_seg_t seg);
>>     /**
>>    * Push out segment head
>>    *
>>    * Push out segment data address (away from data) and increase data
>> length.
>> + * Does not modify packet in case of an error.
>>    *
>>    * seg_data     -= len
>>    * seg_data_len += len
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    * @param len  Number of octets to push head (0 ... seg_headroom)
>>    *
>>    * @return New segment data address, or NULL on an error
>>    */
>> -void *odp_packet_seg_push_head(odp_packet_t pkt, int seg, size_t len);
>> +void *odp_packet_seg_push_head(odp_packet_t pkt, odp_packet_seg_t seg,
>> +                              size_t len);
>>     /**
>>    * Pull in segment head
>>    *
>>    * Pull in segment data address (towards data) and decrease data length.
>> + * Does not modify packet in case of an error.
>>    *
>>    * seg_data     += len
>>    * seg_data_len -= len
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    * @param len  Number of octets to pull head (0 ... seg_data_len)
>>    *
>>    * @return New segment data address, or NULL on an error
>>    */
>> -void *odp_packet_seg_pull_head(odp_packet_t pkt, int seg, size_t len);
>> +void *odp_packet_seg_pull_head(odp_packet_t pkt, odp_packet_seg_t seg,
>> +                              size_t len);
>>     /**
>>    * Push out segment tail
>>    *
>>    * Increase segment data length.
>> + * Does not modify packet in case of an error.
>>    *
>>    * seg_data_len  += len
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    * @param len  Number of octets to push tail (0 ... seg_tailroom)
>>    *
>>    * @return New segment data length, or -1 on an error
>>    */
>> -int odp_packet_seg_push_tail(odp_packet_t pkt, int seg, size_t len);
>> +int odp_packet_seg_push_tail(odp_packet_t pkt, odp_packet_seg_t seg,
>> +                            size_t len);
>>     /**
>>    * Pull in segment tail
>>    *
>>    * Decrease segment data length.
>> + * Does not modify packet in case of an error.
>>    *
>>    * seg_data_len  -= len
>>    *
>>    * @param pkt  Packet handle
>> - * @param seg  Segment index (0 ... seg_count-1)
>> + * @param seg  Segment handle
>>    * @param len  Number of octets to pull tail (0 ... seg_data_len)
>>    *
>>    * @return New segment data length, or -1 on an error
>>    */
>> -int odp_packet_seg_pull_tail(odp_packet_t pkt, int seg, size_t len);
>> +int odp_packet_seg_pull_tail(odp_packet_t pkt, odp_packet_seg_t seg,
>> +                            size_t len);
>>       #ifdef __cplusplus
>>
>
>
Taras Kondratiuk July 8, 2014, 9:45 a.m. UTC | #3
We haven't discussed approach suggested by Bill, where addressing is 
done via offset in a packet, but not via explicit segments.
IMO for application it is the best case.

On 07/08/2014 12:35 PM, Bala Manoharan wrote:
> Hi Maxim,
>
> These APIs have incorporated the comments which were discussed in the
> meeting.
> There are no additional comments from my side.
>
> Regards,
> Bala
>
>
> On 8 July 2014 14:20, Maxim Uvarov <maxim.uvarov@linaro.org
> <mailto:maxim.uvarov@linaro.org>> wrote:
>
>     Taras, Bala, no objection/review comments? ACK?
>
>     Maxim.
>
>
>     On 07/04/2014 02:31 PM, Petri Savolainen wrote:
>
>         Replaced segment index with handle. Segment handle is always
>         coupled with packet handle. Added functions to get segment
>         handle from index and from current handle (iterate to next seg).
>         Added segment info function.
>
>         Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org
>         <mailto:petri.savolainen@linaro.org>>
>         ---
>            include/odp_packet.h | 103
>         ++++++++++++++++++++++++++++++__++++++++++-----------
>            1 file changed, 82 insertions(+), 21 deletions(-)
>
>         diff --git a/include/odp_packet.h b/include/odp_packet.h
>         index 8ae6410..ef4be9e 100644
>         --- a/include/odp_packet.h
>         +++ b/include/odp_packet.h
>         @@ -34,6 +34,25 @@ typedef odp_buffer_t odp_packet_t;
>                /**
>         + * ODP packet segment handle
>         + */
>         +typedef int odp_packet_seg_t;
>         +
>         +/** Invalid packet segment */
>         +#define ODP_PACKET_SEG_INVALID -1
>         +
>         +/**
>         + * ODP packet segment info
>         + */
>         +typedef struct odp_packet_seg_info_t {
>         +       void   *addr;      /**< Segment start address */
>         +       size_t  size;      /**< Segment maximum data size */
>         +       void   *data;      /**< Segment data address */
>         +       size_t  data_len;  /**< Segment data length */
>         +} odp_packet_seg_info_t;
>         +
>         +
>         +/**
>             * Initialize the packet
>             *
>             * Needs to be called if the user allocates a packet buffer,
>         i.e. the packet
>         @@ -242,44 +261,78 @@ int odp_packet_is_segmented(odp___packet_t
>         pkt);
>            int odp_packet_seg_count(odp___packet_t pkt);
>              /**
>         + * Get segment by index
>         + *
>         + * @param pkt   Packet handle
>         + * @param index Segment index (0 ... seg_count-1)
>         + *
>         + * @return Segment handle, or ODP_PACKET_SEG_INVALID on an error
>         + */
>         +odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int index);
>         +
>         +/**
>         + * Get next segment
>         + *
>         + * @param pkt   Packet handle
>         + * @param seg   Current segment handle
>         + *
>         + * @return Handle to next segment, or ODP_PACKET_SEG_INVALID on
>         an error
>         + */
>         +odp_packet_seg_t odp_packet_seg_next(odp___packet_t pkt,
>         odp_packet_seg_t seg);
>         +
>         +/**
>         + * Segment info
>         + *
>         + * Copies segment parameters into the info structure.
>         + *
>         + * @param pkt  Packet handle
>         + * @param seg  Segment handle
>         + * @param info Pointer to segment info structure
>         + *
>         + * @return 0 if successful, otherwise non-zero
>         + */
>         +int odp_packet_seg_info(odp___packet_t pkt, odp_packet_seg_t seg,
>         +                       odp_packet_seg_info_t *info);
>         +
>         +/**
>             * Segment start address
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             *
>         - * @return Segment start address
>         + * @return Segment start address, or NULL on an error
>             */
>         -void *odp_packet_seg_addr(odp___packet_t pkt, int seg);
>         +void *odp_packet_seg_addr(odp___packet_t pkt, odp_packet_seg_t
>         seg);
>              /**
>             * Segment maximum data size
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             *
>             * @return Segment maximum data size
>             */
>         -size_t odp_packet_seg_size(odp___packet_t pkt, int seg);
>         +size_t odp_packet_seg_size(odp___packet_t pkt, odp_packet_seg_t
>         seg);
>              /**
>             * Segment data address
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             *
>             * @return Segment data address
>             */
>         -void *odp_packet_seg_data(odp___packet_t pkt, int seg);
>         +void *odp_packet_seg_data(odp___packet_t pkt, odp_packet_seg_t
>         seg);
>              /**
>             * Segment data length
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             *
>             * @return Segment data length
>             */
>         -size_t odp_packet_seg_data_len(odp___packet_t pkt, int seg);
>         +size_t odp_packet_seg_data_len(odp___packet_t pkt,
>         odp_packet_seg_t seg);
>              /**
>             * Segment headroom
>         @@ -287,11 +340,11 @@ size_t
>         odp_packet_seg_data_len(odp___packet_t pkt, int seg);
>             * seg_headroom = seg_data - seg_addr
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             *
>             * @return Number of octets from seg_addr to seg_data
>             */
>         -size_t odp_packet_seg_headroom(odp___packet_t pkt, int seg);
>         +size_t odp_packet_seg_headroom(odp___packet_t pkt,
>         odp_packet_seg_t seg);
>              /**
>             * Segment tailroom
>         @@ -299,73 +352,81 @@ size_t
>         odp_packet_seg_headroom(odp___packet_t pkt, int seg);
>             * seg_tailroom = seg_size - seg_headroom - seg_data_len
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             *
>             * @return Number of octets from end-of-data to end-of-segment
>             */
>         -size_t odp_packet_seg_tailroom(odp___packet_t pkt, int seg);
>         +size_t odp_packet_seg_tailroom(odp___packet_t pkt,
>         odp_packet_seg_t seg);
>              /**
>             * Push out segment head
>             *
>             * Push out segment data address (away from data) and
>         increase data length.
>         + * Does not modify packet in case of an error.
>             *
>             * seg_data     -= len
>             * seg_data_len += len
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             * @param len  Number of octets to push head (0 ... seg_headroom)
>             *
>             * @return New segment data address, or NULL on an error
>             */
>         -void *odp_packet_seg_push_head(odp___packet_t pkt, int seg,
>         size_t len);
>         +void *odp_packet_seg_push_head(odp___packet_t pkt,
>         odp_packet_seg_t seg,
>         +                              size_t len);
>              /**
>             * Pull in segment head
>             *
>             * Pull in segment data address (towards data) and decrease
>         data length.
>         + * Does not modify packet in case of an error.
>             *
>             * seg_data     += len
>             * seg_data_len -= len
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             * @param len  Number of octets to pull head (0 ... seg_data_len)
>             *
>             * @return New segment data address, or NULL on an error
>             */
>         -void *odp_packet_seg_pull_head(odp___packet_t pkt, int seg,
>         size_t len);
>         +void *odp_packet_seg_pull_head(odp___packet_t pkt,
>         odp_packet_seg_t seg,
>         +                              size_t len);
>              /**
>             * Push out segment tail
>             *
>             * Increase segment data length.
>         + * Does not modify packet in case of an error.
>             *
>             * seg_data_len  += len
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             * @param len  Number of octets to push tail (0 ... seg_tailroom)
>             *
>             * @return New segment data length, or -1 on an error
>             */
>         -int odp_packet_seg_push_tail(odp___packet_t pkt, int seg,
>         size_t len);
>         +int odp_packet_seg_push_tail(odp___packet_t pkt,
>         odp_packet_seg_t seg,
>         +                            size_t len);
>              /**
>             * Pull in segment tail
>             *
>             * Decrease segment data length.
>         + * Does not modify packet in case of an error.
>             *
>             * seg_data_len  -= len
>             *
>             * @param pkt  Packet handle
>         - * @param seg  Segment index (0 ... seg_count-1)
>         + * @param seg  Segment handle
>             * @param len  Number of octets to pull tail (0 ... seg_data_len)
>             *
>             * @return New segment data length, or -1 on an error
>             */
>         -int odp_packet_seg_pull_tail(odp___packet_t pkt, int seg,
>         size_t len);
>         +int odp_packet_seg_pull_tail(odp___packet_t pkt,
>         odp_packet_seg_t seg,
>         +                            size_t len);
>                #ifdef __cplusplus
>
>
>
Balasubramanian Manoharan July 8, 2014, 10:11 a.m. UTC | #4
Hi,

Addressing the segments by providing offset will be a time consuming
operation from the implementation point of view.

As lets say if there is a link list implementation of segments then when an
application provides only offset for addressing the segments, then the
implementation will have to iterate the list each time in-order to identify
the segment in which this offset is available.
But in the given proposal of passing a segment handle along with packet
handle the implementation can store the information of the current segment
within the segment handle.IMO

Regards,
bala


On 8 July 2014 15:15, Taras Kondratiuk <taras.kondratiuk@linaro.org> wrote:

> We haven't discussed approach suggested by Bill, where addressing is done
> via offset in a packet, but not via explicit segments.
> IMO for application it is the best case.
>
>
> On 07/08/2014 12:35 PM, Bala Manoharan wrote:
>
>> Hi Maxim,
>>
>> These APIs have incorporated the comments which were discussed in the
>> meeting.
>> There are no additional comments from my side.
>>
>> Regards,
>> Bala
>>
>>
>> On 8 July 2014 14:20, Maxim Uvarov <maxim.uvarov@linaro.org
>> <mailto:maxim.uvarov@linaro.org>> wrote:
>>
>>     Taras, Bala, no objection/review comments? ACK?
>>
>>     Maxim.
>>
>>
>>     On 07/04/2014 02:31 PM, Petri Savolainen wrote:
>>
>>         Replaced segment index with handle. Segment handle is always
>>         coupled with packet handle. Added functions to get segment
>>         handle from index and from current handle (iterate to next seg).
>>         Added segment info function.
>>
>>         Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org
>>         <mailto:petri.savolainen@linaro.org>>
>>         ---
>>            include/odp_packet.h | 103
>>         ++++++++++++++++++++++++++++++__++++++++++-----------
>>
>>            1 file changed, 82 insertions(+), 21 deletions(-)
>>
>>         diff --git a/include/odp_packet.h b/include/odp_packet.h
>>         index 8ae6410..ef4be9e 100644
>>         --- a/include/odp_packet.h
>>         +++ b/include/odp_packet.h
>>         @@ -34,6 +34,25 @@ typedef odp_buffer_t odp_packet_t;
>>                /**
>>         + * ODP packet segment handle
>>         + */
>>         +typedef int odp_packet_seg_t;
>>         +
>>         +/** Invalid packet segment */
>>         +#define ODP_PACKET_SEG_INVALID -1
>>         +
>>         +/**
>>         + * ODP packet segment info
>>         + */
>>         +typedef struct odp_packet_seg_info_t {
>>         +       void   *addr;      /**< Segment start address */
>>         +       size_t  size;      /**< Segment maximum data size */
>>         +       void   *data;      /**< Segment data address */
>>         +       size_t  data_len;  /**< Segment data length */
>>         +} odp_packet_seg_info_t;
>>         +
>>         +
>>         +/**
>>             * Initialize the packet
>>             *
>>             * Needs to be called if the user allocates a packet buffer,
>>         i.e. the packet
>>         @@ -242,44 +261,78 @@ int odp_packet_is_segmented(odp___packet_t
>>         pkt);
>>            int odp_packet_seg_count(odp___packet_t pkt);
>>
>>              /**
>>         + * Get segment by index
>>         + *
>>         + * @param pkt   Packet handle
>>         + * @param index Segment index (0 ... seg_count-1)
>>         + *
>>         + * @return Segment handle, or ODP_PACKET_SEG_INVALID on an error
>>         + */
>>         +odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int index);
>>         +
>>         +/**
>>         + * Get next segment
>>         + *
>>         + * @param pkt   Packet handle
>>         + * @param seg   Current segment handle
>>         + *
>>         + * @return Handle to next segment, or ODP_PACKET_SEG_INVALID on
>>         an error
>>         + */
>>         +odp_packet_seg_t odp_packet_seg_next(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg);
>>         +
>>         +/**
>>         + * Segment info
>>         + *
>>         + * Copies segment parameters into the info structure.
>>         + *
>>         + * @param pkt  Packet handle
>>         + * @param seg  Segment handle
>>         + * @param info Pointer to segment info structure
>>         + *
>>         + * @return 0 if successful, otherwise non-zero
>>         + */
>>         +int odp_packet_seg_info(odp___packet_t pkt, odp_packet_seg_t
>> seg,
>>
>>         +                       odp_packet_seg_info_t *info);
>>         +
>>         +/**
>>             * Segment start address
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             *
>>         - * @return Segment start address
>>         + * @return Segment start address, or NULL on an error
>>             */
>>         -void *odp_packet_seg_addr(odp___packet_t pkt, int seg);
>>         +void *odp_packet_seg_addr(odp___packet_t pkt, odp_packet_seg_t
>>
>>         seg);
>>              /**
>>             * Segment maximum data size
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             *
>>             * @return Segment maximum data size
>>             */
>>         -size_t odp_packet_seg_size(odp___packet_t pkt, int seg);
>>         +size_t odp_packet_seg_size(odp___packet_t pkt, odp_packet_seg_t
>>
>>         seg);
>>              /**
>>             * Segment data address
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             *
>>             * @return Segment data address
>>             */
>>         -void *odp_packet_seg_data(odp___packet_t pkt, int seg);
>>         +void *odp_packet_seg_data(odp___packet_t pkt, odp_packet_seg_t
>>
>>         seg);
>>              /**
>>             * Segment data length
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             *
>>             * @return Segment data length
>>             */
>>         -size_t odp_packet_seg_data_len(odp___packet_t pkt, int seg);
>>         +size_t odp_packet_seg_data_len(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg);
>>              /**
>>             * Segment headroom
>>         @@ -287,11 +340,11 @@ size_t
>>         odp_packet_seg_data_len(odp___packet_t pkt, int seg);
>>
>>             * seg_headroom = seg_data - seg_addr
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             *
>>             * @return Number of octets from seg_addr to seg_data
>>             */
>>         -size_t odp_packet_seg_headroom(odp___packet_t pkt, int seg);
>>         +size_t odp_packet_seg_headroom(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg);
>>              /**
>>             * Segment tailroom
>>         @@ -299,73 +352,81 @@ size_t
>>         odp_packet_seg_headroom(odp___packet_t pkt, int seg);
>>
>>             * seg_tailroom = seg_size - seg_headroom - seg_data_len
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             *
>>             * @return Number of octets from end-of-data to end-of-segment
>>             */
>>         -size_t odp_packet_seg_tailroom(odp___packet_t pkt, int seg);
>>         +size_t odp_packet_seg_tailroom(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg);
>>              /**
>>             * Push out segment head
>>             *
>>             * Push out segment data address (away from data) and
>>         increase data length.
>>         + * Does not modify packet in case of an error.
>>             *
>>             * seg_data     -= len
>>             * seg_data_len += len
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             * @param len  Number of octets to push head (0 ...
>> seg_headroom)
>>             *
>>             * @return New segment data address, or NULL on an error
>>             */
>>         -void *odp_packet_seg_push_head(odp___packet_t pkt, int seg,
>>         size_t len);
>>         +void *odp_packet_seg_push_head(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg,
>>         +                              size_t len);
>>              /**
>>             * Pull in segment head
>>             *
>>             * Pull in segment data address (towards data) and decrease
>>         data length.
>>         + * Does not modify packet in case of an error.
>>             *
>>             * seg_data     += len
>>             * seg_data_len -= len
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             * @param len  Number of octets to pull head (0 ...
>> seg_data_len)
>>             *
>>             * @return New segment data address, or NULL on an error
>>             */
>>         -void *odp_packet_seg_pull_head(odp___packet_t pkt, int seg,
>>         size_t len);
>>         +void *odp_packet_seg_pull_head(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg,
>>         +                              size_t len);
>>              /**
>>             * Push out segment tail
>>             *
>>             * Increase segment data length.
>>         + * Does not modify packet in case of an error.
>>             *
>>             * seg_data_len  += len
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             * @param len  Number of octets to push tail (0 ...
>> seg_tailroom)
>>             *
>>             * @return New segment data length, or -1 on an error
>>             */
>>         -int odp_packet_seg_push_tail(odp___packet_t pkt, int seg,
>>         size_t len);
>>         +int odp_packet_seg_push_tail(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg,
>>         +                            size_t len);
>>              /**
>>             * Pull in segment tail
>>             *
>>             * Decrease segment data length.
>>         + * Does not modify packet in case of an error.
>>             *
>>             * seg_data_len  -= len
>>             *
>>             * @param pkt  Packet handle
>>         - * @param seg  Segment index (0 ... seg_count-1)
>>         + * @param seg  Segment handle
>>             * @param len  Number of octets to pull tail (0 ...
>> seg_data_len)
>>             *
>>             * @return New segment data length, or -1 on an error
>>             */
>>         -int odp_packet_seg_pull_tail(odp___packet_t pkt, int seg,
>>         size_t len);
>>         +int odp_packet_seg_pull_tail(odp___packet_t pkt,
>>
>>         odp_packet_seg_t seg,
>>         +                            size_t len);
>>                #ifdef __cplusplus
>>
>>
>>
>>
>
Taras Kondratiuk July 8, 2014, 10:18 a.m. UTC | #5
On 07/08/2014 01:11 PM, Bala Manoharan wrote:
>
>
> Hi,
>
> Addressing the segments by providing offset will be a time consuming
> operation from the implementation point of view.
>
> As lets say if there is a link list implementation of segments then when
> an application provides only offset for addressing the segments, then
> the implementation will have to iterate the list each time in-order to
> identify the segment in which this offset is available.
> But in the given proposal of passing a segment handle along with packet
> handle the implementation can store the information of the current
> segment within the segment handle.IMO

I was thinking about this, and IMO implementation can be optimized to 
cache the last accessed segment in TLS, so if user does sequential 
access implementation won't traverse a whole list again.

>
> Regards,
> bala
>
>
> On 8 July 2014 15:15, Taras Kondratiuk <taras.kondratiuk@linaro.org
> <mailto:taras.kondratiuk@linaro.org>> wrote:
>
>     We haven't discussed approach suggested by Bill, where addressing is
>     done via offset in a packet, but not via explicit segments.
>     IMO for application it is the best case.
>
>
>     On 07/08/2014 12:35 PM, Bala Manoharan wrote:
>
>         Hi Maxim,
>
>         These APIs have incorporated the comments which were discussed
>         in the
>         meeting.
>         There are no additional comments from my side.
>
>         Regards,
>         Bala
>
>
>         On 8 July 2014 14:20, Maxim Uvarov <maxim.uvarov@linaro.org
>         <mailto:maxim.uvarov@linaro.org>
>         <mailto:maxim.uvarov@linaro.__org
>         <mailto:maxim.uvarov@linaro.org>>> wrote:
>
>              Taras, Bala, no objection/review comments? ACK?
>
>              Maxim.
>
>
>              On 07/04/2014 02:31 PM, Petri Savolainen wrote:
>
>                  Replaced segment index with handle. Segment handle is
>         always
>                  coupled with packet handle. Added functions to get segment
>                  handle from index and from current handle (iterate to
>         next seg).
>                  Added segment info function.
>
>                  Signed-off-by: Petri Savolainen
>         <petri.savolainen@linaro.org <mailto:petri.savolainen@linaro.org>
>                  <mailto:petri.savolainen@__linaro.org
>         <mailto:petri.savolainen@linaro.org>>>
>                  ---
>                     include/odp_packet.h | 103
>                  ++++++++++++++++++++++++++++++____++++++++++-----------
>
>                     1 file changed, 82 insertions(+), 21 deletions(-)
>
>                  diff --git a/include/odp_packet.h b/include/odp_packet.h
>                  index 8ae6410..ef4be9e 100644
>                  --- a/include/odp_packet.h
>                  +++ b/include/odp_packet.h
>                  @@ -34,6 +34,25 @@ typedef odp_buffer_t odp_packet_t;
>                         /**
>                  + * ODP packet segment handle
>                  + */
>                  +typedef int odp_packet_seg_t;
>                  +
>                  +/** Invalid packet segment */
>                  +#define ODP_PACKET_SEG_INVALID -1
>                  +
>                  +/**
>                  + * ODP packet segment info
>                  + */
>                  +typedef struct odp_packet_seg_info_t {
>                  +       void   *addr;      /**< Segment start address */
>                  +       size_t  size;      /**< Segment maximum data
>         size */
>                  +       void   *data;      /**< Segment data address */
>                  +       size_t  data_len;  /**< Segment data length */
>                  +} odp_packet_seg_info_t;
>                  +
>                  +
>                  +/**
>                      * Initialize the packet
>                      *
>                      * Needs to be called if the user allocates a packet
>         buffer,
>                  i.e. the packet
>                  @@ -242,44 +261,78 @@ int
>         odp_packet_is_segmented(odp_____packet_t
>                  pkt);
>                     int odp_packet_seg_count(odp_____packet_t pkt);
>
>                       /**
>                  + * Get segment by index
>                  + *
>                  + * @param pkt   Packet handle
>                  + * @param index Segment index (0 ... seg_count-1)
>                  + *
>                  + * @return Segment handle, or ODP_PACKET_SEG_INVALID
>         on an error
>                  + */
>                  +odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int
>         index);
>                  +
>                  +/**
>                  + * Get next segment
>                  + *
>                  + * @param pkt   Packet handle
>                  + * @param seg   Current segment handle
>                  + *
>                  + * @return Handle to next segment, or
>         ODP_PACKET_SEG_INVALID on
>                  an error
>                  + */
>                  +odp_packet_seg_t odp_packet_seg_next(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg);
>                  +
>                  +/**
>                  + * Segment info
>                  + *
>                  + * Copies segment parameters into the info structure.
>                  + *
>                  + * @param pkt  Packet handle
>                  + * @param seg  Segment handle
>                  + * @param info Pointer to segment info structure
>                  + *
>                  + * @return 0 if successful, otherwise non-zero
>                  + */
>                  +int odp_packet_seg_info(odp_____packet_t pkt,
>         odp_packet_seg_t seg,
>
>                  +                       odp_packet_seg_info_t *info);
>                  +
>                  +/**
>                      * Segment start address
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      *
>                  - * @return Segment start address
>                  + * @return Segment start address, or NULL on an error
>                      */
>                  -void *odp_packet_seg_addr(odp_____packet_t pkt, int seg);
>                  +void *odp_packet_seg_addr(odp_____packet_t pkt,
>         odp_packet_seg_t
>
>                  seg);
>                       /**
>                      * Segment maximum data size
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      *
>                      * @return Segment maximum data size
>                      */
>                  -size_t odp_packet_seg_size(odp_____packet_t pkt, int seg);
>                  +size_t odp_packet_seg_size(odp_____packet_t pkt,
>         odp_packet_seg_t
>
>                  seg);
>                       /**
>                      * Segment data address
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      *
>                      * @return Segment data address
>                      */
>                  -void *odp_packet_seg_data(odp_____packet_t pkt, int seg);
>                  +void *odp_packet_seg_data(odp_____packet_t pkt,
>         odp_packet_seg_t
>
>                  seg);
>                       /**
>                      * Segment data length
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      *
>                      * @return Segment data length
>                      */
>                  -size_t odp_packet_seg_data_len(odp_____packet_t pkt,
>         int seg);
>                  +size_t odp_packet_seg_data_len(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg);
>                       /**
>                      * Segment headroom
>                  @@ -287,11 +340,11 @@ size_t
>                  odp_packet_seg_data_len(odp_____packet_t pkt, int seg);
>
>                      * seg_headroom = seg_data - seg_addr
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      *
>                      * @return Number of octets from seg_addr to seg_data
>                      */
>                  -size_t odp_packet_seg_headroom(odp_____packet_t pkt,
>         int seg);
>                  +size_t odp_packet_seg_headroom(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg);
>                       /**
>                      * Segment tailroom
>                  @@ -299,73 +352,81 @@ size_t
>                  odp_packet_seg_headroom(odp_____packet_t pkt, int seg);
>
>                      * seg_tailroom = seg_size - seg_headroom - seg_data_len
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      *
>                      * @return Number of octets from end-of-data to
>         end-of-segment
>                      */
>                  -size_t odp_packet_seg_tailroom(odp_____packet_t pkt,
>         int seg);
>                  +size_t odp_packet_seg_tailroom(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg);
>                       /**
>                      * Push out segment head
>                      *
>                      * Push out segment data address (away from data) and
>                  increase data length.
>                  + * Does not modify packet in case of an error.
>                      *
>                      * seg_data     -= len
>                      * seg_data_len += len
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      * @param len  Number of octets to push head (0 ...
>         seg_headroom)
>                      *
>                      * @return New segment data address, or NULL on an error
>                      */
>                  -void *odp_packet_seg_push_head(odp_____packet_t pkt,
>         int seg,
>                  size_t len);
>                  +void *odp_packet_seg_push_head(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg,
>                  +                              size_t len);
>                       /**
>                      * Pull in segment head
>                      *
>                      * Pull in segment data address (towards data) and
>         decrease
>                  data length.
>                  + * Does not modify packet in case of an error.
>                      *
>                      * seg_data     += len
>                      * seg_data_len -= len
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      * @param len  Number of octets to pull head (0 ...
>         seg_data_len)
>                      *
>                      * @return New segment data address, or NULL on an error
>                      */
>                  -void *odp_packet_seg_pull_head(odp_____packet_t pkt,
>         int seg,
>                  size_t len);
>                  +void *odp_packet_seg_pull_head(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg,
>                  +                              size_t len);
>                       /**
>                      * Push out segment tail
>                      *
>                      * Increase segment data length.
>                  + * Does not modify packet in case of an error.
>                      *
>                      * seg_data_len  += len
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      * @param len  Number of octets to push tail (0 ...
>         seg_tailroom)
>                      *
>                      * @return New segment data length, or -1 on an error
>                      */
>                  -int odp_packet_seg_push_tail(odp_____packet_t pkt, int
>         seg,
>                  size_t len);
>                  +int odp_packet_seg_push_tail(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg,
>                  +                            size_t len);
>                       /**
>                      * Pull in segment tail
>                      *
>                      * Decrease segment data length.
>                  + * Does not modify packet in case of an error.
>                      *
>                      * seg_data_len  -= len
>                      *
>                      * @param pkt  Packet handle
>                  - * @param seg  Segment index (0 ... seg_count-1)
>                  + * @param seg  Segment handle
>                      * @param len  Number of octets to pull tail (0 ...
>         seg_data_len)
>                      *
>                      * @return New segment data length, or -1 on an error
>                      */
>                  -int odp_packet_seg_pull_tail(odp_____packet_t pkt, int
>         seg,
>                  size_t len);
>                  +int odp_packet_seg_pull_tail(odp_____packet_t pkt,
>
>                  odp_packet_seg_t seg,
>                  +                            size_t len);
>                         #ifdef __cplusplus
>
>
>
>
>
Balasubramanian Manoharan July 8, 2014, 10:37 a.m. UTC | #6
Hi,

Yes, but that will require additional space to be added in the packet
header since we need to maintain the cache per packet.
Actually both the suggestions are similar the application either modifies
the offset to point the next segment or gets an segment handle to point the
next segment.
IMO sequential access by the application can be better handled by the
implementation if the application passes the segment handle. As in this
case the meta-data will be handled by the implementation rather than the
application.

Regards,
Bala


On 8 July 2014 15:48, Taras Kondratiuk <taras.kondratiuk@linaro.org> wrote:

> On 07/08/2014 01:11 PM, Bala Manoharan wrote:
>
>>
>>
>> Hi,
>>
>> Addressing the segments by providing offset will be a time consuming
>> operation from the implementation point of view.
>>
>> As lets say if there is a link list implementation of segments then when
>> an application provides only offset for addressing the segments, then
>> the implementation will have to iterate the list each time in-order to
>> identify the segment in which this offset is available.
>> But in the given proposal of passing a segment handle along with packet
>> handle the implementation can store the information of the current
>> segment within the segment handle.IMO
>>
>
> I was thinking about this, and IMO implementation can be optimized to
> cache the last accessed segment in TLS, so if user does sequential access
> implementation won't traverse a whole list again.
>
>
>> Regards,
>> bala
>>
>>
>> On 8 July 2014 15:15, Taras Kondratiuk <taras.kondratiuk@linaro.org
>> <mailto:taras.kondratiuk@linaro.org>> wrote:
>>
>>     We haven't discussed approach suggested by Bill, where addressing is
>>     done via offset in a packet, but not via explicit segments.
>>     IMO for application it is the best case.
>>
>>
>>     On 07/08/2014 12:35 PM, Bala Manoharan wrote:
>>
>>         Hi Maxim,
>>
>>         These APIs have incorporated the comments which were discussed
>>         in the
>>         meeting.
>>         There are no additional comments from my side.
>>
>>         Regards,
>>         Bala
>>
>>
>>         On 8 July 2014 14:20, Maxim Uvarov <maxim.uvarov@linaro.org
>>         <mailto:maxim.uvarov@linaro.org>
>>         <mailto:maxim.uvarov@linaro.__org
>>
>>         <mailto:maxim.uvarov@linaro.org>>> wrote:
>>
>>              Taras, Bala, no objection/review comments? ACK?
>>
>>              Maxim.
>>
>>
>>              On 07/04/2014 02:31 PM, Petri Savolainen wrote:
>>
>>                  Replaced segment index with handle. Segment handle is
>>         always
>>                  coupled with packet handle. Added functions to get
>> segment
>>                  handle from index and from current handle (iterate to
>>         next seg).
>>                  Added segment info function.
>>
>>                  Signed-off-by: Petri Savolainen
>>         <petri.savolainen@linaro.org <mailto:petri.savolainen@linaro.org>
>>                  <mailto:petri.savolainen@__linaro.org
>>
>>         <mailto:petri.savolainen@linaro.org>>>
>>                  ---
>>                     include/odp_packet.h | 103
>>                  ++++++++++++++++++++++++++++++____++++++++++-----------
>>
>>
>>                     1 file changed, 82 insertions(+), 21 deletions(-)
>>
>>                  diff --git a/include/odp_packet.h b/include/odp_packet.h
>>                  index 8ae6410..ef4be9e 100644
>>                  --- a/include/odp_packet.h
>>                  +++ b/include/odp_packet.h
>>                  @@ -34,6 +34,25 @@ typedef odp_buffer_t odp_packet_t;
>>                         /**
>>                  + * ODP packet segment handle
>>                  + */
>>                  +typedef int odp_packet_seg_t;
>>                  +
>>                  +/** Invalid packet segment */
>>                  +#define ODP_PACKET_SEG_INVALID -1
>>                  +
>>                  +/**
>>                  + * ODP packet segment info
>>                  + */
>>                  +typedef struct odp_packet_seg_info_t {
>>                  +       void   *addr;      /**< Segment start address */
>>                  +       size_t  size;      /**< Segment maximum data
>>         size */
>>                  +       void   *data;      /**< Segment data address */
>>                  +       size_t  data_len;  /**< Segment data length */
>>                  +} odp_packet_seg_info_t;
>>                  +
>>                  +
>>                  +/**
>>                      * Initialize the packet
>>                      *
>>                      * Needs to be called if the user allocates a packet
>>         buffer,
>>                  i.e. the packet
>>                  @@ -242,44 +261,78 @@ int
>>         odp_packet_is_segmented(odp_____packet_t
>>                  pkt);
>>                     int odp_packet_seg_count(odp_____packet_t pkt);
>>
>>
>>                       /**
>>                  + * Get segment by index
>>                  + *
>>                  + * @param pkt   Packet handle
>>                  + * @param index Segment index (0 ... seg_count-1)
>>                  + *
>>                  + * @return Segment handle, or ODP_PACKET_SEG_INVALID
>>         on an error
>>                  + */
>>                  +odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int
>>         index);
>>                  +
>>                  +/**
>>                  + * Get next segment
>>                  + *
>>                  + * @param pkt   Packet handle
>>                  + * @param seg   Current segment handle
>>                  + *
>>                  + * @return Handle to next segment, or
>>         ODP_PACKET_SEG_INVALID on
>>                  an error
>>                  + */
>>                  +odp_packet_seg_t odp_packet_seg_next(odp_____packet_t
>> pkt,
>>
>>
>>                  odp_packet_seg_t seg);
>>                  +
>>                  +/**
>>                  + * Segment info
>>                  + *
>>                  + * Copies segment parameters into the info structure.
>>                  + *
>>                  + * @param pkt  Packet handle
>>                  + * @param seg  Segment handle
>>                  + * @param info Pointer to segment info structure
>>                  + *
>>                  + * @return 0 if successful, otherwise non-zero
>>                  + */
>>                  +int odp_packet_seg_info(odp_____packet_t pkt,
>>
>>         odp_packet_seg_t seg,
>>
>>                  +                       odp_packet_seg_info_t *info);
>>                  +
>>                  +/**
>>                      * Segment start address
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      *
>>                  - * @return Segment start address
>>                  + * @return Segment start address, or NULL on an error
>>                      */
>>                  -void *odp_packet_seg_addr(odp_____packet_t pkt, int
>> seg);
>>                  +void *odp_packet_seg_addr(odp_____packet_t pkt,
>>
>>         odp_packet_seg_t
>>
>>                  seg);
>>                       /**
>>                      * Segment maximum data size
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      *
>>                      * @return Segment maximum data size
>>                      */
>>                  -size_t odp_packet_seg_size(odp_____packet_t pkt, int
>> seg);
>>                  +size_t odp_packet_seg_size(odp_____packet_t pkt,
>>
>>         odp_packet_seg_t
>>
>>                  seg);
>>                       /**
>>                      * Segment data address
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      *
>>                      * @return Segment data address
>>                      */
>>                  -void *odp_packet_seg_data(odp_____packet_t pkt, int
>> seg);
>>                  +void *odp_packet_seg_data(odp_____packet_t pkt,
>>
>>         odp_packet_seg_t
>>
>>                  seg);
>>                       /**
>>                      * Segment data length
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      *
>>                      * @return Segment data length
>>                      */
>>                  -size_t odp_packet_seg_data_len(odp_____packet_t pkt,
>>         int seg);
>>                  +size_t odp_packet_seg_data_len(odp_____packet_t pkt,
>>
>>
>>                  odp_packet_seg_t seg);
>>                       /**
>>                      * Segment headroom
>>                  @@ -287,11 +340,11 @@ size_t
>>                  odp_packet_seg_data_len(odp_____packet_t pkt, int seg);
>>
>>
>>                      * seg_headroom = seg_data - seg_addr
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      *
>>                      * @return Number of octets from seg_addr to seg_data
>>                      */
>>                  -size_t odp_packet_seg_headroom(odp_____packet_t pkt,
>>         int seg);
>>                  +size_t odp_packet_seg_headroom(odp_____packet_t pkt,
>>
>>
>>                  odp_packet_seg_t seg);
>>                       /**
>>                      * Segment tailroom
>>                  @@ -299,73 +352,81 @@ size_t
>>                  odp_packet_seg_headroom(odp_____packet_t pkt, int seg);
>>
>>
>>                      * seg_tailroom = seg_size - seg_headroom -
>> seg_data_len
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      *
>>                      * @return Number of octets from end-of-data to
>>         end-of-segment
>>                      */
>>                  -size_t odp_packet_seg_tailroom(odp_____packet_t pkt,
>>         int seg);
>>                  +size_t odp_packet_seg_tailroom(odp_____packet_t pkt,
>>
>>
>>                  odp_packet_seg_t seg);
>>                       /**
>>                      * Push out segment head
>>                      *
>>                      * Push out segment data address (away from data) and
>>                  increase data length.
>>                  + * Does not modify packet in case of an error.
>>                      *
>>                      * seg_data     -= len
>>                      * seg_data_len += len
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      * @param len  Number of octets to push head (0 ...
>>         seg_headroom)
>>                      *
>>                      * @return New segment data address, or NULL on an
>> error
>>                      */
>>                  -void *odp_packet_seg_push_head(odp_____packet_t pkt,
>>         int seg,
>>                  size_t len);
>>                  +void *odp_packet_seg_push_head(odp_____packet_t pkt,
>>
>>
>>                  odp_packet_seg_t seg,
>>                  +                              size_t len);
>>                       /**
>>                      * Pull in segment head
>>                      *
>>                      * Pull in segment data address (towards data) and
>>         decrease
>>                  data length.
>>                  + * Does not modify packet in case of an error.
>>                      *
>>                      * seg_data     += len
>>                      * seg_data_len -= len
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      * @param len  Number of octets to pull head (0 ...
>>         seg_data_len)
>>                      *
>>                      * @return New segment data address, or NULL on an
>> error
>>                      */
>>                  -void *odp_packet_seg_pull_head(odp_____packet_t pkt,
>>         int seg,
>>                  size_t len);
>>                  +void *odp_packet_seg_pull_head(odp_____packet_t pkt,
>>
>>
>>                  odp_packet_seg_t seg,
>>                  +                              size_t len);
>>                       /**
>>                      * Push out segment tail
>>                      *
>>                      * Increase segment data length.
>>                  + * Does not modify packet in case of an error.
>>                      *
>>                      * seg_data_len  += len
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      * @param len  Number of octets to push tail (0 ...
>>         seg_tailroom)
>>                      *
>>                      * @return New segment data length, or -1 on an error
>>                      */
>>                  -int odp_packet_seg_push_tail(odp_____packet_t pkt, int
>>         seg,
>>                  size_t len);
>>                  +int odp_packet_seg_push_tail(odp_____packet_t pkt,
>>
>>
>>                  odp_packet_seg_t seg,
>>                  +                            size_t len);
>>                       /**
>>                      * Pull in segment tail
>>                      *
>>                      * Decrease segment data length.
>>                  + * Does not modify packet in case of an error.
>>                      *
>>                      * seg_data_len  -= len
>>                      *
>>                      * @param pkt  Packet handle
>>                  - * @param seg  Segment index (0 ... seg_count-1)
>>                  + * @param seg  Segment handle
>>                      * @param len  Number of octets to pull tail (0 ...
>>         seg_data_len)
>>                      *
>>                      * @return New segment data length, or -1 on an error
>>                      */
>>                  -int odp_packet_seg_pull_tail(odp_____packet_t pkt, int
>>         seg,
>>                  size_t len);
>>                  +int odp_packet_seg_pull_tail(odp_____packet_t pkt,
>>
>>
>>                  odp_packet_seg_t seg,
>>                  +                            size_t len);
>>                         #ifdef __cplusplus
>>
>>
>>
>>
>>
>>
>
Taras Kondratiuk July 8, 2014, 11:13 a.m. UTC | #7
On 07/08/2014 01:37 PM, Bala Manoharan wrote:
> Hi,
>
> Yes, but that will require additional space to be added in the packet
> header since we need to maintain the cache per packet.
> Actually both the suggestions are similar the application either
> modifies the offset to point the next segment or gets an segment handle
> to point the next segment.
> IMO sequential access by the application can be better handled by the
> implementation if the application passes the segment handle. As in this
> case the meta-data will be handled by the implementation rather than the
> application.

Segment handlers were proposed to optimize linked list implementation 
based on the idea that in most cases app will iterate sequentially over 
segments. But now I'm thinking that app is interested in *offset*, so it 
usually will iterate over segments just to reach some offset.
If app is able to request for offset directly, then implementation can
somehow optimize this request.

I'm fine with a current implementation, but 'offset' approach looks more 
app-centered, simpler and abstracted from implementation details.

>
>
> On 8 July 2014 15:48, Taras Kondratiuk <taras.kondratiuk@linaro.org
> <mailto:taras.kondratiuk@linaro.org>> wrote:
>
>     On 07/08/2014 01:11 PM, Bala Manoharan wrote:
>
>
>
>         Hi,
>
>         Addressing the segments by providing offset will be a time consuming
>         operation from the implementation point of view.
>
>         As lets say if there is a link list implementation of segments
>         then when
>         an application provides only offset for addressing the segments,
>         then
>         the implementation will have to iterate the list each time
>         in-order to
>         identify the segment in which this offset is available.
>         But in the given proposal of passing a segment handle along with
>         packet
>         handle the implementation can store the information of the current
>         segment within the segment handle.IMO
>
>
>     I was thinking about this, and IMO implementation can be optimized
>     to cache the last accessed segment in TLS, so if user does
>     sequential access implementation won't traverse a whole list again.
>
>
>         Regards,
>         bala
>
>
>         On 8 July 2014 15:15, Taras Kondratiuk
>         <taras.kondratiuk@linaro.org <mailto:taras.kondratiuk@linaro.org>
>         <mailto:taras.kondratiuk@__linaro.org
>         <mailto:taras.kondratiuk@linaro.org>>> wrote:
>
>              We haven't discussed approach suggested by Bill, where
>         addressing is
>              done via offset in a packet, but not via explicit segments.
>              IMO for application it is the best case.
>
>
>              On 07/08/2014 12:35 PM, Bala Manoharan wrote:
>
>                  Hi Maxim,
>
>                  These APIs have incorporated the comments which were
>         discussed
>                  in the
>                  meeting.
>                  There are no additional comments from my side.
>
>                  Regards,
>                  Bala
>
>
>                  On 8 July 2014 14:20, Maxim Uvarov
>         <maxim.uvarov@linaro.org <mailto:maxim.uvarov@linaro.org>
>                  <mailto:maxim.uvarov@linaro.__org
>         <mailto:maxim.uvarov@linaro.org>>
>                  <mailto:maxim.uvarov@linaro.
>         <mailto:maxim.uvarov@linaro.>____org
>
>                  <mailto:maxim.uvarov@linaro.__org
>         <mailto:maxim.uvarov@linaro.org>>>> wrote:
>
>                       Taras, Bala, no objection/review comments? ACK?
>
>                       Maxim.
>
>
>                       On 07/04/2014 02:31 PM, Petri Savolainen wrote:
>
>                           Replaced segment index with handle. Segment
>         handle is
>                  always
>                           coupled with packet handle. Added functions to
>         get segment
>                           handle from index and from current handle
>         (iterate to
>                  next seg).
>                           Added segment info function.
>
>                           Signed-off-by: Petri Savolainen
>                  <petri.savolainen@linaro.org
>         <mailto:petri.savolainen@linaro.org>
>         <mailto:petri.savolainen@__linaro.org
>         <mailto:petri.savolainen@linaro.org>>
>                           <mailto:petri.savolainen@
>         <mailto:petri.savolainen@>__lin__aro.org <http://linaro.org>
>
>                  <mailto:petri.savolainen@__linaro.org
>         <mailto:petri.savolainen@linaro.org>>>>
>                           ---
>                              include/odp_packet.h | 103
>
>           ++++++++++++++++++++++++++++++______++++++++++-----------
>
>
>                              1 file changed, 82 insertions(+), 21
>         deletions(-)
>
>                           diff --git a/include/odp_packet.h
>         b/include/odp_packet.h
>                           index 8ae6410..ef4be9e 100644
>                           --- a/include/odp_packet.h
>                           +++ b/include/odp_packet.h
>                           @@ -34,6 +34,25 @@ typedef odp_buffer_t
>         odp_packet_t;
>                                  /**
>                           + * ODP packet segment handle
>                           + */
>                           +typedef int odp_packet_seg_t;
>                           +
>                           +/** Invalid packet segment */
>                           +#define ODP_PACKET_SEG_INVALID -1
>                           +
>                           +/**
>                           + * ODP packet segment info
>                           + */
>                           +typedef struct odp_packet_seg_info_t {
>                           +       void   *addr;      /**< Segment start
>         address */
>                           +       size_t  size;      /**< Segment
>         maximum data
>                  size */
>                           +       void   *data;      /**< Segment data
>         address */
>                           +       size_t  data_len;  /**< Segment data
>         length */
>                           +} odp_packet_seg_info_t;
>                           +
>                           +
>                           +/**
>                               * Initialize the packet
>                               *
>                               * Needs to be called if the user allocates
>         a packet
>                  buffer,
>                           i.e. the packet
>                           @@ -242,44 +261,78 @@ int
>                  odp_packet_is_segmented(odp_______packet_t
>                           pkt);
>                              int odp_packet_seg_count(odp_______packet_t
>         pkt);
>
>
>                                /**
>                           + * Get segment by index
>                           + *
>                           + * @param pkt   Packet handle
>                           + * @param index Segment index (0 ... seg_count-1)
>                           + *
>                           + * @return Segment handle, or
>         ODP_PACKET_SEG_INVALID
>                  on an error
>                           + */
>                           +odp_packet_seg_t odp_packet_seg(odp_packet_t
>         pkt, int
>                  index);
>                           +
>                           +/**
>                           + * Get next segment
>                           + *
>                           + * @param pkt   Packet handle
>                           + * @param seg   Current segment handle
>                           + *
>                           + * @return Handle to next segment, or
>                  ODP_PACKET_SEG_INVALID on
>                           an error
>                           + */
>                           +odp_packet_seg_t
>         odp_packet_seg_next(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg);
>                           +
>                           +/**
>                           + * Segment info
>                           + *
>                           + * Copies segment parameters into the info
>         structure.
>                           + *
>                           + * @param pkt  Packet handle
>                           + * @param seg  Segment handle
>                           + * @param info Pointer to segment info structure
>                           + *
>                           + * @return 0 if successful, otherwise non-zero
>                           + */
>                           +int odp_packet_seg_info(odp_______packet_t pkt,
>
>                  odp_packet_seg_t seg,
>
>                           +                       odp_packet_seg_info_t
>         *info);
>                           +
>                           +/**
>                               * Segment start address
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               *
>                           - * @return Segment start address
>                           + * @return Segment start address, or NULL on
>         an error
>                               */
>                           -void *odp_packet_seg_addr(odp_______packet_t
>         pkt, int seg);
>                           +void *odp_packet_seg_addr(odp_______packet_t pkt,
>
>                  odp_packet_seg_t
>
>                           seg);
>                                /**
>                               * Segment maximum data size
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               *
>                               * @return Segment maximum data size
>                               */
>                           -size_t odp_packet_seg_size(odp_______packet_t
>         pkt, int seg);
>                           +size_t odp_packet_seg_size(odp_______packet_t
>         pkt,
>
>                  odp_packet_seg_t
>
>                           seg);
>                                /**
>                               * Segment data address
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               *
>                               * @return Segment data address
>                               */
>                           -void *odp_packet_seg_data(odp_______packet_t
>         pkt, int seg);
>                           +void *odp_packet_seg_data(odp_______packet_t pkt,
>
>                  odp_packet_seg_t
>
>                           seg);
>                                /**
>                               * Segment data length
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               *
>                               * @return Segment data length
>                               */
>                           -size_t
>         odp_packet_seg_data_len(odp_______packet_t pkt,
>                  int seg);
>                           +size_t
>         odp_packet_seg_data_len(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg);
>                                /**
>                               * Segment headroom
>                           @@ -287,11 +340,11 @@ size_t
>                           odp_packet_seg_data_len(odp_______packet_t
>         pkt, int seg);
>
>
>                               * seg_headroom = seg_data - seg_addr
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               *
>                               * @return Number of octets from seg_addr
>         to seg_data
>                               */
>                           -size_t
>         odp_packet_seg_headroom(odp_______packet_t pkt,
>                  int seg);
>                           +size_t
>         odp_packet_seg_headroom(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg);
>                                /**
>                               * Segment tailroom
>                           @@ -299,73 +352,81 @@ size_t
>                           odp_packet_seg_headroom(odp_______packet_t
>         pkt, int seg);
>
>
>                               * seg_tailroom = seg_size - seg_headroom -
>         seg_data_len
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               *
>                               * @return Number of octets from end-of-data to
>                  end-of-segment
>                               */
>                           -size_t
>         odp_packet_seg_tailroom(odp_______packet_t pkt,
>                  int seg);
>                           +size_t
>         odp_packet_seg_tailroom(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg);
>                                /**
>                               * Push out segment head
>                               *
>                               * Push out segment data address (away from
>         data) and
>                           increase data length.
>                           + * Does not modify packet in case of an error.
>                               *
>                               * seg_data     -= len
>                               * seg_data_len += len
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               * @param len  Number of octets to push
>         head (0 ...
>                  seg_headroom)
>                               *
>                               * @return New segment data address, or
>         NULL on an error
>                               */
>                           -void
>         *odp_packet_seg_push_head(odp_______packet_t pkt,
>                  int seg,
>                           size_t len);
>                           +void
>         *odp_packet_seg_push_head(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg,
>                           +                              size_t len);
>                                /**
>                               * Pull in segment head
>                               *
>                               * Pull in segment data address (towards
>         data) and
>                  decrease
>                           data length.
>                           + * Does not modify packet in case of an error.
>                               *
>                               * seg_data     += len
>                               * seg_data_len -= len
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               * @param len  Number of octets to pull
>         head (0 ...
>                  seg_data_len)
>                               *
>                               * @return New segment data address, or
>         NULL on an error
>                               */
>                           -void
>         *odp_packet_seg_pull_head(odp_______packet_t pkt,
>                  int seg,
>                           size_t len);
>                           +void
>         *odp_packet_seg_pull_head(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg,
>                           +                              size_t len);
>                                /**
>                               * Push out segment tail
>                               *
>                               * Increase segment data length.
>                           + * Does not modify packet in case of an error.
>                               *
>                               * seg_data_len  += len
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               * @param len  Number of octets to push
>         tail (0 ...
>                  seg_tailroom)
>                               *
>                               * @return New segment data length, or -1
>         on an error
>                               */
>                           -int
>         odp_packet_seg_push_tail(odp_______packet_t pkt, int
>                  seg,
>                           size_t len);
>                           +int
>         odp_packet_seg_push_tail(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg,
>                           +                            size_t len);
>                                /**
>                               * Pull in segment tail
>                               *
>                               * Decrease segment data length.
>                           + * Does not modify packet in case of an error.
>                               *
>                               * seg_data_len  -= len
>                               *
>                               * @param pkt  Packet handle
>                           - * @param seg  Segment index (0 ... seg_count-1)
>                           + * @param seg  Segment handle
>                               * @param len  Number of octets to pull
>         tail (0 ...
>                  seg_data_len)
>                               *
>                               * @return New segment data length, or -1
>         on an error
>                               */
>                           -int
>         odp_packet_seg_pull_tail(odp_______packet_t pkt, int
>                  seg,
>                           size_t len);
>                           +int
>         odp_packet_seg_pull_tail(odp_______packet_t pkt,
>
>
>                           odp_packet_seg_t seg,
>                           +                            size_t len);
>                                  #ifdef __cplusplus
>
>
>
>
>
>
>
Bill Fischofer July 8, 2014, 12:24 p.m. UTC | #8
Well, I'm glad to see the offset approach has some appeal.  :)

Seriously, the point is that in ODP we want the APIs to be
application-centric but also be mindful of efficient implementation
considerations.  In the case of buffer access the key is that in the data
plane it is very atypical for SW to need to iterate over an entire buffer.
 When considering something like crypto, then that is the norm, but here it
isn't SW that's doing that but a crypto engine which is typically HW and
accessing the native HW buffer structures directly using its own mechanisms
that are optimal.  The same would be true for a pattern matching engine,
which is what you'd want to have for any serious DPI (deep packet
inspection) work in the data plane.  In the data plane, SW is most
interested in packet headers, not payload, and these are what is in the
first segment.

The principle of orthogonality is that interfaces should specify the what
and leave the implementation the freedom to supply the how behind each
interface.  When those blur then you invariably get a lot of asymmetries
where some implementations map very well to the API because they just
happen to match the "how" of that the API is using while others have a very
difficult time doing this.  That's one of the things we want to avoid with
ODP.


On Tue, Jul 8, 2014 at 6:13 AM, Taras Kondratiuk <
taras.kondratiuk@linaro.org> wrote:

> On 07/08/2014 01:37 PM, Bala Manoharan wrote:
>
>> Hi,
>>
>> Yes, but that will require additional space to be added in the packet
>> header since we need to maintain the cache per packet.
>> Actually both the suggestions are similar the application either
>> modifies the offset to point the next segment or gets an segment handle
>> to point the next segment.
>> IMO sequential access by the application can be better handled by the
>> implementation if the application passes the segment handle. As in this
>> case the meta-data will be handled by the implementation rather than the
>> application.
>>
>
> Segment handlers were proposed to optimize linked list implementation
> based on the idea that in most cases app will iterate sequentially over
> segments. But now I'm thinking that app is interested in *offset*, so it
> usually will iterate over segments just to reach some offset.
> If app is able to request for offset directly, then implementation can
> somehow optimize this request.
>
> I'm fine with a current implementation, but 'offset' approach looks more
> app-centered, simpler and abstracted from implementation details.
>
>
>>
>> On 8 July 2014 15:48, Taras Kondratiuk <taras.kondratiuk@linaro.org
>> <mailto:taras.kondratiuk@linaro.org>> wrote:
>>
>>     On 07/08/2014 01:11 PM, Bala Manoharan wrote:
>>
>>
>>
>>         Hi,
>>
>>         Addressing the segments by providing offset will be a time
>> consuming
>>         operation from the implementation point of view.
>>
>>         As lets say if there is a link list implementation of segments
>>         then when
>>         an application provides only offset for addressing the segments,
>>         then
>>         the implementation will have to iterate the list each time
>>         in-order to
>>         identify the segment in which this offset is available.
>>         But in the given proposal of passing a segment handle along with
>>         packet
>>         handle the implementation can store the information of the current
>>         segment within the segment handle.IMO
>>
>>
>>     I was thinking about this, and IMO implementation can be optimized
>>     to cache the last accessed segment in TLS, so if user does
>>     sequential access implementation won't traverse a whole list again.
>>
>>
>>         Regards,
>>         bala
>>
>>
>>         On 8 July 2014 15:15, Taras Kondratiuk
>>         <taras.kondratiuk@linaro.org <mailto:taras.kondratiuk@linaro.org>
>>         <mailto:taras.kondratiuk@__linaro.org
>>
>>         <mailto:taras.kondratiuk@linaro.org>>> wrote:
>>
>>              We haven't discussed approach suggested by Bill, where
>>         addressing is
>>              done via offset in a packet, but not via explicit segments.
>>              IMO for application it is the best case.
>>
>>
>>              On 07/08/2014 12:35 PM, Bala Manoharan wrote:
>>
>>                  Hi Maxim,
>>
>>                  These APIs have incorporated the comments which were
>>         discussed
>>                  in the
>>                  meeting.
>>                  There are no additional comments from my side.
>>
>>                  Regards,
>>                  Bala
>>
>>
>>                  On 8 July 2014 14:20, Maxim Uvarov
>>         <maxim.uvarov@linaro.org <mailto:maxim.uvarov@linaro.org>
>>                  <mailto:maxim.uvarov@linaro.__org
>>         <mailto:maxim.uvarov@linaro.org>>
>>                  <mailto:maxim.uvarov@linaro.
>>         <mailto:maxim.uvarov@linaro.>____org
>>
>>
>>                  <mailto:maxim.uvarov@linaro.__org
>>         <mailto:maxim.uvarov@linaro.org>>>> wrote:
>>
>>                       Taras, Bala, no objection/review comments? ACK?
>>
>>                       Maxim.
>>
>>
>>                       On 07/04/2014 02:31 PM, Petri Savolainen wrote:
>>
>>                           Replaced segment index with handle. Segment
>>         handle is
>>                  always
>>                           coupled with packet handle. Added functions to
>>         get segment
>>                           handle from index and from current handle
>>         (iterate to
>>                  next seg).
>>                           Added segment info function.
>>
>>                           Signed-off-by: Petri Savolainen
>>                  <petri.savolainen@linaro.org
>>         <mailto:petri.savolainen@linaro.org>
>>         <mailto:petri.savolainen@__linaro.org
>>         <mailto:petri.savolainen@linaro.org>>
>>                           <mailto:petri.savolainen@
>>         <mailto:petri.savolainen@>__lin__aro.org <http://linaro.org>
>>
>>
>>                  <mailto:petri.savolainen@__linaro.org
>>         <mailto:petri.savolainen@linaro.org>>>>
>>                           ---
>>                              include/odp_packet.h | 103
>>
>>           ++++++++++++++++++++++++++++++______++++++++++-----------
>>
>>
>>
>>                              1 file changed, 82 insertions(+), 21
>>         deletions(-)
>>
>>                           diff --git a/include/odp_packet.h
>>         b/include/odp_packet.h
>>                           index 8ae6410..ef4be9e 100644
>>                           --- a/include/odp_packet.h
>>                           +++ b/include/odp_packet.h
>>                           @@ -34,6 +34,25 @@ typedef odp_buffer_t
>>         odp_packet_t;
>>                                  /**
>>                           + * ODP packet segment handle
>>                           + */
>>                           +typedef int odp_packet_seg_t;
>>                           +
>>                           +/** Invalid packet segment */
>>                           +#define ODP_PACKET_SEG_INVALID -1
>>                           +
>>                           +/**
>>                           + * ODP packet segment info
>>                           + */
>>                           +typedef struct odp_packet_seg_info_t {
>>                           +       void   *addr;      /**< Segment start
>>         address */
>>                           +       size_t  size;      /**< Segment
>>         maximum data
>>                  size */
>>                           +       void   *data;      /**< Segment data
>>         address */
>>                           +       size_t  data_len;  /**< Segment data
>>         length */
>>                           +} odp_packet_seg_info_t;
>>                           +
>>                           +
>>                           +/**
>>                               * Initialize the packet
>>                               *
>>                               * Needs to be called if the user allocates
>>         a packet
>>                  buffer,
>>                           i.e. the packet
>>                           @@ -242,44 +261,78 @@ int
>>                  odp_packet_is_segmented(odp_______packet_t
>>                           pkt);
>>                              int odp_packet_seg_count(odp_______packet_t
>>
>>         pkt);
>>
>>
>>                                /**
>>                           + * Get segment by index
>>                           + *
>>                           + * @param pkt   Packet handle
>>                           + * @param index Segment index (0 ...
>> seg_count-1)
>>                           + *
>>                           + * @return Segment handle, or
>>         ODP_PACKET_SEG_INVALID
>>                  on an error
>>                           + */
>>                           +odp_packet_seg_t odp_packet_seg(odp_packet_t
>>         pkt, int
>>                  index);
>>                           +
>>                           +/**
>>                           + * Get next segment
>>                           + *
>>                           + * @param pkt   Packet handle
>>                           + * @param seg   Current segment handle
>>                           + *
>>                           + * @return Handle to next segment, or
>>                  ODP_PACKET_SEG_INVALID on
>>                           an error
>>                           + */
>>                           +odp_packet_seg_t
>>         odp_packet_seg_next(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg);
>>                           +
>>                           +/**
>>                           + * Segment info
>>                           + *
>>                           + * Copies segment parameters into the info
>>         structure.
>>                           + *
>>                           + * @param pkt  Packet handle
>>                           + * @param seg  Segment handle
>>                           + * @param info Pointer to segment info
>> structure
>>                           + *
>>                           + * @return 0 if successful, otherwise non-zero
>>                           + */
>>                           +int odp_packet_seg_info(odp_______packet_t
>> pkt,
>>
>>
>>                  odp_packet_seg_t seg,
>>
>>                           +                       odp_packet_seg_info_t
>>         *info);
>>                           +
>>                           +/**
>>                               * Segment start address
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               *
>>                           - * @return Segment start address
>>                           + * @return Segment start address, or NULL on
>>         an error
>>                               */
>>                           -void *odp_packet_seg_addr(odp_______packet_t
>>         pkt, int seg);
>>                           +void *odp_packet_seg_addr(odp_______packet_t
>> pkt,
>>
>>
>>                  odp_packet_seg_t
>>
>>                           seg);
>>                                /**
>>                               * Segment maximum data size
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               *
>>                               * @return Segment maximum data size
>>                               */
>>                           -size_t odp_packet_seg_size(odp_______packet_t
>>         pkt, int seg);
>>                           +size_t odp_packet_seg_size(odp_______packet_t
>>
>>         pkt,
>>
>>                  odp_packet_seg_t
>>
>>                           seg);
>>                                /**
>>                               * Segment data address
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               *
>>                               * @return Segment data address
>>                               */
>>                           -void *odp_packet_seg_data(odp_______packet_t
>>         pkt, int seg);
>>                           +void *odp_packet_seg_data(odp_______packet_t
>> pkt,
>>
>>
>>                  odp_packet_seg_t
>>
>>                           seg);
>>                                /**
>>                               * Segment data length
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               *
>>                               * @return Segment data length
>>                               */
>>                           -size_t
>>         odp_packet_seg_data_len(odp_______packet_t pkt,
>>                  int seg);
>>                           +size_t
>>         odp_packet_seg_data_len(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg);
>>                                /**
>>                               * Segment headroom
>>                           @@ -287,11 +340,11 @@ size_t
>>                           odp_packet_seg_data_len(odp_______packet_t
>>
>>         pkt, int seg);
>>
>>
>>                               * seg_headroom = seg_data - seg_addr
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               *
>>                               * @return Number of octets from seg_addr
>>         to seg_data
>>                               */
>>                           -size_t
>>         odp_packet_seg_headroom(odp_______packet_t pkt,
>>                  int seg);
>>                           +size_t
>>         odp_packet_seg_headroom(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg);
>>                                /**
>>                               * Segment tailroom
>>                           @@ -299,73 +352,81 @@ size_t
>>                           odp_packet_seg_headroom(odp_______packet_t
>>
>>         pkt, int seg);
>>
>>
>>                               * seg_tailroom = seg_size - seg_headroom -
>>         seg_data_len
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               *
>>                               * @return Number of octets from end-of-data
>> to
>>                  end-of-segment
>>                               */
>>                           -size_t
>>         odp_packet_seg_tailroom(odp_______packet_t pkt,
>>                  int seg);
>>                           +size_t
>>         odp_packet_seg_tailroom(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg);
>>                                /**
>>                               * Push out segment head
>>                               *
>>                               * Push out segment data address (away from
>>         data) and
>>                           increase data length.
>>                           + * Does not modify packet in case of an error.
>>                               *
>>                               * seg_data     -= len
>>                               * seg_data_len += len
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               * @param len  Number of octets to push
>>         head (0 ...
>>                  seg_headroom)
>>                               *
>>                               * @return New segment data address, or
>>         NULL on an error
>>                               */
>>                           -void
>>         *odp_packet_seg_push_head(odp_______packet_t pkt,
>>
>>                  int seg,
>>                           size_t len);
>>                           +void
>>         *odp_packet_seg_push_head(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg,
>>                           +                              size_t len);
>>                                /**
>>                               * Pull in segment head
>>                               *
>>                               * Pull in segment data address (towards
>>         data) and
>>                  decrease
>>                           data length.
>>                           + * Does not modify packet in case of an error.
>>                               *
>>                               * seg_data     += len
>>                               * seg_data_len -= len
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               * @param len  Number of octets to pull
>>         head (0 ...
>>                  seg_data_len)
>>                               *
>>                               * @return New segment data address, or
>>         NULL on an error
>>                               */
>>                           -void
>>         *odp_packet_seg_pull_head(odp_______packet_t pkt,
>>
>>                  int seg,
>>                           size_t len);
>>                           +void
>>         *odp_packet_seg_pull_head(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg,
>>                           +                              size_t len);
>>                                /**
>>                               * Push out segment tail
>>                               *
>>                               * Increase segment data length.
>>                           + * Does not modify packet in case of an error.
>>                               *
>>                               * seg_data_len  += len
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               * @param len  Number of octets to push
>>         tail (0 ...
>>                  seg_tailroom)
>>                               *
>>                               * @return New segment data length, or -1
>>         on an error
>>                               */
>>                           -int
>>         odp_packet_seg_push_tail(odp_______packet_t pkt, int
>>                  seg,
>>                           size_t len);
>>                           +int
>>         odp_packet_seg_push_tail(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg,
>>                           +                            size_t len);
>>                                /**
>>                               * Pull in segment tail
>>                               *
>>                               * Decrease segment data length.
>>                           + * Does not modify packet in case of an error.
>>                               *
>>                               * seg_data_len  -= len
>>                               *
>>                               * @param pkt  Packet handle
>>                           - * @param seg  Segment index (0 ...
>> seg_count-1)
>>                           + * @param seg  Segment handle
>>                               * @param len  Number of octets to pull
>>         tail (0 ...
>>                  seg_data_len)
>>                               *
>>                               * @return New segment data length, or -1
>>         on an error
>>                               */
>>                           -int
>>         odp_packet_seg_pull_tail(odp_______packet_t pkt, int
>>                  seg,
>>                           size_t len);
>>                           +int
>>         odp_packet_seg_pull_tail(odp_______packet_t pkt,
>>
>>
>>
>>                           odp_packet_seg_t seg,
>>                           +                            size_t len);
>>                                  #ifdef __cplusplus
>>
>>
>>
>>
>>
>>
>>
>>
>
Maxim Uvarov July 9, 2014, 6:39 a.m. UTC | #9
Applied!

Maxim.

On 07/04/2014 02:31 PM, Petri Savolainen wrote:
> Replaced segment index with handle. Segment handle is always
> coupled with packet handle. Added functions to get segment
> handle from index and from current handle (iterate to next seg).
> Added segment info function.
>
> Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
> ---
>   include/odp_packet.h | 103 ++++++++++++++++++++++++++++++++++++++++-----------
>   1 file changed, 82 insertions(+), 21 deletions(-)
>
> diff --git a/include/odp_packet.h b/include/odp_packet.h
> index 8ae6410..ef4be9e 100644
> --- a/include/odp_packet.h
> +++ b/include/odp_packet.h
> @@ -34,6 +34,25 @@ typedef odp_buffer_t odp_packet_t;
>   
>   
>   /**
> + * ODP packet segment handle
> + */
> +typedef int odp_packet_seg_t;
> +
> +/** Invalid packet segment */
> +#define ODP_PACKET_SEG_INVALID -1
> +
> +/**
> + * ODP packet segment info
> + */
> +typedef struct odp_packet_seg_info_t {
> +	void   *addr;      /**< Segment start address */
> +	size_t  size;      /**< Segment maximum data size */
> +	void   *data;      /**< Segment data address */
> +	size_t  data_len;  /**< Segment data length */
> +} odp_packet_seg_info_t;
> +
> +
> +/**
>    * Initialize the packet
>    *
>    * Needs to be called if the user allocates a packet buffer, i.e. the packet
> @@ -242,44 +261,78 @@ int odp_packet_is_segmented(odp_packet_t pkt);
>   int odp_packet_seg_count(odp_packet_t pkt);
>   
>   /**
> + * Get segment by index
> + *
> + * @param pkt   Packet handle
> + * @param index Segment index (0 ... seg_count-1)
> + *
> + * @return Segment handle, or ODP_PACKET_SEG_INVALID on an error
> + */
> +odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int index);
> +
> +/**
> + * Get next segment
> + *
> + * @param pkt   Packet handle
> + * @param seg   Current segment handle
> + *
> + * @return Handle to next segment, or ODP_PACKET_SEG_INVALID on an error
> + */
> +odp_packet_seg_t odp_packet_seg_next(odp_packet_t pkt, odp_packet_seg_t seg);
> +
> +/**
> + * Segment info
> + *
> + * Copies segment parameters into the info structure.
> + *
> + * @param pkt  Packet handle
> + * @param seg  Segment handle
> + * @param info Pointer to segment info structure
> + *
> + * @return 0 if successful, otherwise non-zero
> + */
> +int odp_packet_seg_info(odp_packet_t pkt, odp_packet_seg_t seg,
> +			odp_packet_seg_info_t *info);
> +
> +/**
>    * Segment start address
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
> - * @return Segment start address
> + * @return Segment start address, or NULL on an error
>    */
> -void *odp_packet_seg_addr(odp_packet_t pkt, int seg);
> +void *odp_packet_seg_addr(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment maximum data size
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Segment maximum data size
>    */
> -size_t odp_packet_seg_size(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_size(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment data address
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Segment data address
>    */
> -void *odp_packet_seg_data(odp_packet_t pkt, int seg);
> +void *odp_packet_seg_data(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment data length
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Segment data length
>    */
> -size_t odp_packet_seg_data_len(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment headroom
> @@ -287,11 +340,11 @@ size_t odp_packet_seg_data_len(odp_packet_t pkt, int seg);
>    * seg_headroom = seg_data - seg_addr
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Number of octets from seg_addr to seg_data
>    */
> -size_t odp_packet_seg_headroom(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_headroom(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Segment tailroom
> @@ -299,73 +352,81 @@ size_t odp_packet_seg_headroom(odp_packet_t pkt, int seg);
>    * seg_tailroom = seg_size - seg_headroom - seg_data_len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    *
>    * @return Number of octets from end-of-data to end-of-segment
>    */
> -size_t odp_packet_seg_tailroom(odp_packet_t pkt, int seg);
> +size_t odp_packet_seg_tailroom(odp_packet_t pkt, odp_packet_seg_t seg);
>   
>   /**
>    * Push out segment head
>    *
>    * Push out segment data address (away from data) and increase data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data     -= len
>    * seg_data_len += len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to push head (0 ... seg_headroom)
>    *
>    * @return New segment data address, or NULL on an error
>    */
> -void *odp_packet_seg_push_head(odp_packet_t pkt, int seg, size_t len);
> +void *odp_packet_seg_push_head(odp_packet_t pkt, odp_packet_seg_t seg,
> +			       size_t len);
>   
>   /**
>    * Pull in segment head
>    *
>    * Pull in segment data address (towards data) and decrease data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data     += len
>    * seg_data_len -= len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to pull head (0 ... seg_data_len)
>    *
>    * @return New segment data address, or NULL on an error
>    */
> -void *odp_packet_seg_pull_head(odp_packet_t pkt, int seg, size_t len);
> +void *odp_packet_seg_pull_head(odp_packet_t pkt, odp_packet_seg_t seg,
> +			       size_t len);
>   
>   /**
>    * Push out segment tail
>    *
>    * Increase segment data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data_len  += len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to push tail (0 ... seg_tailroom)
>    *
>    * @return New segment data length, or -1 on an error
>    */
> -int odp_packet_seg_push_tail(odp_packet_t pkt, int seg, size_t len);
> +int odp_packet_seg_push_tail(odp_packet_t pkt, odp_packet_seg_t seg,
> +			     size_t len);
>   
>   /**
>    * Pull in segment tail
>    *
>    * Decrease segment data length.
> + * Does not modify packet in case of an error.
>    *
>    * seg_data_len  -= len
>    *
>    * @param pkt  Packet handle
> - * @param seg  Segment index (0 ... seg_count-1)
> + * @param seg  Segment handle
>    * @param len  Number of octets to pull tail (0 ... seg_data_len)
>    *
>    * @return New segment data length, or -1 on an error
>    */
> -int odp_packet_seg_pull_tail(odp_packet_t pkt, int seg, size_t len);
> +int odp_packet_seg_pull_tail(odp_packet_t pkt, odp_packet_seg_t seg,
> +			     size_t len);
>   
>   
>   #ifdef __cplusplus
diff mbox

Patch

diff --git a/include/odp_packet.h b/include/odp_packet.h
index 8ae6410..ef4be9e 100644
--- a/include/odp_packet.h
+++ b/include/odp_packet.h
@@ -34,6 +34,25 @@  typedef odp_buffer_t odp_packet_t;
 
 
 /**
+ * ODP packet segment handle
+ */
+typedef int odp_packet_seg_t;
+
+/** Invalid packet segment */
+#define ODP_PACKET_SEG_INVALID -1
+
+/**
+ * ODP packet segment info
+ */
+typedef struct odp_packet_seg_info_t {
+	void   *addr;      /**< Segment start address */
+	size_t  size;      /**< Segment maximum data size */
+	void   *data;      /**< Segment data address */
+	size_t  data_len;  /**< Segment data length */
+} odp_packet_seg_info_t;
+
+
+/**
  * Initialize the packet
  *
  * Needs to be called if the user allocates a packet buffer, i.e. the packet
@@ -242,44 +261,78 @@  int odp_packet_is_segmented(odp_packet_t pkt);
 int odp_packet_seg_count(odp_packet_t pkt);
 
 /**
+ * Get segment by index
+ *
+ * @param pkt   Packet handle
+ * @param index Segment index (0 ... seg_count-1)
+ *
+ * @return Segment handle, or ODP_PACKET_SEG_INVALID on an error
+ */
+odp_packet_seg_t odp_packet_seg(odp_packet_t pkt, int index);
+
+/**
+ * Get next segment
+ *
+ * @param pkt   Packet handle
+ * @param seg   Current segment handle
+ *
+ * @return Handle to next segment, or ODP_PACKET_SEG_INVALID on an error
+ */
+odp_packet_seg_t odp_packet_seg_next(odp_packet_t pkt, odp_packet_seg_t seg);
+
+/**
+ * Segment info
+ *
+ * Copies segment parameters into the info structure.
+ *
+ * @param pkt  Packet handle
+ * @param seg  Segment handle
+ * @param info Pointer to segment info structure
+ *
+ * @return 0 if successful, otherwise non-zero
+ */
+int odp_packet_seg_info(odp_packet_t pkt, odp_packet_seg_t seg,
+			odp_packet_seg_info_t *info);
+
+/**
  * Segment start address
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  *
- * @return Segment start address
+ * @return Segment start address, or NULL on an error
  */
-void *odp_packet_seg_addr(odp_packet_t pkt, int seg);
+void *odp_packet_seg_addr(odp_packet_t pkt, odp_packet_seg_t seg);
 
 /**
  * Segment maximum data size
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  *
  * @return Segment maximum data size
  */
-size_t odp_packet_seg_size(odp_packet_t pkt, int seg);
+size_t odp_packet_seg_size(odp_packet_t pkt, odp_packet_seg_t seg);
 
 /**
  * Segment data address
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  *
  * @return Segment data address
  */
-void *odp_packet_seg_data(odp_packet_t pkt, int seg);
+void *odp_packet_seg_data(odp_packet_t pkt, odp_packet_seg_t seg);
 
 /**
  * Segment data length
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  *
  * @return Segment data length
  */
-size_t odp_packet_seg_data_len(odp_packet_t pkt, int seg);
+size_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg);
 
 /**
  * Segment headroom
@@ -287,11 +340,11 @@  size_t odp_packet_seg_data_len(odp_packet_t pkt, int seg);
  * seg_headroom = seg_data - seg_addr
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  *
  * @return Number of octets from seg_addr to seg_data
  */
-size_t odp_packet_seg_headroom(odp_packet_t pkt, int seg);
+size_t odp_packet_seg_headroom(odp_packet_t pkt, odp_packet_seg_t seg);
 
 /**
  * Segment tailroom
@@ -299,73 +352,81 @@  size_t odp_packet_seg_headroom(odp_packet_t pkt, int seg);
  * seg_tailroom = seg_size - seg_headroom - seg_data_len
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  *
  * @return Number of octets from end-of-data to end-of-segment
  */
-size_t odp_packet_seg_tailroom(odp_packet_t pkt, int seg);
+size_t odp_packet_seg_tailroom(odp_packet_t pkt, odp_packet_seg_t seg);
 
 /**
  * Push out segment head
  *
  * Push out segment data address (away from data) and increase data length.
+ * Does not modify packet in case of an error.
  *
  * seg_data     -= len
  * seg_data_len += len
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  * @param len  Number of octets to push head (0 ... seg_headroom)
  *
  * @return New segment data address, or NULL on an error
  */
-void *odp_packet_seg_push_head(odp_packet_t pkt, int seg, size_t len);
+void *odp_packet_seg_push_head(odp_packet_t pkt, odp_packet_seg_t seg,
+			       size_t len);
 
 /**
  * Pull in segment head
  *
  * Pull in segment data address (towards data) and decrease data length.
+ * Does not modify packet in case of an error.
  *
  * seg_data     += len
  * seg_data_len -= len
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  * @param len  Number of octets to pull head (0 ... seg_data_len)
  *
  * @return New segment data address, or NULL on an error
  */
-void *odp_packet_seg_pull_head(odp_packet_t pkt, int seg, size_t len);
+void *odp_packet_seg_pull_head(odp_packet_t pkt, odp_packet_seg_t seg,
+			       size_t len);
 
 /**
  * Push out segment tail
  *
  * Increase segment data length.
+ * Does not modify packet in case of an error.
  *
  * seg_data_len  += len
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  * @param len  Number of octets to push tail (0 ... seg_tailroom)
  *
  * @return New segment data length, or -1 on an error
  */
-int odp_packet_seg_push_tail(odp_packet_t pkt, int seg, size_t len);
+int odp_packet_seg_push_tail(odp_packet_t pkt, odp_packet_seg_t seg,
+			     size_t len);
 
 /**
  * Pull in segment tail
  *
  * Decrease segment data length.
+ * Does not modify packet in case of an error.
  *
  * seg_data_len  -= len
  *
  * @param pkt  Packet handle
- * @param seg  Segment index (0 ... seg_count-1)
+ * @param seg  Segment handle
  * @param len  Number of octets to pull tail (0 ... seg_data_len)
  *
  * @return New segment data length, or -1 on an error
  */
-int odp_packet_seg_pull_tail(odp_packet_t pkt, int seg, size_t len);
+int odp_packet_seg_pull_tail(odp_packet_t pkt, odp_packet_seg_t seg,
+			     size_t len);
 
 
 #ifdef __cplusplus