Thanks for clarification. Regarding the sharing, is 0 specifying that the
application does not require sharing or is a requirement for that segment
to be private?

Alex


On 22 October 2014 16:18, Savolainen, Petri (NSN - FI/Espoo) <
[email protected]> wrote:

>  0 is the default => with current flag definitions: both SW + HW can
> access,  not shared with external processes.
>
>
>
> -Petri
>
>
>
> *From:* ext Alexandru Badicioiu [mailto:[email protected]]
> *Sent:* Wednesday, October 22, 2014 4:01 PM
> *To:* Ciprian Barbu
> *Cc:* Bill Fischofer; Savolainen, Petri (NSN - FI/Espoo);
> [email protected]
>
> *Subject:* Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support API
>
>
>
> The option of creating buffer pools out of memory regions does not solve
> existing applications portability problem. The odp_pktio application
> expects packets to be allocated in shared memory regions. Is this a
> semantic that should be satisfied by all platforms?
>
>  odp_shm_create takes a flag argument which has two values for
> linux-generic:
>
> /*
>
>  * Shared memory flags
>
>  */
>
>
>
> /* Share level */
>
> #define ODP_SHM_SW_ONLY 0x1 /**< Application SW only, no HW access */
>
> #define ODP_SHM_PROC    0x2 /**< Share with external processes */
>
>
>
> but odp_pktio uses 0. Could we assume that this value has a kind of
> ODP_SHM_PACKET meaning?
>
> We could also explicitly extend this flag list to work across platforms.
>
>
>
> Alex
>
>
>
>
>
>
>
>
>
>
>
> On 22 October 2014 14:59, Ciprian Barbu <[email protected]> wrote:
>
> On Wed, Oct 22, 2014 at 2:47 PM, Ciprian Barbu <[email protected]>
> wrote:
> > This thread has been cold for 5 days, so the assumption is that we can
> > go forward with the design right now. This patch series proposed by
> > Bala updates some part of the API to the final form of the Buffer
> > Design Document, we should have it merged if there are no more
> > objections. For that more people with the right expertise should have
> > a look at it and get the thread back on track.
> >
> > I for example have observed the following issue. All the examples
> > create buffer pools over shared memory, which doesn't make sense for
> > some platforms, linux-dpdk for example, which ignores the base_addr
> > argument altogether. I think we need more clarity on this subject, for
> > sure the creation of buffer pools will differ from platform to
> > platform, which migrates to the application responsibility.
> >
> > I think we should have a helper function to easily create buffer pools
> > without worrying too much about the difference in buffer management
> > between platforms, so that one can write a simple portable application
> > with no sweat. For the hardcore programmers the API still gives fine
> > control to buffer management that depending on the platform could
> > involve additional prerequisites, like creating a shared memory
> > segment to hold the buffer pool.
>
> Ok, so I had another look at the Buffer Management final design. I now
> see that the option of creating buffer pools from regions has been
> removed, so in this case things will be simpler for the applications.
> In other words we should really start working on the full
> implementation of the API because from there the problem I just stated
> above (having to create shared memory segments) will disappear.
>
>
> >
> > On Fri, Oct 17, 2014 at 4:33 PM, Bill Fischofer
> > <[email protected]> wrote:
> >> Let's consider the implications of removing segmentation support from
> >> buffers and only having that concept be part of packets.
> >>
> >> The first question that arises is what is the relationship between the
> >> abstract types odp_packet_t and odp_buffer_t? This is important because
> >> currently we say that packets are allocated from ODP buffer pools, not
> from
> >> packet pools.  Do we need a separate odp_packet_pool_t that is used for
> >> packets?
> >>
> >> Today, when I allocate a packet I'm allocating a single object that
> happens
> >> to be a single buffer object of type ODP_BUFFER_TYPE_PACKET.  But that
> only
> >> works if the two objects have compatible semantics (including
> segmentation).
> >> If the semantics are not compatible, then an odp_packet_t may in fact be
> >> composed of multiple odp_buffer_t's because the packet may consist of
> >> multiple segments and buffers no longer recognize the concept of
> segments so
> >> a single buffer can only be a single segment.
> >>
> >> So now an odp_packet_segment_t may be an odp_buffer_t but an
> odp_packet_t in
> >> fact is some meta-object that is constructed (by whom?) from multiple
> >> odp_packet_segment_ts that are themselves odp_buffer_ts.  So
> >> odp_packet_to_buffer() no longer makes sense since there is no longer a
> >> one-to-one correspondence between packets and buffers.  We could have an
> >> odp_packet_segment_to_buffer() routine instead.
> >>
> >> Next question: What about meta data?  If an odp_packet_t is a type of an
> >> odp_buffer_t then this is very straightforward since all buffer meta
> data is
> >> reusable as packet meta data and the packet type can just add its own
> >> specific meta data to this set.  But if an odp_packet_t is now a
> separate
> >> object then where does the storage for its meta data come from? If we
> try to
> >> map it into an odp_buffer_t that doesn't work since an odp_packet_t may
> >> consist of multiple underlying odp_buffer_ts, one for each
> >> odp_packet_segment_t.  Is the packet meta data duplicated in each
> segment?
> >> Is the first segment of a packet special (odp_packet_first_segment_t)?
> And
> >> what about user meta data, since this is of potentially variable size?
> >>
> >> I submit that there are a lot of implications to this that need to be
> fully
> >> thought through, which is why I believe it's simpler to keep
> segmentation as
> >> part of buffers that (for now) only happens to be used by a particular
> type
> >> of buffer, namely packets.
> >>
> >> Bill
> >>
> >> On Fri, Oct 17, 2014 at 8:05 AM, Ola Liljedahl <
> [email protected]>
> >> wrote:
> >>>
> >>> Personally I don't see any need for segmentation support in buffers. I
> am
> >>> just trying to shoot down what I think is flawed reasoning.
> >>>
> >>> -- Ola#1
> >>>
> >>> On 17 October 2014 15:03, Ola Liljedahl <[email protected]>
> wrote:
> >>>>
> >>>> But segmentation is already needed in a current and known subclass
> (i.e.
> >>>> packets). We are not talking about some other feature which we don't
> know if
> >>>> it will be needed. So this is not a case of "just in case".
> >>>>
> >>>> -- Ola#1
> >>>>
> >>>>
> >>>> On 17 October 2014 14:45, Ola Dahl <[email protected]> wrote:
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>> I do not think it is wise to put features in the base class "just in
> >>>>> case" they would be needed in some future (not yet known) subclass.
> >>>>>
> >>>>> So if the concept of segmentation is relevant for packets but not for
> >>>>> timers then I think it should be implemented as a feature of packets.
> >>>>>
> >>>>> Best regards,
> >>>>>
> >>>>> Ola D
> >>>>>
> >>>>> On Fri, Oct 17, 2014 at 2:33 PM, Bill Fischofer
> >>>>> <[email protected]> wrote:
> >>>>>>
> >>>>>> I agree that packets are the buffer type that most likely uses
> >>>>>> segments, however there are many advantages to putting this support
> in the
> >>>>>> base class rather than the subclass independent of the number of
> buffer
> >>>>>> subclasses that will use this support today.
> >>>>>>
> >>>>>> It's simpler
> >>>>>> It's more extensible
> >>>>>> It results in cleaner and more efficient application code
> >>>>>>
> >>>>>> Allow me to expand on these points.  First simplicity.  Call the
> work
> >>>>>> required to support segmentation in the implementation X.  That X
> is going
> >>>>>> to be pretty much constant no matter where it is done.  But if the
> >>>>>> implementation has a choice between doing X at a low level vs.
> doing it at a
> >>>>>> high level then it's simpler for the implementation to do it once
> and be
> >>>>>> done with it.  If the implementation does it at a higher level then
> it is
> >>>>>> either constrained to map that higher-level implementation to be
> built on a
> >>>>>> set of lower-level functions that may or may not be appropriate or
> else it
> >>>>>> needs to do a completely parallel implementation that is optimal
> but highly
> >>>>>> duplicative.
> >>>>>>
> >>>>>> Extensibility should be clear.  If at some future point we decide
> >>>>>> segmentation would be useful for some new buffer type (e.g., IPC)
> then
> >>>>>> that's trivial to do if the base class supports it and awkward if
> it's only
> >>>>>> part of packets.
> >>>>>>
> >>>>>> From an application standpoint, it's cleaner because the packet APIs
> >>>>>> are just wrappers around their corresponding buffer APIs and can be
> mapped
> >>>>>> directly.  Otherwise we have a set of APIs that don't map and are
> not easily
> >>>>>> translatable.
> >>>>>>
> >>>>>> With regard to efficient segment access, that's what the
> >>>>>> odp_packet_addr() routine provides--one-step fast-path
> addressability to the
> >>>>>> first segment of a packet.  An odp_packet_t is an abstract opaque
> type.  It
> >>>>>> is not, and cannot be treated as an address by the application.
> >>>>>>
> >>>>>> Does that make sense?
> >>>>>>
> >>>>>> Bill
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On Fri, Oct 17, 2014 at 5:37 AM, Savolainen, Petri (NSN - FI/Espoo)
> >>>>>> <[email protected]> wrote:
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 1. The only segmentation use case is for segmented packet, not for
> >>>>>>> segmented buffers.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 2. Common case for packets is that everything application needs is
> in
> >>>>>>> the first segment. Odp_packet_t could refer always into that “first
> >>>>>>> segment”, so that application (in the common case) would not need
> to use
> >>>>>>> odp_packet_seg_xxx() calls at all – only odp_packet_xxx() calls.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> When buffer level features are minimized, the need for
> >>>>>>> odp_buffer_xxx(odp_packet_to_buffer(pkt),...) is minimized. All
> packet
> >>>>>>> manipulation should happen through odp_packet_xxx(pkt, …) calls.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> -Petri
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> From: ext Bill Fischofer [mailto:[email protected]]
> >>>>>>> Sent: Friday, October 17, 2014 1:17 PM
> >>>>>>> To: Savolainen, Petri (NSN - FI/Espoo)
> >>>>>>> Cc: ext Jacob, Jerin; [email protected]
> >>>>>>>
> >>>>>>>
> >>>>>>> Subject: Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support
> API
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> I'm not sure how to understand these two statements:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 1. There's no use case for segmented buffers
> >>>>>>>
> >>>>>>> 2. We should optimize for the common case (with segments)
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> These seem contradictory.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> The use case for segmented buffers is that some platforms have a
> >>>>>>> HW-defined and managed segmented buffer model. If we insist that
> the
> >>>>>>> application be able to specify and control packet segment sizes we
> are
> >>>>>>> making the decision to exclude such platforms from supporting
> ODP.  The
> >>>>>>> optimization suggested is precisely what is being proposed here.
> By default
> >>>>>>> packets are assumed to be contained in implementation-managed
> segmented
> >>>>>>> buffers and the first segment will be large enough to contain all
> packet
> >>>>>>> headers for non-pathological cases.  The case where the
> application wishes
> >>>>>>> to traverse the entire packet in SW is expected to be rare because
> in the
> >>>>>>> data plane you simply do not have the cycles to do this at line
> rate for all
> >>>>>>> packets.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> As for having both odp_buffer_xxx() and odp_packet_xxx() APIs,
> this is
> >>>>>>> simply syntax to avoid the constant need for explicit conversion
> functions
> >>>>>>> since unlike C++, C does not support generic functions.  So you
> cannot pass
> >>>>>>> an odp_packet_t to a function that expects an odp_buffer_t
> argument without
> >>>>>>> a conversion call.  Do we really want to force applications to
> constantly be
> >>>>>>> writing code like:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> odp_buffer_xxx(odp_packet_to_buffer(pkt),...)
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> rather than
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> odp_packet_xxx(pkt,...)
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> Not only is this awkward, it is also inefficient.  By having the
> >>>>>>> explicit odp_packet_xxx() calls, the implementation is free to
> optimize
> >>>>>>> these references in whatever manner is appropriate to that
> implementation.
> >>>>>>> For some this may be a simple preprocessor-type expansion while
> for others
> >>>>>>> there may be more sophisticated handling.  But the application
> should
> >>>>>>> neither know nor care about how the implementation chooses to do
> this.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On Fri, Oct 17, 2014 at 2:27 AM, Savolainen, Petri (NSN - FI/Espoo)
> >>>>>>> <[email protected]> wrote:
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> This is also my opinion. There’s no use case for segmented buffers
> in
> >>>>>>> v1.0 - so let’s keep it simple and define that buffers (and thus
> buffer
> >>>>>>> pools) are always unsegmented. Segmentation comes into play only
> with
> >>>>>>> packets (and only with those packets that cannot fit into a single
> buffer).
> >>>>>>> For example, if implementation has max buffer size 256, any
> packets larger
> >>>>>>> than that are segmented and segments are handled with
> packet_seg_xxx calls.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> Also, I’d propose that we optimize for the common case (with
> segments)
> >>>>>>> - so that the odp_packet_t handle would refer always to the head
> of packet
> >>>>>>> segment. If the first segment (data/data_len pointed by the
> odp_packet_t)
> >>>>>>> carries all data application is interested in (=protocol headers),
> the
> >>>>>>> application would not have to use the segment API at all. Most
> applications
> >>>>>>> would not see any difference between small/large or
> segmented/unsegmented
> >>>>>>> packets as long as all headers fit into the first segment.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> -Petri
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> From: [email protected]
> >>>>>>> [mailto:[email protected]] On Behalf Of ext Jacob,
> Jerin
> >>>>>>> Sent: Friday, October 17, 2014 9:34 AM
> >>>>>>> To: Bill Fischofer
> >>>>>>> Cc: [email protected]
> >>>>>>> Subject: Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support
> API
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> The need for segment API infrastructure is very clear.The question
> is,
> >>>>>>> Do we need separate APIs for
> >>>>>>>
> >>>>>>> segment management at odp_buffer_segment* AND odp_packet_segment*
> >>>>>>> levels ?
> >>>>>>>
> >>>>>>> as ODP_BUFFER_TYPE_TIMEOUT and ODP_BUFFER_TYPE_RAW will be always
> >>>>>>> unsegmented and if there is a
> >>>>>>>
> >>>>>>> API for odp_packet_segement* then there will be not be any consumer
> >>>>>>> for odp_buffer_segment* API for 1.0
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> ________________________________
> >>>>>>>
> >>>>>>> From: Bill Fischofer <[email protected]>
> >>>>>>> Sent: Thursday, October 16, 2014 9:08 PM
> >>>>>>> To: Jacob, Jerin
> >>>>>>> Cc: Ola Liljedahl; Balasubramanian Manoharan;
> [email protected]
> >>>>>>> Subject: Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support
> API
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> From the buffer design doc (p. 8-9):
> >>>>>>>
> >>>>>>> Buffer Pool Options
> >>>>>>>
> >>>>>>> The odp_buffer_opts_e enum is used to specify additional options
> >>>>>>> relating to the buffer pool.  Buffer pool options defined are:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> ·     ODP_BUFFER_OPTS_NONE
> >>>>>>>
> >>>>>>> ·     ODP_BUFFER_OPTS_UNSEGMENTED
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> These options are additive so an application can simply specify a
> >>>>>>> buf_opts by ORing together the options needed.  Note that buffer
> pool
> >>>>>>> options are themselves OPTIONAL and a given implementation MAY
> fail the
> >>>>>>> buffer pool creation request with an appropriate errno if the
> requested
> >>>>>>> option is not supported by the underlying ODP implementation, with
> the
> >>>>>>> exception that UNSEGMENTED pools MUST be supported for non-packet
> types and
> >>>>>>> for packet types as long as the requested size is less than the
> >>>>>>> implementation-defined native packet segment size.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> Use ODP_BUFFER_OPTS_NONE to specify default buffer pool options
> with
> >>>>>>> no additions.  The ODP_BUFFER_OPTS_UNSEGMENTED option specifies
> that the
> >>>>>>> buffer pool should be unsegmented.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> So unsegmented buffer pool support is available.  As far as RAW
> >>>>>>> buffers go, again from the doc (p. 14):
> >>>>>>>
> >>>>>>> ODP_BUFFER_TYPE_RAW
> >>>>>>>
> >>>>>>> This is the “basic” buffer type which simply consists of a single
> >>>>>>> fixed-sized block of contiguous memory.  Buffers of this type do
> not support
> >>>>>>> user meta data and the only built-in meta data supported for this
> type of
> >>>>>>> buffer are those that are statically computable, such as pool and
> size. This
> >>>>>>> type of buffer is entirely under application control and most of
> the buffer
> >>>>>>> APIs defined in this document are not available.  APIs for this
> type of
> >>>>>>> buffer are described in this document.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> So RAW buffers are always unsegmented.  The intent is that Packets
> are
> >>>>>>> by default segmented but can be unsegmented while the other buffer
> types are
> >>>>>>> by default unsegmented but (with the exception of RAW buffers) can
> be made
> >>>>>>> segmented.  This is because all buffers start out as a single
> segment and
> >>>>>>> hence are unsegmented until they are expanded to overflow that
> single
> >>>>>>> segment.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> Hope that clarifies things.  Again, this is all very
> straightforward
> >>>>>>> and only comes into play when actually needed.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On Wed, Oct 8, 2014 at 4:03 AM, Jacob, Jerin
> >>>>>>> <[email protected]> wrote:
> >>>>>>>
> >>>>>>> If there is no valid use case for supporting segmentation for raw
> >>>>>>> buffers then lets drop it. At least it will reduce the effort of
> >>>>>>>
> >>>>>>> implementing and testing/verification buffer APIs on  different
> >>>>>>> platforms.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> ________________________________
> >>>>>>>
> >>>>>>> From: [email protected]
> >>>>>>> <[email protected]> on behalf of Ola Liljedahl
> >>>>>>> <[email protected]>
> >>>>>>> Sent: Wednesday, October 8, 2014 1:37 PM
> >>>>>>> To: Balasubramanian Manoharan
> >>>>>>> Cc: [email protected]
> >>>>>>> Subject: Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support
> API
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> As I wrote in my comment to the architecture discussion yesterday,
> I
> >>>>>>> am against segmentation for buffers. Or at least there must be the
> >>>>>>> possibility to create a buffer pool with guaranteed non-segmented
> buffers.
> >>>>>>> Segmented packets are OK but not all usages for buffers relate to
> packets. A
> >>>>>>> lot of internal usages (timeouts, SW messages, internal data
> structures)
> >>>>>>> will not be able to handle segmented buffers so you must be able
> to force
> >>>>>>> the creation of buffer pools with non-segmented buffers.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> -- Ola
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On 8 October 2014 09:50, Balasubramanian Manoharan
> >>>>>>> <[email protected]> wrote:
> >>>>>>>
> >>>>>>> This patch contains ODP Buffer Management missing APIs
> >>>>>>> The intent of this patch is to port the missing APIs from Buffer
> >>>>>>> Management design document into Linux-generic repo.
> >>>>>>> The dummy functions will be replaced during linux-generic
> >>>>>>> implementation.
> >>>>>>>
> >>>>>>> Signed-off-by: Balasubramanian Manoharan <
> [email protected]>
> >>>>>>> ---
> >>>>>>>  platform/linux-generic/include/api/odp_buffer.h    | 203
> >>>>>>> ++++++++++++++++++++-
> >>>>>>>  .../linux-generic/include/api/odp_buffer_pool.h    |  30 +++
> >>>>>>>  platform/linux-generic/odp_buffer.c                | 120
> ++++++++++++
> >>>>>>>  platform/linux-generic/odp_buffer_pool.c           |   7 +
> >>>>>>>  4 files changed, 351 insertions(+), 9 deletions(-)
> >>>>>>>
> >>>>>>> diff --git a/platform/linux-generic/include/api/odp_buffer.h
> >>>>>>> b/platform/linux-generic/include/api/odp_buffer.h
> >>>>>>> index d8577fd..aeb75ed 100644
> >>>>>>> --- a/platform/linux-generic/include/api/odp_buffer.h
> >>>>>>> +++ b/platform/linux-generic/include/api/odp_buffer.h
> >>>>>>> @@ -28,8 +28,34 @@ extern "C" {
> >>>>>>>   */
> >>>>>>>  typedef uint32_t odp_buffer_t;
> >>>>>>>
> >>>>>>> -#define ODP_BUFFER_INVALID (0xffffffff) /**< Invalid buffer */
> >>>>>>> +/**
> >>>>>>> +* ODP buffer segment
> >>>>>>> +*/
> >>>>>>> +typedef uint32_t odp_buffer_segment_t;
> >>>>>>>
> >>>>>>> +/**
> >>>>>>> +* ODP buffer type
> >>>>>>> +*/
> >>>>>>> +typedef enum odp_buffer_type {
> >>>>>>> +       ODP_BUFFER_TYPE_INVALID = -1,   /**< Buffer type invalid */
> >>>>>>> +       ODP_BUFFER_TYPE_ANY = 0,        /**< Buffer that can hold
> any
> >>>>>>> other
> >>>>>>> +                                       buffer type */
> >>>>>>> +       ODP_BUFFER_TYPE_RAW = 1,        /**< Raw buffer,
> >>>>>>> +                                       no additional metadata */
> >>>>>>> +       ODP_BUFFER_TYPE_PACKET = 2,     /**< Packet buffer */
> >>>>>>> +       ODP_BUFFER_TYPE_TIMEOUT = 3     /**< Timeout buffer */
> >>>>>>> +} odp_buffer_type_e;
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> +* ODP buffer options
> >>>>>>> +*/
> >>>>>>> +typedef enum odp_buffer_opts {
> >>>>>>> +       ODP_BUFFER_OPTS_NONE,
> >>>>>>> +       ODP_BUFFER_OPTS_UNSEGMENTED
> >>>>>>> +} odp_buffer_opts_e;
> >>>>>>> +
> >>>>>>> +#define ODP_BUFFER_INVALID (0xffffffff) /**< Invalid buffer */
> >>>>>>> +#define ODP_SEGMENT_INVALID (0xffffffff) /**< Invalid segment */
> >>>>>>>
> >>>>>>>  /**
> >>>>>>>   * Buffer start address
> >>>>>>> @@ -58,14 +84,6 @@ size_t odp_buffer_size(odp_buffer_t buf);
> >>>>>>>   */
> >>>>>>>  int odp_buffer_type(odp_buffer_t buf);
> >>>>>>>
> >>>>>>> -#define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */
> >>>>>>> -#define ODP_BUFFER_TYPE_ANY       0  /**< Buffer that can hold any
> >>>>>>> other
> >>>>>>> -                                         buffer type */
> >>>>>>> -#define ODP_BUFFER_TYPE_RAW       1  /**< Raw buffer, no
> additional
> >>>>>>> metadata */
> >>>>>>> -#define ODP_BUFFER_TYPE_PACKET    2  /**< Packet buffer */
> >>>>>>> -#define ODP_BUFFER_TYPE_TIMEOUT   3  /**< Timeout buffer */
> >>>>>>> -
> >>>>>>> -
> >>>>>>>  /**
> >>>>>>>   * Tests if buffer is valid
> >>>>>>>   *
> >>>>>>> @@ -76,6 +94,110 @@ int odp_buffer_type(odp_buffer_t buf);
> >>>>>>>  int odp_buffer_is_valid(odp_buffer_t buf);
> >>>>>>>
> >>>>>>>  /**
> >>>>>>> + * Tests if buffer is segmented
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle
> >>>>>>> + *
> >>>>>>> + * @return             1 if buffer has more than one segment,
> >>>>>>> + *                     otherwise 0
> >>>>>>> + */
> >>>>>>> +
> >>>>>>> +int odp_buffer_is_segmented(odp_buffer_t buf);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Get address and size of user meta data associated with a buffer
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf             Buffer handle
> >>>>>>> + * @param[out] udata_size      Number of bytes of user meta data
> >>>>>>> available
> >>>>>>> + *                             at the returned address
> >>>>>>> + * @return                     Address of the user meta data for
> this
> >>>>>>> buffer
> >>>>>>> + *                             or NULL if the buffer has no user
> meta
> >>>>>>> data.
> >>>>>>> + */
> >>>>>>> +void *odp_buffer_udata(odp_buffer_t buf, size_t *udata_size);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Get address of user meta data associated with a buffer
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle
> >>>>>>> + *
> >>>>>>> + * @return             Address of the user meta data for this
> buffer
> >>>>>>> + *                     or NULL if the buffer has no user meta
> data.
> >>>>>>> + */
> >>>>>>> +void *odp_buffer_udata_addr(odp_buffer_t buf);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Get count of number of segments in a buffer
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle
> >>>>>>> + *
> >>>>>>> + * @return             Count of the number of segments in buf
> >>>>>>> + */
> >>>>>>> +size_t odp_buffer_segment_count(odp_buffer_t buf);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Get the segment identifier for a buffer segment by index
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle
> >>>>>>> + * @param[in]  ndx     Segment index of segment of interest
> >>>>>>> + *
> >>>>>>> + * @return             Segment identifier or ODP_SEGMENT_INVALID
> if
> >>>>>>> the
> >>>>>>> + *                     supplied ndx is out of range.
> >>>>>>> + */
> >>>>>>> +odp_buffer_segment_t odp_buffer_segment_by_index(odp_buffer_t buf,
> >>>>>>> size_t ndx);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Get the next segment identifier for a buffer segment
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle
> >>>>>>> + * @param[in]  seg     Segment identifier of the previous segment
> >>>>>>> + *
> >>>>>>> + * @return             Segment identifier of the next segment,
> >>>>>>> +                       or ODP_SEGMENT_INVALID.
> >>>>>>> + */
> >>>>>>> +odp_buffer_segment_t odp_buffer_segment_next(odp_buffer_t buf,
> >>>>>>> +                                            odp_buffer_segment_t
> >>>>>>> seg);
> >>>>>>> +/**
> >>>>>>> + * Get start address for a specified buffer segment
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle
> >>>>>>> + * @param[in]  seg     Segment identifier of the buffer to be
> >>>>>>> addressed
> >>>>>>> + * @param[out] seglen  Returned number of bytes in this buffer
> >>>>>>> + *                     segment available at returned address
> >>>>>>> + *
> >>>>>>> + * @return             Segment start address or NULL
> >>>>>>> + */
> >>>>>>> +void *odp_buffer_segment_map(odp_buffer_t buf,
> odp_buffer_segment_t
> >>>>>>> seg,
> >>>>>>> +size_t *seglen);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + *Unmap a buffer segment
> >>>>>>> + *
> >>>>>>> + * @param[in]  seg     Buffer segment handle
> >>>>>>> + */
> >>>>>>> +void odp_buffer_segment_unmap(odp_buffer_segment_t seg);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> +* Get start address for a specified buffer offset
> >>>>>>> +*
> >>>>>>> +* @param[in]   buf     Buffer handle
> >>>>>>> +* @param[in]   offset  Byte offset within the buffer to be
> addressed
> >>>>>>> +* @param[out]  seglen  Returned number of bytes in this buffer
> >>>>>>> +*                      segment available at returned address
> >>>>>>> +*
> >>>>>>> +* @return              Offset start address or NULL
> >>>>>>> +*/
> >>>>>>> +void *odp_buffer_offset_map(odp_buffer_t buf, size_t offset,
> >>>>>>> +size_t *seglen);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Unmap a buffer segment by offset
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle
> >>>>>>> + * @param[in]  offset  Buffer offset
> >>>>>>> + */
> >>>>>>> +void odp_buffer_offset_unmap(odp_buffer_t buf, size_t offset);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>>   * Print buffer metadata to STDOUT
> >>>>>>>   *
> >>>>>>>   * @param buf      Buffer handle
> >>>>>>> @@ -83,6 +205,69 @@ int odp_buffer_is_valid(odp_buffer_t buf);
> >>>>>>>   */
> >>>>>>>  void odp_buffer_print(odp_buffer_t buf);
> >>>>>>>
> >>>>>>> +/**
> >>>>>>> + * Split a buffer into two buffers at a specified split point
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Handle of buffer to split
> >>>>>>> + * @param[in]  offset  Byte offset within buf to split buffer
> >>>>>>> + *
> >>>>>>> + * @return             Buffer handle of the created split buffer
> >>>>>>> + */
> >>>>>>> +odp_buffer_t odp_buffer_split(odp_buffer_t buf, size_t offset);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Join two buffers into a single buffer
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf1    Buffer handle of first buffer to join
> >>>>>>> + * @param[in]  buf2    Buffer handle of second buffer to join
> >>>>>>> + *
> >>>>>>> + * @return             Buffer handle of the joined buffer
> >>>>>>> + */
> >>>>>>> +odp_buffer_t odp_buffer_join(odp_buffer_t buf1, odp_buffer_t
> buf2);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Trim a buffer at a specified trim point
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle of buffer to trim
> >>>>>>> + * @param[in]  offset  byte offset within buf to trim
> >>>>>>> + *
> >>>>>>> + * @return             Handle of the trimmed buffer or
> >>>>>>> + *                     ODP_BUFFER_INVALID if the operation was not
> >>>>>>> performed
> >>>>>>> + */
> >>>>>>> +odp_buffer_t odp_buffer_trim(odp_buffer_t buf, size_t offset);
> >>>>>>> +/**
> >>>>>>> + * Extend a buffer for a specified number of bytes
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle of buffer to expand
> >>>>>>> + * @param[in]  ext     size, in bytes, of the extent to add to the
> >>>>>>> + *                     existing buffer.
> >>>>>>> + *
> >>>>>>> + * @return             Handle of the extended buffer or
> >>>>>>> ODP_BUFFER_INVALID
> >>>>>>> + *                     if the operation was not performed
> >>>>>>> + */
> >>>>>>> +odp_buffer_t odp_buffer_extend(odp_buffer_t buf, size_t ext);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Clone a buffer, returning an exact copy of it
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle of buffer to duplicate
> >>>>>>> + *
> >>>>>>> + * @return             Handle of the duplicated buffer or
> >>>>>>> ODP_BUFFER_INVALID
> >>>>>>> + *                     if the operation was not performed
> >>>>>>> + */
> >>>>>>> +odp_buffer_t odp_buffer_clone(odp_buffer_t buf);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * Copy a buffer, returning an exact copy of it
> >>>>>>> + *
> >>>>>>> + * @param[in]  buf     Buffer handle of buffer to copy
> >>>>>>> + *
> >>>>>>> + * @return             Handle of the copied buffer or
> >>>>>>> ODP_BUFFER_INVALID
> >>>>>>> + *                     if the operation was not performed
> >>>>>>> + */
> >>>>>>> +odp_buffer_t odp_buffer_copy(odp_buffer_t buf);
> >>>>>>> +
> >>>>>>> +
> >>>>>>>
> >>>>>>>  #ifdef __cplusplus
> >>>>>>>  }
> >>>>>>> diff --git a/platform/linux-generic/include/api/odp_buffer_pool.h
> >>>>>>> b/platform/linux-generic/include/api/odp_buffer_pool.h
> >>>>>>> index fe88898..f85d96c 100644
> >>>>>>> --- a/platform/linux-generic/include/api/odp_buffer_pool.h
> >>>>>>> +++ b/platform/linux-generic/include/api/odp_buffer_pool.h
> >>>>>>> @@ -52,6 +52,27 @@ odp_buffer_pool_t odp_buffer_pool_create(const
> char
> >>>>>>> *name,
> >>>>>>>
> >>>>>>>
> >>>>>>>  /**
> >>>>>>> + * Get the next buffer pool from its predecessor
> >>>>>>> + *
> >>>>>>> + * @param[in]  pool            Buffer pool handle
> >>>>>>> + * @param[out] name            Name of the pool
> >>>>>>> + *                             (max ODP_BUFFER_POOL_NAME_LEN - 1
> >>>>>>> chars)
> >>>>>>> + * @param[out] udata_size      Size of user meta data used by this
> >>>>>>> pool.
> >>>>>>> + * @param[out] buf_num         Number of buffers contained in this
> >>>>>>> pool
> >>>>>>> + * @param[out] buf_size        Default size of application data in
> >>>>>>> each buffer
> >>>>>>> + * @param[out] buf_type        Buffer type of the pool
> >>>>>>> + * @param[out] buf_opts        Buffer options for this pool
> >>>>>>> + * @param[out] predef          Predefined (1) or Created (0).
> >>>>>>> + *
> >>>>>>> + * @return                     Buffer pool handle
> >>>>>>> + */
> >>>>>>> +odp_buffer_pool_t odp_buffer_pool_next(odp_buffer_pool_t pool,
> >>>>>>> +                                      char *name, size_t
> *udata_size,
> >>>>>>> +                                      size_t *buf_num, size_t
> >>>>>>> *buf_size,
> >>>>>>> +                                      enum odp_buffer_type
> *buf_type,
> >>>>>>> +                                      enum odp_buffer_opts
> *buf_opts,
> >>>>>>> +                                      uint32_t *predef);
> >>>>>>> +/**
> >>>>>>>   * Find a buffer pool by name
> >>>>>>>   *
> >>>>>>>   * @param name      Name of the pool
> >>>>>>> @@ -80,6 +101,15 @@ void odp_buffer_pool_print(odp_buffer_pool_t
> >>>>>>> pool);
> >>>>>>>   */
> >>>>>>>  odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool);
> >>>>>>>
> >>>>>>> +/**
> >>>>>>> +* Allocate a buffer from a buffer pool
> >>>>>>> +*
> >>>>>>> +* @param[in]   pool    Pool handle
> >>>>>>> +* @param[in]   size    Size of object to store in buffer
> >>>>>>> +*
> >>>>>>> +* @return              Buffer handle or ODP_BUFFER_INVALID
> >>>>>>> +*/
> >>>>>>> +odp_buffer_t odp_buffer_alloc_size(odp_buffer_pool_t pool, size_t
> >>>>>>> size);
> >>>>>>>
> >>>>>>>  /**
> >>>>>>>   * Buffer free
> >>>>>>> diff --git a/platform/linux-generic/odp_buffer.c
> >>>>>>> b/platform/linux-generic/odp_buffer.c
> >>>>>>> index e54e0e7..7f4b4f0 100644
> >>>>>>> --- a/platform/linux-generic/odp_buffer.c
> >>>>>>> +++ b/platform/linux-generic/odp_buffer.c
> >>>>>>> @@ -45,6 +45,21 @@ int odp_buffer_is_valid(odp_buffer_t buf)
> >>>>>>>         return (handle.index != ODP_BUFFER_INVALID_INDEX);
> >>>>>>>  }
> >>>>>>>
> >>>>>>> +int odp_buffer_is_segmented(odp_buffer_t buf)
> >>>>>>> +{
> >>>>>>> +       odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf);
> >>>>>>> +
> >>>>>>> +       if (buf_hdr->scatter.num_bufs == 0)
> >>>>>>> +               return 0;
> >>>>>>> +       else
> >>>>>>> +               return 1;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +size_t odp_buffer_segment_count(odp_buffer_t buf)
> >>>>>>> +{
> >>>>>>> +       odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf);
> >>>>>>> +       return (size_t)buf_hdr->scatter.num_bufs + 1;
> >>>>>>> +}
> >>>>>>>
> >>>>>>>  int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf)
> >>>>>>>  {
> >>>>>>> @@ -101,8 +116,113 @@ void odp_buffer_print(odp_buffer_t buf)
> >>>>>>>         printf("\n%s\n", str);
> >>>>>>>  }
> >>>>>>>
> >>>>>>> +void *odp_buffer_udata(odp_buffer_t buf, size_t *udata_size)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)udata_size;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +void *odp_buffer_udata_addr(odp_buffer_t buf)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +odp_buffer_segment_t odp_buffer_segment_by_index(odp_buffer_t buf,
> >>>>>>> +                                                size_t ndx)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)ndx;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +odp_buffer_segment_t odp_buffer_segment_next(odp_buffer_t buf,
> >>>>>>> +                                            odp_buffer_segment_t
> seg)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)seg;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +void *odp_buffer_segment_map(odp_buffer_t buf,
> odp_buffer_segment_t
> >>>>>>> seg,
> >>>>>>> +                            size_t *seglen)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)seg;
> >>>>>>> +       (void)seglen;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +void *odp_buffer_offset_map(odp_buffer_t buf, size_t offset,
> >>>>>>> +size_t *seglen)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)offset;
> >>>>>>> +       (void)seglen;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +void odp_buffer_offset_unmap(odp_buffer_t buf, size_t offset)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)offset;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>>  void odp_buffer_copy_scatter(odp_buffer_t buf_dst, odp_buffer_t
> >>>>>>> buf_src)
> >>>>>>>  {
> >>>>>>>         (void)buf_dst;
> >>>>>>>         (void)buf_src;
> >>>>>>>  }
> >>>>>>> +
> >>>>>>> +odp_buffer_t odp_buffer_split(odp_buffer_t buf, size_t offset)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)offset;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +odp_buffer_t odp_buffer_join(odp_buffer_t buf1, odp_buffer_t buf2)
> >>>>>>> +{
> >>>>>>> +       (void)buf1;
> >>>>>>> +       (void)buf2;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +odp_buffer_t odp_buffer_trim(odp_buffer_t buf, size_t offset)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)offset;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +odp_buffer_t odp_buffer_extend(odp_buffer_t buf, size_t ext)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       (void)ext;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +odp_buffer_t odp_buffer_clone(odp_buffer_t buf)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +odp_buffer_t odp_buffer_copy(odp_buffer_t buf)
> >>>>>>> +{
> >>>>>>> +       (void)buf;
> >>>>>>> +       ODP_UNIMPLEMENTED();
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> diff --git a/platform/linux-generic/odp_buffer_pool.c
> >>>>>>> b/platform/linux-generic/odp_buffer_pool.c
> >>>>>>> index a48d7d6..bff4db5 100644
> >>>>>>> --- a/platform/linux-generic/odp_buffer_pool.c
> >>>>>>> +++ b/platform/linux-generic/odp_buffer_pool.c
> >>>>>>> @@ -471,6 +471,13 @@ odp_buffer_t
> odp_buffer_alloc(odp_buffer_pool_t
> >>>>>>> pool_hdl)
> >>>>>>>         return handle.u32;
> >>>>>>>  }
> >>>>>>>
> >>>>>>> +odp_buffer_t odp_buffer_alloc_size(odp_buffer_pool_t pool, size_t
> >>>>>>> size)
> >>>>>>> +{
> >>>>>>> +       (void)pool;
> >>>>>>> +       (void) size;
> >>>>>>> +       ODP_ERR("%s function is yet to be implemented", __func__);
> >>>>>>> +       return 0;
> >>>>>>> +}
> >>>>>>>
> >>>>>>>  void odp_buffer_free(odp_buffer_t buf)
> >>>>>>>  {
> >>>>>>> --
> >>>>>>> 2.0.1.472.g6f92e5f
> >>>>>>>
> >>>>>>>
> >>>>>>> _______________________________________________
> >>>>>>> lng-odp mailing list
> >>>>>>> [email protected]
> >>>>>>> http://lists.linaro.org/mailman/listinfo/lng-odp
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> _______________________________________________
> >>>>>>> lng-odp mailing list
> >>>>>>> [email protected]
> >>>>>>> http://lists.linaro.org/mailman/listinfo/lng-odp
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> _______________________________________________
> >>>>>> lng-odp mailing list
> >>>>>> [email protected]
> >>>>>> http://lists.linaro.org/mailman/listinfo/lng-odp
> >>>>>>
> >>>>>
> >>>>>
> >>>>> _______________________________________________
> >>>>> lng-odp mailing list
> >>>>> [email protected]
> >>>>> http://lists.linaro.org/mailman/listinfo/lng-odp
> >>>>>
> >>>>
> >>>
> >>
> >>
> >> _______________________________________________
> >> lng-odp mailing list
> >> [email protected]
> >> http://lists.linaro.org/mailman/listinfo/lng-odp
> >>
>
> _______________________________________________
> lng-odp mailing list
> [email protected]
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
>
_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to