diff mbox

[RFC,API-NEXT] api: packet: add packet reference apis

Message ID 1477447014-700-1-git-send-email-bill.fischofer@linaro.org
State New
Headers show

Commit Message

Bill Fischofer Oct. 26, 2016, 1:56 a.m. UTC
Add the following five packet APIs:

- odp_packet_ref_static()
- odp_packet_ref()
- odp_packet_ref_pkt()
- odp_packet_is_a_ref()
- odp_packet_is_referenced()

Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

---
 include/odp/api/spec/packet.h | 143 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 143 insertions(+)

-- 
2.7.4

Comments

Balasubramanian Manoharan Oct. 26, 2016, 5:19 p.m. UTC | #1
On 26 October 2016 at 07:26, Bill Fischofer <bill.fischofer@linaro.org> wrote:
> Add the following five packet APIs:

>

> - odp_packet_ref_static()

> - odp_packet_ref()

> - odp_packet_ref_pkt()

> - odp_packet_is_a_ref()

> - odp_packet_is_referenced()

>

> Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

> ---

>  include/odp/api/spec/packet.h | 143 ++++++++++++++++++++++++++++++++++++++++++

>  1 file changed, 143 insertions(+)

>

> diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h

> index 4a14f2d..7e347c5 100644

> --- a/include/odp/api/spec/packet.h

> +++ b/include/odp/api/spec/packet.h

> @@ -846,6 +846,149 @@ int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail);

>

>  /*

>   *

> + * References

> + * ********************************************************

> + *

> + */

> +

> +/**

> + * Create a static reference to a packet

> + *

> + * Create a (shared) reference to a base packet. A static reference is used to

> + * retain a copy of the packet so that the storage behind it is not freed

> + * until all references to the packet are freed. This can be used, for

> + * example, to support efficient retransmission processing.

> + *

> + * @param pkt    Handle of the base packet for which a static reference is

> + *               to be created.

> + *

> + * @return                    Handle of the reference packet

> + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains unchanged.

> + *

> + * @note The intent of a static reference is that both the base packet and the

> + *       returned reference should be treated as read-only after this

> + *       call. Results are unpredictable if this restriction is not observed.

> + *

> + * @note Static references have restrictions but may have performance

> + *       advantages on some platforms if the caller does not intend to modify

> + *       the reference packet. If modification is needed (e.g., to prefix a

> + *       unique header onto the packet) then odp_packet_ref() should be used.

> + */

> +odp_packet_t odp_packet_ref_static(odp_packet_t pkt);

> +

> +/**

> + * Create a reference to a packet

> + *

> + * Create a (shared) reference to a base packet starting at a specified byte

> + * offset. This reference may be used as an argument to header manipulation

> + * APIs to prefix a unique header onto the shared base. The storage associated

> + * with the base packet is not freed until all references to it are freed,

> + * which permits easy multicasting or retransmission processing to be

> + * performed.

> + *

> + * @param pkt    Handle of the base packet for which a reference is to be

> + *               created.

> + *

> + * @param offset Byte offset in the base packet at which the shared reference

> + *               is to begin. Must be in the range 0..odp_packet_len(pkt)-1.

> + *

> + * @return                    Handle of the reference packet

> + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains unchanged.

> + *

> + * @note This operation prepends a zero-length header onto the base packet

> + *       beginning at the specified offset. This header is always drawn from

> + *       the same pool as the base packet.

> + *

> + * @note Because references are unique packets, any bytes pushed onto the head

> + *       of a reference via odp_packet_push_head() or odp_packet_extend_head()

> + *       are unique to this reference and are not seen by any other reference

> + *       to the same base packet.

> + *

> + * @note The base pkt used as input to this routine may itself by a reference

> + *       to some other base packet. Implementations MAY restrict the ability

> + *       to create such compound references. Attempts to exceed any

> + *       implementation limits in this regard will result in this call failing

> + *       and returning ODP_PACKET_INVALID.

> + *

> + * @note If the caller does not indend to push a header onto the returned

> + *       reference, the odp_packet_ref_static() API may be used. This may be a

> + *       more efficient means of obtaining another reference to a base packet

> + *       that will be treated as read-only.

> + */

> +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);

> +

> +/**

> + * Create a reference to another packet from a header packet

> + *

> + * Create a (shared) reference to a base packet starting at a specified byte

> + * offset by prepending a header packet. The resulting reference consists of

> + * the unshared header followed by the shared base packet starting at the

> + * specified offset. This shared portion should be regarded as read-only. The

> + * storage associated with the shared portion of the reference is not freed

> + * until all references to it are freed, which permits easy multicasting or

> + * retransmission processing to be performed.

> + *

> + * @param pkt    Handle of the base packet for which a reference is to be

> + *               created.

> + *

> + * @param offset Byte offset in the base packet at which the shared reference

> + *               to begin. Must be in the range 0..odp_packet_len(pkt)-1.

> + *

> + * @param hdr    Handle of the header packet to be prefixed onto the base

> + *               packet to create the reference. If this is specified as

> + *               ODP_PACKET_INVALID, this call is equivalent to

> + *               odp_packet_ref().

> + *

> + * @return       Handle of the reference packet. This may or may not be the

> + *               same as the input hdr packet. The caller should only use this

> + *               handle since the original hdr packet no longer has any

> + *               independent existence.

> + *

> + * @retval ODP_PACKET_INVALID If the reference failed. In this case both pkt

> + *                            and hdr are unchanged.

> + *

> + * @note Either packet input to this routine may itself be a reference,

> + *       however individual implementations MAY impose limits on how deeply

> + *       splices may be nested and fail the call if those limits are exceeded.

> + *

> + * @note The packets used as input to this routine may reside in different

> + *       pools, however individual implementations MAY require that both

> + *       reside in the same pool and fail the call if this restriction is not

> + *       observed. odp_packet_pool() on the returned reference returns the

> + *       pool id of the header packet.

> + */

> +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,

> +                               odp_packet_t hdr);


Creating reference at specified offset becomes tricky if multiple
references are created at multiple offsets in the same segment and
referred by different packet headers. Amount of segment meta data is
limited and since there is no limit on the number of different offsets
created in the segment, each reference of the segment could have
different offsets and there is a need for large amount of meta data at
each segment header.

Since this API is used in fast path the efficiency would become an
issue if the same is implemented using packet copy.

Regards,
Bala
> +

> +/**

> + * Test if a packet is a reference

> + *

> + * A packet is a reference if it was created by odp_packet_ref_xxx().

> + * Note that a reference created from another reference is considered

> + * a compound reference.

> + *

> + * @param pkt Packet handle

> + *

> + * @retval 0  Packet is not a reference

> + * @retval >0 Packet is a reference consisting of N individual packets.

> + */

> +int odp_packet_is_a_ref(odp_packet_t pkt);

> +

> +/**

> + * Test if a packet is referenced

> + *

> + * A packet is referenced if a reference was created on it by

> + * odp_packet_ref_xxx().

> + *

> + * @param pkt Packet handle

> + *

> + * @retval 0  Packet is not referenced

> + * @retval >0 Packet is N references based on it

> + */

> +int odp_packet_is_referenced(odp_packet_t pkt);

> +

> +/*

> + *

>   * Copy

>   * ********************************************************

>   *

> --

> 2.7.4

>
Bill Fischofer Oct. 26, 2016, 5:47 p.m. UTC | #2
On Wed, Oct 26, 2016 at 12:19 PM, Bala Manoharan <bala.manoharan@linaro.org>
wrote:

> On 26 October 2016 at 07:26, Bill Fischofer <bill.fischofer@linaro.org>

> wrote:

> > Add the following five packet APIs:

> >

> > - odp_packet_ref_static()

> > - odp_packet_ref()

> > - odp_packet_ref_pkt()

> > - odp_packet_is_a_ref()

> > - odp_packet_is_referenced()

> >

> > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

> > ---

> >  include/odp/api/spec/packet.h | 143 ++++++++++++++++++++++++++++++

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

> >  1 file changed, 143 insertions(+)

> >

> > diff --git a/include/odp/api/spec/packet.h

> b/include/odp/api/spec/packet.h

> > index 4a14f2d..7e347c5 100644

> > --- a/include/odp/api/spec/packet.h

> > +++ b/include/odp/api/spec/packet.h

> > @@ -846,6 +846,149 @@ int odp_packet_split(odp_packet_t *pkt, uint32_t

> len, odp_packet_t *tail);

> >

> >  /*

> >   *

> > + * References

> > + * ********************************************************

> > + *

> > + */

> > +

> > +/**

> > + * Create a static reference to a packet

> > + *

> > + * Create a (shared) reference to a base packet. A static reference is

> used to

> > + * retain a copy of the packet so that the storage behind it is not

> freed

> > + * until all references to the packet are freed. This can be used, for

> > + * example, to support efficient retransmission processing.

> > + *

> > + * @param pkt    Handle of the base packet for which a static reference

> is

> > + *               to be created.

> > + *

> > + * @return                    Handle of the reference packet

> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

> unchanged.

> > + *

> > + * @note The intent of a static reference is that both the base packet

> and the

> > + *       returned reference should be treated as read-only after this

> > + *       call. Results are unpredictable if this restriction is not

> observed.

> > + *

> > + * @note Static references have restrictions but may have performance

> > + *       advantages on some platforms if the caller does not intend to

> modify

> > + *       the reference packet. If modification is needed (e.g., to

> prefix a

> > + *       unique header onto the packet) then odp_packet_ref() should be

> used.

> > + */

> > +odp_packet_t odp_packet_ref_static(odp_packet_t pkt);

> > +

> > +/**

> > + * Create a reference to a packet

> > + *

> > + * Create a (shared) reference to a base packet starting at a specified

> byte

> > + * offset. This reference may be used as an argument to header

> manipulation

> > + * APIs to prefix a unique header onto the shared base. The storage

> associated

> > + * with the base packet is not freed until all references to it are

> freed,

> > + * which permits easy multicasting or retransmission processing to be

> > + * performed.

> > + *

> > + * @param pkt    Handle of the base packet for which a reference is to

> be

> > + *               created.

> > + *

> > + * @param offset Byte offset in the base packet at which the shared

> reference

> > + *               is to begin. Must be in the range

> 0..odp_packet_len(pkt)-1.

> > + *

> > + * @return                    Handle of the reference packet

> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

> unchanged.

> > + *

> > + * @note This operation prepends a zero-length header onto the base

> packet

> > + *       beginning at the specified offset. This header is always drawn

> from

> > + *       the same pool as the base packet.

> > + *

> > + * @note Because references are unique packets, any bytes pushed onto

> the head

> > + *       of a reference via odp_packet_push_head() or

> odp_packet_extend_head()

> > + *       are unique to this reference and are not seen by any other

> reference

> > + *       to the same base packet.

> > + *

> > + * @note The base pkt used as input to this routine may itself by a

> reference

> > + *       to some other base packet. Implementations MAY restrict the

> ability

> > + *       to create such compound references. Attempts to exceed any

> > + *       implementation limits in this regard will result in this call

> failing

> > + *       and returning ODP_PACKET_INVALID.

> > + *

> > + * @note If the caller does not indend to push a header onto the

> returned

> > + *       reference, the odp_packet_ref_static() API may be used. This

> may be a

> > + *       more efficient means of obtaining another reference to a base

> packet

> > + *       that will be treated as read-only.

> > + */

> > +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);

> > +

> > +/**

> > + * Create a reference to another packet from a header packet

> > + *

> > + * Create a (shared) reference to a base packet starting at a specified

> byte

> > + * offset by prepending a header packet. The resulting reference

> consists of

> > + * the unshared header followed by the shared base packet starting at

> the

> > + * specified offset. This shared portion should be regarded as

> read-only. The

> > + * storage associated with the shared portion of the reference is not

> freed

> > + * until all references to it are freed, which permits easy

> multicasting or

> > + * retransmission processing to be performed.

> > + *

> > + * @param pkt    Handle of the base packet for which a reference is to

> be

> > + *               created.

> > + *

> > + * @param offset Byte offset in the base packet at which the shared

> reference

> > + *               to begin. Must be in the range

> 0..odp_packet_len(pkt)-1.

> > + *

> > + * @param hdr    Handle of the header packet to be prefixed onto the

> base

> > + *               packet to create the reference. If this is specified as

> > + *               ODP_PACKET_INVALID, this call is equivalent to

> > + *               odp_packet_ref().

> > + *

> > + * @return       Handle of the reference packet. This may or may not be

> the

> > + *               same as the input hdr packet. The caller should only

> use this

> > + *               handle since the original hdr packet no longer has any

> > + *               independent existence.

> > + *

> > + * @retval ODP_PACKET_INVALID If the reference failed. In this case

> both pkt

> > + *                            and hdr are unchanged.

> > + *

> > + * @note Either packet input to this routine may itself be a reference,

> > + *       however individual implementations MAY impose limits on how

> deeply

> > + *       splices may be nested and fail the call if those limits are

> exceeded.

> > + *

> > + * @note The packets used as input to this routine may reside in

> different

> > + *       pools, however individual implementations MAY require that both

> > + *       reside in the same pool and fail the call if this restriction

> is not

> > + *       observed. odp_packet_pool() on the returned reference returns

> the

> > + *       pool id of the header packet.

> > + */

> > +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,

> > +                               odp_packet_t hdr);

>

> Creating reference at specified offset becomes tricky if multiple

> references are created at multiple offsets in the same segment and

> referred by different packet headers. Amount of segment meta data is

> limited and since there is no limit on the number of different offsets

> created in the segment, each reference of the segment could have

> different offsets and there is a need for large amount of meta data at

> each segment header.

>


Is it sufficient to limit the number of references that can be created on a
given base packet and/or the number of different offsets that can be used?


>

> Since this API is used in fast path the efficiency would become an

> issue if the same is implemented using packet copy.

>


I agree. I'd rather see a reference operation fail and let the application
do copies if needed rather than silently copying things behind the scenes
resulting in unpredictable performance. ODP already has a rich set of APIs
that support partial or complete packet copying. The whole purpose of these
APIs is to promote sharing. If the implementation cannot offer sharing
under some conditions than it's better to live with that then to pretend
that sharing is happening when it isn't.


>

> Regards,

> Bala

> > +

> > +/**

> > + * Test if a packet is a reference

> > + *

> > + * A packet is a reference if it was created by odp_packet_ref_xxx().

> > + * Note that a reference created from another reference is considered

> > + * a compound reference.

> > + *

> > + * @param pkt Packet handle

> > + *

> > + * @retval 0  Packet is not a reference

> > + * @retval >0 Packet is a reference consisting of N individual packets.

> > + */

> > +int odp_packet_is_a_ref(odp_packet_t pkt);

> > +

> > +/**

> > + * Test if a packet is referenced

> > + *

> > + * A packet is referenced if a reference was created on it by

> > + * odp_packet_ref_xxx().

> > + *

> > + * @param pkt Packet handle

> > + *

> > + * @retval 0  Packet is not referenced

> > + * @retval >0 Packet is N references based on it

> > + */

> > +int odp_packet_is_referenced(odp_packet_t pkt);

> > +

> > +/*

> > + *

> >   * Copy

> >   * ********************************************************

> >   *

> > --

> > 2.7.4

> >

>
Balasubramanian Manoharan Oct. 27, 2016, 12:26 p.m. UTC | #3
On 26 October 2016 at 23:17, Bill Fischofer <bill.fischofer@linaro.org> wrote:
>

>

> On Wed, Oct 26, 2016 at 12:19 PM, Bala Manoharan <bala.manoharan@linaro.org>

> wrote:

>>

>> On 26 October 2016 at 07:26, Bill Fischofer <bill.fischofer@linaro.org>

>> wrote:

>> > Add the following five packet APIs:

>> >

>> > - odp_packet_ref_static()

>> > - odp_packet_ref()

>> > - odp_packet_ref_pkt()

>> > - odp_packet_is_a_ref()

>> > - odp_packet_is_referenced()

>> >

>> > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

>> > ---

>> >  include/odp/api/spec/packet.h | 143

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

>> >  1 file changed, 143 insertions(+)

>> >

>> > diff --git a/include/odp/api/spec/packet.h

>> > b/include/odp/api/spec/packet.h

>> > index 4a14f2d..7e347c5 100644

>> > --- a/include/odp/api/spec/packet.h

>> > +++ b/include/odp/api/spec/packet.h

>> > @@ -846,6 +846,149 @@ int odp_packet_split(odp_packet_t *pkt, uint32_t

>> > len, odp_packet_t *tail);

>> >

>> >  /*

>> >   *

>> > + * References

>> > + * ********************************************************

>> > + *

>> > + */

>> > +

>> > +/**

>> > + * Create a static reference to a packet

>> > + *

>> > + * Create a (shared) reference to a base packet. A static reference is

>> > used to

>> > + * retain a copy of the packet so that the storage behind it is not

>> > freed

>> > + * until all references to the packet are freed. This can be used, for

>> > + * example, to support efficient retransmission processing.

>> > + *

>> > + * @param pkt    Handle of the base packet for which a static reference

>> > is

>> > + *               to be created.

>> > + *

>> > + * @return                    Handle of the reference packet

>> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

>> > unchanged.

>> > + *

>> > + * @note The intent of a static reference is that both the base packet

>> > and the

>> > + *       returned reference should be treated as read-only after this

>> > + *       call. Results are unpredictable if this restriction is not

>> > observed.

>> > + *

>> > + * @note Static references have restrictions but may have performance

>> > + *       advantages on some platforms if the caller does not intend to

>> > modify

>> > + *       the reference packet. If modification is needed (e.g., to

>> > prefix a

>> > + *       unique header onto the packet) then odp_packet_ref() should be

>> > used.

>> > + */

>> > +odp_packet_t odp_packet_ref_static(odp_packet_t pkt);

>> > +

>> > +/**

>> > + * Create a reference to a packet

>> > + *

>> > + * Create a (shared) reference to a base packet starting at a specified

>> > byte

>> > + * offset. This reference may be used as an argument to header

>> > manipulation

>> > + * APIs to prefix a unique header onto the shared base. The storage

>> > associated

>> > + * with the base packet is not freed until all references to it are

>> > freed,

>> > + * which permits easy multicasting or retransmission processing to be

>> > + * performed.

>> > + *

>> > + * @param pkt    Handle of the base packet for which a reference is to

>> > be

>> > + *               created.

>> > + *

>> > + * @param offset Byte offset in the base packet at which the shared

>> > reference

>> > + *               is to begin. Must be in the range

>> > 0..odp_packet_len(pkt)-1.

>> > + *

>> > + * @return                    Handle of the reference packet

>> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

>> > unchanged.

>> > + *

>> > + * @note This operation prepends a zero-length header onto the base

>> > packet

>> > + *       beginning at the specified offset. This header is always drawn

>> > from

>> > + *       the same pool as the base packet.

>> > + *

>> > + * @note Because references are unique packets, any bytes pushed onto

>> > the head

>> > + *       of a reference via odp_packet_push_head() or

>> > odp_packet_extend_head()

>> > + *       are unique to this reference and are not seen by any other

>> > reference

>> > + *       to the same base packet.

>> > + *

>> > + * @note The base pkt used as input to this routine may itself by a

>> > reference

>> > + *       to some other base packet. Implementations MAY restrict the

>> > ability

>> > + *       to create such compound references. Attempts to exceed any

>> > + *       implementation limits in this regard will result in this call

>> > failing

>> > + *       and returning ODP_PACKET_INVALID.

>> > + *

>> > + * @note If the caller does not indend to push a header onto the

>> > returned

>> > + *       reference, the odp_packet_ref_static() API may be used. This

>> > may be a

>> > + *       more efficient means of obtaining another reference to a base

>> > packet

>> > + *       that will be treated as read-only.

>> > + */

>> > +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);

>> > +

>> > +/**

>> > + * Create a reference to another packet from a header packet

>> > + *

>> > + * Create a (shared) reference to a base packet starting at a specified

>> > byte

>> > + * offset by prepending a header packet. The resulting reference

>> > consists of

>> > + * the unshared header followed by the shared base packet starting at

>> > the

>> > + * specified offset. This shared portion should be regarded as

>> > read-only. The

>> > + * storage associated with the shared portion of the reference is not

>> > freed

>> > + * until all references to it are freed, which permits easy

>> > multicasting or

>> > + * retransmission processing to be performed.

>> > + *

>> > + * @param pkt    Handle of the base packet for which a reference is to

>> > be

>> > + *               created.

>> > + *

>> > + * @param offset Byte offset in the base packet at which the shared

>> > reference

>> > + *               to begin. Must be in the range

>> > 0..odp_packet_len(pkt)-1.

>> > + *

>> > + * @param hdr    Handle of the header packet to be prefixed onto the

>> > base

>> > + *               packet to create the reference. If this is specified

>> > as

>> > + *               ODP_PACKET_INVALID, this call is equivalent to

>> > + *               odp_packet_ref().

>> > + *

>> > + * @return       Handle of the reference packet. This may or may not be

>> > the

>> > + *               same as the input hdr packet. The caller should only

>> > use this

>> > + *               handle since the original hdr packet no longer has any

>> > + *               independent existence.

>> > + *

>> > + * @retval ODP_PACKET_INVALID If the reference failed. In this case

>> > both pkt

>> > + *                            and hdr are unchanged.

>> > + *

>> > + * @note Either packet input to this routine may itself be a reference,

>> > + *       however individual implementations MAY impose limits on how

>> > deeply

>> > + *       splices may be nested and fail the call if those limits are

>> > exceeded.

>> > + *

>> > + * @note The packets used as input to this routine may reside in

>> > different

>> > + *       pools, however individual implementations MAY require that

>> > both

>> > + *       reside in the same pool and fail the call if this restriction

>> > is not

>> > + *       observed. odp_packet_pool() on the returned reference returns

>> > the

>> > + *       pool id of the header packet.

>> > + */

>> > +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,

>> > +                               odp_packet_t hdr);

>>

>> Creating reference at specified offset becomes tricky if multiple

>> references are created at multiple offsets in the same segment and

>> referred by different packet headers. Amount of segment meta data is

>> limited and since there is no limit on the number of different offsets

>> created in the segment, each reference of the segment could have

>> different offsets and there is a need for large amount of meta data at

>> each segment header.

>

>

> Is it sufficient to limit the number of references that can be created on a

> given base packet and/or the number of different offsets that can be used?


Maybe this could simplify the implementation but not sure if
application will be able to confront to this limitation.
>

>>

>>

>> Since this API is used in fast path the efficiency would become an

>> issue if the same is implemented using packet copy.

>

>

> I agree. I'd rather see a reference operation fail and let the application

> do copies if needed rather than silently copying things behind the scenes

> resulting in unpredictable performance. ODP already has a rich set of APIs

> that support partial or complete packet copying. The whole purpose of these

> APIs is to promote sharing. If the implementation cannot offer sharing under

> some conditions than it's better to live with that then to pretend that

> sharing is happening when it isn't.


Regarding the question of offset value it is reasonable to assume that
the offset will be near the head of the packet.
Coz the current API definition allows the offset to be from 0 to
(packet_length -1)  but the most likely use-case will be to use
multiple headers with common data and the offset value might be
smaller compared to the packet length.

-Bala
>

>>

>>

>> Regards,

>> Bala

>> > +

>> > +/**

>> > + * Test if a packet is a reference

>> > + *

>> > + * A packet is a reference if it was created by odp_packet_ref_xxx().

>> > + * Note that a reference created from another reference is considered

>> > + * a compound reference.

>> > + *

>> > + * @param pkt Packet handle

>> > + *

>> > + * @retval 0  Packet is not a reference

>> > + * @retval >0 Packet is a reference consisting of N individual packets.

>> > + */

>> > +int odp_packet_is_a_ref(odp_packet_t pkt);

>> > +

>> > +/**

>> > + * Test if a packet is referenced

>> > + *

>> > + * A packet is referenced if a reference was created on it by

>> > + * odp_packet_ref_xxx().

>> > + *

>> > + * @param pkt Packet handle

>> > + *

>> > + * @retval 0  Packet is not referenced

>> > + * @retval >0 Packet is N references based on it

>> > + */

>> > +int odp_packet_is_referenced(odp_packet_t pkt);

>> > +

>> > +/*

>> > + *

>> >   * Copy

>> >   * ********************************************************

>> >   *

>> > --

>> > 2.7.4

>> >

>

>
Bill Fischofer Oct. 27, 2016, 2:08 p.m. UTC | #4
On Thu, Oct 27, 2016 at 7:26 AM, Bala Manoharan <bala.manoharan@linaro.org>
wrote:

> On 26 October 2016 at 23:17, Bill Fischofer <bill.fischofer@linaro.org>

> wrote:

> >

> >

> > On Wed, Oct 26, 2016 at 12:19 PM, Bala Manoharan <

> bala.manoharan@linaro.org>

> > wrote:

> >>

> >> On 26 October 2016 at 07:26, Bill Fischofer <bill.fischofer@linaro.org>

> >> wrote:

> >> > Add the following five packet APIs:

> >> >

> >> > - odp_packet_ref_static()

> >> > - odp_packet_ref()

> >> > - odp_packet_ref_pkt()

> >> > - odp_packet_is_a_ref()

> >> > - odp_packet_is_referenced()

> >> >

> >> > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

> >> > ---

> >> >  include/odp/api/spec/packet.h | 143

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

> >> >  1 file changed, 143 insertions(+)

> >> >

> >> > diff --git a/include/odp/api/spec/packet.h

> >> > b/include/odp/api/spec/packet.h

> >> > index 4a14f2d..7e347c5 100644

> >> > --- a/include/odp/api/spec/packet.h

> >> > +++ b/include/odp/api/spec/packet.h

> >> > @@ -846,6 +846,149 @@ int odp_packet_split(odp_packet_t *pkt, uint32_t

> >> > len, odp_packet_t *tail);

> >> >

> >> >  /*

> >> >   *

> >> > + * References

> >> > + * ********************************************************

> >> > + *

> >> > + */

> >> > +

> >> > +/**

> >> > + * Create a static reference to a packet

> >> > + *

> >> > + * Create a (shared) reference to a base packet. A static reference

> is

> >> > used to

> >> > + * retain a copy of the packet so that the storage behind it is not

> >> > freed

> >> > + * until all references to the packet are freed. This can be used,

> for

> >> > + * example, to support efficient retransmission processing.

> >> > + *

> >> > + * @param pkt    Handle of the base packet for which a static

> reference

> >> > is

> >> > + *               to be created.

> >> > + *

> >> > + * @return                    Handle of the reference packet

> >> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

> >> > unchanged.

> >> > + *

> >> > + * @note The intent of a static reference is that both the base

> packet

> >> > and the

> >> > + *       returned reference should be treated as read-only after this

> >> > + *       call. Results are unpredictable if this restriction is not

> >> > observed.

> >> > + *

> >> > + * @note Static references have restrictions but may have performance

> >> > + *       advantages on some platforms if the caller does not intend

> to

> >> > modify

> >> > + *       the reference packet. If modification is needed (e.g., to

> >> > prefix a

> >> > + *       unique header onto the packet) then odp_packet_ref() should

> be

> >> > used.

> >> > + */

> >> > +odp_packet_t odp_packet_ref_static(odp_packet_t pkt);

> >> > +

> >> > +/**

> >> > + * Create a reference to a packet

> >> > + *

> >> > + * Create a (shared) reference to a base packet starting at a

> specified

> >> > byte

> >> > + * offset. This reference may be used as an argument to header

> >> > manipulation

> >> > + * APIs to prefix a unique header onto the shared base. The storage

> >> > associated

> >> > + * with the base packet is not freed until all references to it are

> >> > freed,

> >> > + * which permits easy multicasting or retransmission processing to be

> >> > + * performed.

> >> > + *

> >> > + * @param pkt    Handle of the base packet for which a reference is

> to

> >> > be

> >> > + *               created.

> >> > + *

> >> > + * @param offset Byte offset in the base packet at which the shared

> >> > reference

> >> > + *               is to begin. Must be in the range

> >> > 0..odp_packet_len(pkt)-1.

> >> > + *

> >> > + * @return                    Handle of the reference packet

> >> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

> >> > unchanged.

> >> > + *

> >> > + * @note This operation prepends a zero-length header onto the base

> >> > packet

> >> > + *       beginning at the specified offset. This header is always

> drawn

> >> > from

> >> > + *       the same pool as the base packet.

> >> > + *

> >> > + * @note Because references are unique packets, any bytes pushed onto

> >> > the head

> >> > + *       of a reference via odp_packet_push_head() or

> >> > odp_packet_extend_head()

> >> > + *       are unique to this reference and are not seen by any other

> >> > reference

> >> > + *       to the same base packet.

> >> > + *

> >> > + * @note The base pkt used as input to this routine may itself by a

> >> > reference

> >> > + *       to some other base packet. Implementations MAY restrict the

> >> > ability

> >> > + *       to create such compound references. Attempts to exceed any

> >> > + *       implementation limits in this regard will result in this

> call

> >> > failing

> >> > + *       and returning ODP_PACKET_INVALID.

> >> > + *

> >> > + * @note If the caller does not indend to push a header onto the

> >> > returned

> >> > + *       reference, the odp_packet_ref_static() API may be used. This

> >> > may be a

> >> > + *       more efficient means of obtaining another reference to a

> base

> >> > packet

> >> > + *       that will be treated as read-only.

> >> > + */

> >> > +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);

> >> > +

> >> > +/**

> >> > + * Create a reference to another packet from a header packet

> >> > + *

> >> > + * Create a (shared) reference to a base packet starting at a

> specified

> >> > byte

> >> > + * offset by prepending a header packet. The resulting reference

> >> > consists of

> >> > + * the unshared header followed by the shared base packet starting at

> >> > the

> >> > + * specified offset. This shared portion should be regarded as

> >> > read-only. The

> >> > + * storage associated with the shared portion of the reference is not

> >> > freed

> >> > + * until all references to it are freed, which permits easy

> >> > multicasting or

> >> > + * retransmission processing to be performed.

> >> > + *

> >> > + * @param pkt    Handle of the base packet for which a reference is

> to

> >> > be

> >> > + *               created.

> >> > + *

> >> > + * @param offset Byte offset in the base packet at which the shared

> >> > reference

> >> > + *               to begin. Must be in the range

> >> > 0..odp_packet_len(pkt)-1.

> >> > + *

> >> > + * @param hdr    Handle of the header packet to be prefixed onto the

> >> > base

> >> > + *               packet to create the reference. If this is specified

> >> > as

> >> > + *               ODP_PACKET_INVALID, this call is equivalent to

> >> > + *               odp_packet_ref().

> >> > + *

> >> > + * @return       Handle of the reference packet. This may or may not

> be

> >> > the

> >> > + *               same as the input hdr packet. The caller should only

> >> > use this

> >> > + *               handle since the original hdr packet no longer has

> any

> >> > + *               independent existence.

> >> > + *

> >> > + * @retval ODP_PACKET_INVALID If the reference failed. In this case

> >> > both pkt

> >> > + *                            and hdr are unchanged.

> >> > + *

> >> > + * @note Either packet input to this routine may itself be a

> reference,

> >> > + *       however individual implementations MAY impose limits on how

> >> > deeply

> >> > + *       splices may be nested and fail the call if those limits are

> >> > exceeded.

> >> > + *

> >> > + * @note The packets used as input to this routine may reside in

> >> > different

> >> > + *       pools, however individual implementations MAY require that

> >> > both

> >> > + *       reside in the same pool and fail the call if this

> restriction

> >> > is not

> >> > + *       observed. odp_packet_pool() on the returned reference

> returns

> >> > the

> >> > + *       pool id of the header packet.

> >> > + */

> >> > +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,

> >> > +                               odp_packet_t hdr);

> >>

> >> Creating reference at specified offset becomes tricky if multiple

> >> references are created at multiple offsets in the same segment and

> >> referred by different packet headers. Amount of segment meta data is

> >> limited and since there is no limit on the number of different offsets

> >> created in the segment, each reference of the segment could have

> >> different offsets and there is a need for large amount of meta data at

> >> each segment header.

> >

> >

> > Is it sufficient to limit the number of references that can be created

> on a

> > given base packet and/or the number of different offsets that can be

> used?

>

> Maybe this could simplify the implementation but not sure if

> application will be able to confront to this limitation.

> >

> >>

> >>

> >> Since this API is used in fast path the efficiency would become an

> >> issue if the same is implemented using packet copy.

> >

> >

> > I agree. I'd rather see a reference operation fail and let the

> application

> > do copies if needed rather than silently copying things behind the scenes

> > resulting in unpredictable performance. ODP already has a rich set of

> APIs

> > that support partial or complete packet copying. The whole purpose of

> these

> > APIs is to promote sharing. If the implementation cannot offer sharing

> under

> > some conditions than it's better to live with that then to pretend that

> > sharing is happening when it isn't.

>

> Regarding the question of offset value it is reasonable to assume that

> the offset will be near the head of the packet.

> Coz the current API definition allows the offset to be from 0 to

> (packet_length -1)  but the most likely use-case will be to use

> multiple headers with common data and the offset value might be

> smaller compared to the packet length.

>


Yes, that would be the expected case, however the implementation is free to
fail the request if the offset is too big for it. I assume you'd like to
restrict the offset to residing within the first segment of the base packet?


>

> -Bala

> >

> >>

> >>

> >> Regards,

> >> Bala

> >> > +

> >> > +/**

> >> > + * Test if a packet is a reference

> >> > + *

> >> > + * A packet is a reference if it was created by odp_packet_ref_xxx().

> >> > + * Note that a reference created from another reference is considered

> >> > + * a compound reference.

> >> > + *

> >> > + * @param pkt Packet handle

> >> > + *

> >> > + * @retval 0  Packet is not a reference

> >> > + * @retval >0 Packet is a reference consisting of N individual

> packets.

> >> > + */

> >> > +int odp_packet_is_a_ref(odp_packet_t pkt);

> >> > +

> >> > +/**

> >> > + * Test if a packet is referenced

> >> > + *

> >> > + * A packet is referenced if a reference was created on it by

> >> > + * odp_packet_ref_xxx().

> >> > + *

> >> > + * @param pkt Packet handle

> >> > + *

> >> > + * @retval 0  Packet is not referenced

> >> > + * @retval >0 Packet is N references based on it

> >> > + */

> >> > +int odp_packet_is_referenced(odp_packet_t pkt);

> >> > +

> >> > +/*

> >> > + *

> >> >   * Copy

> >> >   * ********************************************************

> >> >   *

> >> > --

> >> > 2.7.4

> >> >

> >

> >

>
Balasubramanian Manoharan Oct. 27, 2016, 2:09 p.m. UTC | #5
Regards,
Bala


On 27 October 2016 at 19:38, Bill Fischofer <bill.fischofer@linaro.org> wrote:
>

>

> On Thu, Oct 27, 2016 at 7:26 AM, Bala Manoharan <bala.manoharan@linaro.org>

> wrote:

>>

>> On 26 October 2016 at 23:17, Bill Fischofer <bill.fischofer@linaro.org>

>> wrote:

>> >

>> >

>> > On Wed, Oct 26, 2016 at 12:19 PM, Bala Manoharan

>> > <bala.manoharan@linaro.org>

>> > wrote:

>> >>

>> >> On 26 October 2016 at 07:26, Bill Fischofer <bill.fischofer@linaro.org>

>> >> wrote:

>> >> > Add the following five packet APIs:

>> >> >

>> >> > - odp_packet_ref_static()

>> >> > - odp_packet_ref()

>> >> > - odp_packet_ref_pkt()

>> >> > - odp_packet_is_a_ref()

>> >> > - odp_packet_is_referenced()

>> >> >

>> >> > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

>> >> > ---

>> >> >  include/odp/api/spec/packet.h | 143

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

>> >> >  1 file changed, 143 insertions(+)

>> >> >

>> >> > diff --git a/include/odp/api/spec/packet.h

>> >> > b/include/odp/api/spec/packet.h

>> >> > index 4a14f2d..7e347c5 100644

>> >> > --- a/include/odp/api/spec/packet.h

>> >> > +++ b/include/odp/api/spec/packet.h

>> >> > @@ -846,6 +846,149 @@ int odp_packet_split(odp_packet_t *pkt,

>> >> > uint32_t

>> >> > len, odp_packet_t *tail);

>> >> >

>> >> >  /*

>> >> >   *

>> >> > + * References

>> >> > + * ********************************************************

>> >> > + *

>> >> > + */

>> >> > +

>> >> > +/**

>> >> > + * Create a static reference to a packet

>> >> > + *

>> >> > + * Create a (shared) reference to a base packet. A static reference

>> >> > is

>> >> > used to

>> >> > + * retain a copy of the packet so that the storage behind it is not

>> >> > freed

>> >> > + * until all references to the packet are freed. This can be used,

>> >> > for

>> >> > + * example, to support efficient retransmission processing.

>> >> > + *

>> >> > + * @param pkt    Handle of the base packet for which a static

>> >> > reference

>> >> > is

>> >> > + *               to be created.

>> >> > + *

>> >> > + * @return                    Handle of the reference packet

>> >> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

>> >> > unchanged.

>> >> > + *

>> >> > + * @note The intent of a static reference is that both the base

>> >> > packet

>> >> > and the

>> >> > + *       returned reference should be treated as read-only after

>> >> > this

>> >> > + *       call. Results are unpredictable if this restriction is not

>> >> > observed.

>> >> > + *

>> >> > + * @note Static references have restrictions but may have

>> >> > performance

>> >> > + *       advantages on some platforms if the caller does not intend

>> >> > to

>> >> > modify

>> >> > + *       the reference packet. If modification is needed (e.g., to

>> >> > prefix a

>> >> > + *       unique header onto the packet) then odp_packet_ref() should

>> >> > be

>> >> > used.

>> >> > + */

>> >> > +odp_packet_t odp_packet_ref_static(odp_packet_t pkt);

>> >> > +

>> >> > +/**

>> >> > + * Create a reference to a packet

>> >> > + *

>> >> > + * Create a (shared) reference to a base packet starting at a

>> >> > specified

>> >> > byte

>> >> > + * offset. This reference may be used as an argument to header

>> >> > manipulation

>> >> > + * APIs to prefix a unique header onto the shared base. The storage

>> >> > associated

>> >> > + * with the base packet is not freed until all references to it are

>> >> > freed,

>> >> > + * which permits easy multicasting or retransmission processing to

>> >> > be

>> >> > + * performed.

>> >> > + *

>> >> > + * @param pkt    Handle of the base packet for which a reference is

>> >> > to

>> >> > be

>> >> > + *               created.

>> >> > + *

>> >> > + * @param offset Byte offset in the base packet at which the shared

>> >> > reference

>> >> > + *               is to begin. Must be in the range

>> >> > 0..odp_packet_len(pkt)-1.

>> >> > + *

>> >> > + * @return                    Handle of the reference packet

>> >> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet remains

>> >> > unchanged.

>> >> > + *

>> >> > + * @note This operation prepends a zero-length header onto the base

>> >> > packet

>> >> > + *       beginning at the specified offset. This header is always

>> >> > drawn

>> >> > from

>> >> > + *       the same pool as the base packet.

>> >> > + *

>> >> > + * @note Because references are unique packets, any bytes pushed

>> >> > onto

>> >> > the head

>> >> > + *       of a reference via odp_packet_push_head() or

>> >> > odp_packet_extend_head()

>> >> > + *       are unique to this reference and are not seen by any other

>> >> > reference

>> >> > + *       to the same base packet.

>> >> > + *

>> >> > + * @note The base pkt used as input to this routine may itself by a

>> >> > reference

>> >> > + *       to some other base packet. Implementations MAY restrict the

>> >> > ability

>> >> > + *       to create such compound references. Attempts to exceed any

>> >> > + *       implementation limits in this regard will result in this

>> >> > call

>> >> > failing

>> >> > + *       and returning ODP_PACKET_INVALID.

>> >> > + *

>> >> > + * @note If the caller does not indend to push a header onto the

>> >> > returned

>> >> > + *       reference, the odp_packet_ref_static() API may be used.

>> >> > This

>> >> > may be a

>> >> > + *       more efficient means of obtaining another reference to a

>> >> > base

>> >> > packet

>> >> > + *       that will be treated as read-only.

>> >> > + */

>> >> > +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);

>> >> > +

>> >> > +/**

>> >> > + * Create a reference to another packet from a header packet

>> >> > + *

>> >> > + * Create a (shared) reference to a base packet starting at a

>> >> > specified

>> >> > byte

>> >> > + * offset by prepending a header packet. The resulting reference

>> >> > consists of

>> >> > + * the unshared header followed by the shared base packet starting

>> >> > at

>> >> > the

>> >> > + * specified offset. This shared portion should be regarded as

>> >> > read-only. The

>> >> > + * storage associated with the shared portion of the reference is

>> >> > not

>> >> > freed

>> >> > + * until all references to it are freed, which permits easy

>> >> > multicasting or

>> >> > + * retransmission processing to be performed.

>> >> > + *

>> >> > + * @param pkt    Handle of the base packet for which a reference is

>> >> > to

>> >> > be

>> >> > + *               created.

>> >> > + *

>> >> > + * @param offset Byte offset in the base packet at which the shared

>> >> > reference

>> >> > + *               to begin. Must be in the range

>> >> > 0..odp_packet_len(pkt)-1.

>> >> > + *

>> >> > + * @param hdr    Handle of the header packet to be prefixed onto the

>> >> > base

>> >> > + *               packet to create the reference. If this is

>> >> > specified

>> >> > as

>> >> > + *               ODP_PACKET_INVALID, this call is equivalent to

>> >> > + *               odp_packet_ref().

>> >> > + *

>> >> > + * @return       Handle of the reference packet. This may or may not

>> >> > be

>> >> > the

>> >> > + *               same as the input hdr packet. The caller should

>> >> > only

>> >> > use this

>> >> > + *               handle since the original hdr packet no longer has

>> >> > any

>> >> > + *               independent existence.

>> >> > + *

>> >> > + * @retval ODP_PACKET_INVALID If the reference failed. In this case

>> >> > both pkt

>> >> > + *                            and hdr are unchanged.

>> >> > + *

>> >> > + * @note Either packet input to this routine may itself be a

>> >> > reference,

>> >> > + *       however individual implementations MAY impose limits on how

>> >> > deeply

>> >> > + *       splices may be nested and fail the call if those limits are

>> >> > exceeded.

>> >> > + *

>> >> > + * @note The packets used as input to this routine may reside in

>> >> > different

>> >> > + *       pools, however individual implementations MAY require that

>> >> > both

>> >> > + *       reside in the same pool and fail the call if this

>> >> > restriction

>> >> > is not

>> >> > + *       observed. odp_packet_pool() on the returned reference

>> >> > returns

>> >> > the

>> >> > + *       pool id of the header packet.

>> >> > + */

>> >> > +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,

>> >> > +                               odp_packet_t hdr);

>> >>

>> >> Creating reference at specified offset becomes tricky if multiple

>> >> references are created at multiple offsets in the same segment and

>> >> referred by different packet headers. Amount of segment meta data is

>> >> limited and since there is no limit on the number of different offsets

>> >> created in the segment, each reference of the segment could have

>> >> different offsets and there is a need for large amount of meta data at

>> >> each segment header.

>> >

>> >

>> > Is it sufficient to limit the number of references that can be created

>> > on a

>> > given base packet and/or the number of different offsets that can be

>> > used?

>>

>> Maybe this could simplify the implementation but not sure if

>> application will be able to confront to this limitation.

>> >

>> >>

>> >>

>> >> Since this API is used in fast path the efficiency would become an

>> >> issue if the same is implemented using packet copy.

>> >

>> >

>> > I agree. I'd rather see a reference operation fail and let the

>> > application

>> > do copies if needed rather than silently copying things behind the

>> > scenes

>> > resulting in unpredictable performance. ODP already has a rich set of

>> > APIs

>> > that support partial or complete packet copying. The whole purpose of

>> > these

>> > APIs is to promote sharing. If the implementation cannot offer sharing

>> > under

>> > some conditions than it's better to live with that then to pretend that

>> > sharing is happening when it isn't.

>>

>> Regarding the question of offset value it is reasonable to assume that

>> the offset will be near the head of the packet.

>> Coz the current API definition allows the offset to be from 0 to

>> (packet_length -1)  but the most likely use-case will be to use

>> multiple headers with common data and the offset value might be

>> smaller compared to the packet length.

>

>

> Yes, that would be the expected case, however the implementation is free to

> fail the request if the offset is too big for it. I assume you'd like to

> restrict the offset to residing within the first segment of the base packet?


Yes. First segment would be ideal, but I would like to know the
application use-case also.

-Bala
>

>>

>>

>> -Bala

>> >

>> >>

>> >>

>> >> Regards,

>> >> Bala

>> >> > +

>> >> > +/**

>> >> > + * Test if a packet is a reference

>> >> > + *

>> >> > + * A packet is a reference if it was created by

>> >> > odp_packet_ref_xxx().

>> >> > + * Note that a reference created from another reference is

>> >> > considered

>> >> > + * a compound reference.

>> >> > + *

>> >> > + * @param pkt Packet handle

>> >> > + *

>> >> > + * @retval 0  Packet is not a reference

>> >> > + * @retval >0 Packet is a reference consisting of N individual

>> >> > packets.

>> >> > + */

>> >> > +int odp_packet_is_a_ref(odp_packet_t pkt);

>> >> > +

>> >> > +/**

>> >> > + * Test if a packet is referenced

>> >> > + *

>> >> > + * A packet is referenced if a reference was created on it by

>> >> > + * odp_packet_ref_xxx().

>> >> > + *

>> >> > + * @param pkt Packet handle

>> >> > + *

>> >> > + * @retval 0  Packet is not referenced

>> >> > + * @retval >0 Packet is N references based on it

>> >> > + */

>> >> > +int odp_packet_is_referenced(odp_packet_t pkt);

>> >> > +

>> >> > +/*

>> >> > + *

>> >> >   * Copy

>> >> >   * ********************************************************

>> >> >   *

>> >> > --

>> >> > 2.7.4

>> >> >

>> >

>> >

>

>
Bill Fischofer Oct. 27, 2016, 2:12 p.m. UTC | #6
On Thu, Oct 27, 2016 at 9:09 AM, Bala Manoharan <bala.manoharan@linaro.org>
wrote:

> Regards,

> Bala

>

>

> On 27 October 2016 at 19:38, Bill Fischofer <bill.fischofer@linaro.org>

> wrote:

> >

> >

> > On Thu, Oct 27, 2016 at 7:26 AM, Bala Manoharan <

> bala.manoharan@linaro.org>

> > wrote:

> >>

> >> On 26 October 2016 at 23:17, Bill Fischofer <bill.fischofer@linaro.org>

> >> wrote:

> >> >

> >> >

> >> > On Wed, Oct 26, 2016 at 12:19 PM, Bala Manoharan

> >> > <bala.manoharan@linaro.org>

> >> > wrote:

> >> >>

> >> >> On 26 October 2016 at 07:26, Bill Fischofer <

> bill.fischofer@linaro.org>

> >> >> wrote:

> >> >> > Add the following five packet APIs:

> >> >> >

> >> >> > - odp_packet_ref_static()

> >> >> > - odp_packet_ref()

> >> >> > - odp_packet_ref_pkt()

> >> >> > - odp_packet_is_a_ref()

> >> >> > - odp_packet_is_referenced()

> >> >> >

> >> >> > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

> >> >> > ---

> >> >> >  include/odp/api/spec/packet.h | 143

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

> >> >> >  1 file changed, 143 insertions(+)

> >> >> >

> >> >> > diff --git a/include/odp/api/spec/packet.h

> >> >> > b/include/odp/api/spec/packet.h

> >> >> > index 4a14f2d..7e347c5 100644

> >> >> > --- a/include/odp/api/spec/packet.h

> >> >> > +++ b/include/odp/api/spec/packet.h

> >> >> > @@ -846,6 +846,149 @@ int odp_packet_split(odp_packet_t *pkt,

> >> >> > uint32_t

> >> >> > len, odp_packet_t *tail);

> >> >> >

> >> >> >  /*

> >> >> >   *

> >> >> > + * References

> >> >> > + * ********************************************************

> >> >> > + *

> >> >> > + */

> >> >> > +

> >> >> > +/**

> >> >> > + * Create a static reference to a packet

> >> >> > + *

> >> >> > + * Create a (shared) reference to a base packet. A static

> reference

> >> >> > is

> >> >> > used to

> >> >> > + * retain a copy of the packet so that the storage behind it is

> not

> >> >> > freed

> >> >> > + * until all references to the packet are freed. This can be used,

> >> >> > for

> >> >> > + * example, to support efficient retransmission processing.

> >> >> > + *

> >> >> > + * @param pkt    Handle of the base packet for which a static

> >> >> > reference

> >> >> > is

> >> >> > + *               to be created.

> >> >> > + *

> >> >> > + * @return                    Handle of the reference packet

> >> >> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet

> remains

> >> >> > unchanged.

> >> >> > + *

> >> >> > + * @note The intent of a static reference is that both the base

> >> >> > packet

> >> >> > and the

> >> >> > + *       returned reference should be treated as read-only after

> >> >> > this

> >> >> > + *       call. Results are unpredictable if this restriction is

> not

> >> >> > observed.

> >> >> > + *

> >> >> > + * @note Static references have restrictions but may have

> >> >> > performance

> >> >> > + *       advantages on some platforms if the caller does not

> intend

> >> >> > to

> >> >> > modify

> >> >> > + *       the reference packet. If modification is needed (e.g., to

> >> >> > prefix a

> >> >> > + *       unique header onto the packet) then odp_packet_ref()

> should

> >> >> > be

> >> >> > used.

> >> >> > + */

> >> >> > +odp_packet_t odp_packet_ref_static(odp_packet_t pkt);

> >> >> > +

> >> >> > +/**

> >> >> > + * Create a reference to a packet

> >> >> > + *

> >> >> > + * Create a (shared) reference to a base packet starting at a

> >> >> > specified

> >> >> > byte

> >> >> > + * offset. This reference may be used as an argument to header

> >> >> > manipulation

> >> >> > + * APIs to prefix a unique header onto the shared base. The

> storage

> >> >> > associated

> >> >> > + * with the base packet is not freed until all references to it

> are

> >> >> > freed,

> >> >> > + * which permits easy multicasting or retransmission processing to

> >> >> > be

> >> >> > + * performed.

> >> >> > + *

> >> >> > + * @param pkt    Handle of the base packet for which a reference

> is

> >> >> > to

> >> >> > be

> >> >> > + *               created.

> >> >> > + *

> >> >> > + * @param offset Byte offset in the base packet at which the

> shared

> >> >> > reference

> >> >> > + *               is to begin. Must be in the range

> >> >> > 0..odp_packet_len(pkt)-1.

> >> >> > + *

> >> >> > + * @return                    Handle of the reference packet

> >> >> > + * @retval ODP_PACKET_INVALID Operation failed. Base packet

> remains

> >> >> > unchanged.

> >> >> > + *

> >> >> > + * @note This operation prepends a zero-length header onto the

> base

> >> >> > packet

> >> >> > + *       beginning at the specified offset. This header is always

> >> >> > drawn

> >> >> > from

> >> >> > + *       the same pool as the base packet.

> >> >> > + *

> >> >> > + * @note Because references are unique packets, any bytes pushed

> >> >> > onto

> >> >> > the head

> >> >> > + *       of a reference via odp_packet_push_head() or

> >> >> > odp_packet_extend_head()

> >> >> > + *       are unique to this reference and are not seen by any

> other

> >> >> > reference

> >> >> > + *       to the same base packet.

> >> >> > + *

> >> >> > + * @note The base pkt used as input to this routine may itself by

> a

> >> >> > reference

> >> >> > + *       to some other base packet. Implementations MAY restrict

> the

> >> >> > ability

> >> >> > + *       to create such compound references. Attempts to exceed

> any

> >> >> > + *       implementation limits in this regard will result in this

> >> >> > call

> >> >> > failing

> >> >> > + *       and returning ODP_PACKET_INVALID.

> >> >> > + *

> >> >> > + * @note If the caller does not indend to push a header onto the

> >> >> > returned

> >> >> > + *       reference, the odp_packet_ref_static() API may be used.

> >> >> > This

> >> >> > may be a

> >> >> > + *       more efficient means of obtaining another reference to a

> >> >> > base

> >> >> > packet

> >> >> > + *       that will be treated as read-only.

> >> >> > + */

> >> >> > +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);

> >> >> > +

> >> >> > +/**

> >> >> > + * Create a reference to another packet from a header packet

> >> >> > + *

> >> >> > + * Create a (shared) reference to a base packet starting at a

> >> >> > specified

> >> >> > byte

> >> >> > + * offset by prepending a header packet. The resulting reference

> >> >> > consists of

> >> >> > + * the unshared header followed by the shared base packet starting

> >> >> > at

> >> >> > the

> >> >> > + * specified offset. This shared portion should be regarded as

> >> >> > read-only. The

> >> >> > + * storage associated with the shared portion of the reference is

> >> >> > not

> >> >> > freed

> >> >> > + * until all references to it are freed, which permits easy

> >> >> > multicasting or

> >> >> > + * retransmission processing to be performed.

> >> >> > + *

> >> >> > + * @param pkt    Handle of the base packet for which a reference

> is

> >> >> > to

> >> >> > be

> >> >> > + *               created.

> >> >> > + *

> >> >> > + * @param offset Byte offset in the base packet at which the

> shared

> >> >> > reference

> >> >> > + *               to begin. Must be in the range

> >> >> > 0..odp_packet_len(pkt)-1.

> >> >> > + *

> >> >> > + * @param hdr    Handle of the header packet to be prefixed onto

> the

> >> >> > base

> >> >> > + *               packet to create the reference. If this is

> >> >> > specified

> >> >> > as

> >> >> > + *               ODP_PACKET_INVALID, this call is equivalent to

> >> >> > + *               odp_packet_ref().

> >> >> > + *

> >> >> > + * @return       Handle of the reference packet. This may or may

> not

> >> >> > be

> >> >> > the

> >> >> > + *               same as the input hdr packet. The caller should

> >> >> > only

> >> >> > use this

> >> >> > + *               handle since the original hdr packet no longer

> has

> >> >> > any

> >> >> > + *               independent existence.

> >> >> > + *

> >> >> > + * @retval ODP_PACKET_INVALID If the reference failed. In this

> case

> >> >> > both pkt

> >> >> > + *                            and hdr are unchanged.

> >> >> > + *

> >> >> > + * @note Either packet input to this routine may itself be a

> >> >> > reference,

> >> >> > + *       however individual implementations MAY impose limits on

> how

> >> >> > deeply

> >> >> > + *       splices may be nested and fail the call if those limits

> are

> >> >> > exceeded.

> >> >> > + *

> >> >> > + * @note The packets used as input to this routine may reside in

> >> >> > different

> >> >> > + *       pools, however individual implementations MAY require

> that

> >> >> > both

> >> >> > + *       reside in the same pool and fail the call if this

> >> >> > restriction

> >> >> > is not

> >> >> > + *       observed. odp_packet_pool() on the returned reference

> >> >> > returns

> >> >> > the

> >> >> > + *       pool id of the header packet.

> >> >> > + */

> >> >> > +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t

> offset,

> >> >> > +                               odp_packet_t hdr);

> >> >>

> >> >> Creating reference at specified offset becomes tricky if multiple

> >> >> references are created at multiple offsets in the same segment and

> >> >> referred by different packet headers. Amount of segment meta data is

> >> >> limited and since there is no limit on the number of different

> offsets

> >> >> created in the segment, each reference of the segment could have

> >> >> different offsets and there is a need for large amount of meta data

> at

> >> >> each segment header.

> >> >

> >> >

> >> > Is it sufficient to limit the number of references that can be created

> >> > on a

> >> > given base packet and/or the number of different offsets that can be

> >> > used?

> >>

> >> Maybe this could simplify the implementation but not sure if

> >> application will be able to confront to this limitation.

> >> >

> >> >>

> >> >>

> >> >> Since this API is used in fast path the efficiency would become an

> >> >> issue if the same is implemented using packet copy.

> >> >

> >> >

> >> > I agree. I'd rather see a reference operation fail and let the

> >> > application

> >> > do copies if needed rather than silently copying things behind the

> >> > scenes

> >> > resulting in unpredictable performance. ODP already has a rich set of

> >> > APIs

> >> > that support partial or complete packet copying. The whole purpose of

> >> > these

> >> > APIs is to promote sharing. If the implementation cannot offer sharing

> >> > under

> >> > some conditions than it's better to live with that then to pretend

> that

> >> > sharing is happening when it isn't.

> >>

> >> Regarding the question of offset value it is reasonable to assume that

> >> the offset will be near the head of the packet.

> >> Coz the current API definition allows the offset to be from 0 to

> >> (packet_length -1)  but the most likely use-case will be to use

> >> multiple headers with common data and the offset value might be

> >> smaller compared to the packet length.

> >

> >

> > Yes, that would be the expected case, however the implementation is free

> to

> > fail the request if the offset is too big for it. I assume you'd like to

> > restrict the offset to residing within the first segment of the base

> packet?

>

> Yes. First segment would be ideal, but I would like to know the

> application use-case also.

>


The main application use case is to support things like multicast, so the
expectation is that you'd be prepending individual headers on a common
payload, which should be the bulk of the packet. Since headers are expected
to reside within the first segment of the packet in the vast majority of
cases, I don't think this should represent an unreasonable limitation in
practice.


>

> -Bala

> >

> >>

> >>

> >> -Bala

> >> >

> >> >>

> >> >>

> >> >> Regards,

> >> >> Bala

> >> >> > +

> >> >> > +/**

> >> >> > + * Test if a packet is a reference

> >> >> > + *

> >> >> > + * A packet is a reference if it was created by

> >> >> > odp_packet_ref_xxx().

> >> >> > + * Note that a reference created from another reference is

> >> >> > considered

> >> >> > + * a compound reference.

> >> >> > + *

> >> >> > + * @param pkt Packet handle

> >> >> > + *

> >> >> > + * @retval 0  Packet is not a reference

> >> >> > + * @retval >0 Packet is a reference consisting of N individual

> >> >> > packets.

> >> >> > + */

> >> >> > +int odp_packet_is_a_ref(odp_packet_t pkt);

> >> >> > +

> >> >> > +/**

> >> >> > + * Test if a packet is referenced

> >> >> > + *

> >> >> > + * A packet is referenced if a reference was created on it by

> >> >> > + * odp_packet_ref_xxx().

> >> >> > + *

> >> >> > + * @param pkt Packet handle

> >> >> > + *

> >> >> > + * @retval 0  Packet is not referenced

> >> >> > + * @retval >0 Packet is N references based on it

> >> >> > + */

> >> >> > +int odp_packet_is_referenced(odp_packet_t pkt);

> >> >> > +

> >> >> > +/*

> >> >> > + *

> >> >> >   * Copy

> >> >> >   * ********************************************************

> >> >> >   *

> >> >> > --

> >> >> > 2.7.4

> >> >> >

> >> >

> >> >

> >

> >

>
diff mbox

Patch

diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h
index 4a14f2d..7e347c5 100644
--- a/include/odp/api/spec/packet.h
+++ b/include/odp/api/spec/packet.h
@@ -846,6 +846,149 @@  int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail);
 
 /*
  *
+ * References
+ * ********************************************************
+ *
+ */
+
+/**
+ * Create a static reference to a packet
+ *
+ * Create a (shared) reference to a base packet. A static reference is used to
+ * retain a copy of the packet so that the storage behind it is not freed
+ * until all references to the packet are freed. This can be used, for
+ * example, to support efficient retransmission processing.
+ *
+ * @param pkt    Handle of the base packet for which a static reference is
+ *               to be created.
+ *
+ * @return                    Handle of the reference packet
+ * @retval ODP_PACKET_INVALID Operation failed. Base packet remains unchanged.
+ *
+ * @note The intent of a static reference is that both the base packet and the
+ *       returned reference should be treated as read-only after this
+ *       call. Results are unpredictable if this restriction is not observed.
+ *
+ * @note Static references have restrictions but may have performance
+ *       advantages on some platforms if the caller does not intend to modify
+ *       the reference packet. If modification is needed (e.g., to prefix a
+ *       unique header onto the packet) then odp_packet_ref() should be used.
+ */
+odp_packet_t odp_packet_ref_static(odp_packet_t pkt);
+
+/**
+ * Create a reference to a packet
+ *
+ * Create a (shared) reference to a base packet starting at a specified byte
+ * offset. This reference may be used as an argument to header manipulation
+ * APIs to prefix a unique header onto the shared base. The storage associated
+ * with the base packet is not freed until all references to it are freed,
+ * which permits easy multicasting or retransmission processing to be
+ * performed.
+ *
+ * @param pkt    Handle of the base packet for which a reference is to be
+ *               created.
+ *
+ * @param offset Byte offset in the base packet at which the shared reference
+ *               is to begin. Must be in the range 0..odp_packet_len(pkt)-1.
+ *
+ * @return                    Handle of the reference packet
+ * @retval ODP_PACKET_INVALID Operation failed. Base packet remains unchanged.
+ *
+ * @note This operation prepends a zero-length header onto the base packet
+ *       beginning at the specified offset. This header is always drawn from
+ *       the same pool as the base packet.
+ *
+ * @note Because references are unique packets, any bytes pushed onto the head
+ *       of a reference via odp_packet_push_head() or odp_packet_extend_head()
+ *       are unique to this reference and are not seen by any other reference
+ *       to the same base packet.
+ *
+ * @note The base pkt used as input to this routine may itself by a reference
+ *       to some other base packet. Implementations MAY restrict the ability
+ *       to create such compound references. Attempts to exceed any
+ *       implementation limits in this regard will result in this call failing
+ *       and returning ODP_PACKET_INVALID.
+ *
+ * @note If the caller does not indend to push a header onto the returned
+ *       reference, the odp_packet_ref_static() API may be used. This may be a
+ *       more efficient means of obtaining another reference to a base packet
+ *       that will be treated as read-only.
+ */
+odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);
+
+/**
+ * Create a reference to another packet from a header packet
+ *
+ * Create a (shared) reference to a base packet starting at a specified byte
+ * offset by prepending a header packet. The resulting reference consists of
+ * the unshared header followed by the shared base packet starting at the
+ * specified offset. This shared portion should be regarded as read-only. The
+ * storage associated with the shared portion of the reference is not freed
+ * until all references to it are freed, which permits easy multicasting or
+ * retransmission processing to be performed.
+ *
+ * @param pkt    Handle of the base packet for which a reference is to be
+ *               created.
+ *
+ * @param offset Byte offset in the base packet at which the shared reference
+ *               to begin. Must be in the range 0..odp_packet_len(pkt)-1.
+ *
+ * @param hdr    Handle of the header packet to be prefixed onto the base
+ *               packet to create the reference. If this is specified as
+ *               ODP_PACKET_INVALID, this call is equivalent to
+ *               odp_packet_ref().
+ *
+ * @return       Handle of the reference packet. This may or may not be the
+ *               same as the input hdr packet. The caller should only use this
+ *               handle since the original hdr packet no longer has any
+ *               independent existence.
+ *
+ * @retval ODP_PACKET_INVALID If the reference failed. In this case both pkt
+ *                            and hdr are unchanged.
+ *
+ * @note Either packet input to this routine may itself be a reference,
+ *       however individual implementations MAY impose limits on how deeply
+ *       splices may be nested and fail the call if those limits are exceeded.
+ *
+ * @note The packets used as input to this routine may reside in different
+ *       pools, however individual implementations MAY require that both
+ *       reside in the same pool and fail the call if this restriction is not
+ *       observed. odp_packet_pool() on the returned reference returns the
+ *       pool id of the header packet.
+ */
+odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,
+				odp_packet_t hdr);
+
+/**
+ * Test if a packet is a reference
+ *
+ * A packet is a reference if it was created by odp_packet_ref_xxx().
+ * Note that a reference created from another reference is considered
+ * a compound reference.
+ *
+ * @param pkt Packet handle
+ *
+ * @retval 0  Packet is not a reference
+ * @retval >0 Packet is a reference consisting of N individual packets.
+ */
+int odp_packet_is_a_ref(odp_packet_t pkt);
+
+/**
+ * Test if a packet is referenced
+ *
+ * A packet is referenced if a reference was created on it by
+ * odp_packet_ref_xxx().
+ *
+ * @param pkt Packet handle
+ *
+ * @retval 0  Packet is not referenced
+ * @retval >0 Packet is N references based on it
+ */
+int odp_packet_is_referenced(odp_packet_t pkt);
+
+/*
+ *
  * Copy
  * ********************************************************
  *