diff mbox

ODP Buffer Management support for Scatter-gather list

Message ID 1402960310-11288-1-git-send-email-bala.manoharan@linaro.org
State New
Headers show

Commit Message

Balasubramanian Manoharan June 16, 2014, 11:11 p.m. UTC
From: Bala Manoharan <bala.manoharan@linaro.org>

This patch contains the initial draft of Buffer Management with support for scatter-gather list 

Regards,
Bala

Signed-off-by: Bala Manoharan <bala.manoharan@linaro.org>
---
 include/odp_buffer.h |   73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

Comments

Balasubramanian Manoharan June 16, 2014, 11:51 p.m. UTC | #1
Hi All,

This patch is meant for discussion on scatter-gather buffer support.
The implementation of these functions will be submitted once the proposed
APIs are finalised.

Regards,
Bala


On 16 June 2014 16:11, <bala.manoharan@linaro.org> wrote:

> From: Bala Manoharan <bala.manoharan@linaro.org>
>
> This patch contains the initial draft of Buffer Management with support
> for scatter-gather list
>
> Regards,
> Bala
>
> Signed-off-by: Bala Manoharan <bala.manoharan@linaro.org>
> ---
>  include/odp_buffer.h |   73
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
>
> diff --git a/include/odp_buffer.h b/include/odp_buffer.h
> index d79e76d..c313168 100644
> --- a/include/odp_buffer.h
> +++ b/include/odp_buffer.h
> @@ -92,6 +92,79 @@ int odp_buffer_is_valid(odp_buffer_t buf);
>   */
>  void odp_buffer_print(odp_buffer_t buf);
>
> +/**
> +*Number of segments in this scatter-gather List
> +*
> +*@param buf    Buffer Handle
> +*
> +*@return       Total number of segments in this scatter-gather List.
> +*
> +**/
> +int odp_buffer_segment_count(odp_buffer_t buf)
> +
> +/**
> +*Address of the segment in the buffer list.
> +*
> +*@param buf    Buffer Handle
> +*@param n      Index number for the segment in the SG list
> +*@param size   Returns the size of the current addressable segment
> +
> +*@return       Segment start address
> +**/
> +
> +void* odp_buffer_segment_addr(odp_buffer_t buf, int n, size_t* size);
> +
> +/*
> +*Creates ODP Buffer from a memory region
> +*
> +*@param addr   Address of the memory region
> +*@param size    Size of the memory region
> +*
> +*@return       Buffer Handle to the newly create odp buffer
> +*/
> +odp_buffer_t     odp_buffer_from_memory_region(void* addr, int size );
> +
> +/**
> +* Merge Buffer list into a singe buffer
> +*@param buf    Array of ODP Buffer Handles
> +*@param num    Number of Buffers in the buf Array
> +
> +*@return       Buffer Handle to the newly created odp buffer
> +**/
> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
> +
> +/**
> +* Split a single Buffer into a list of odp buffers
> +*
> +*@param buf    Buffer Handle
> +*
> +*@param        size    Maximum size of the individual buffers
> +*
> +*@return       Array of newly created Buffer Handle
> +**/
> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
> +
> +/**
> +* Append a buffer at the end of a scatter-gather list of buffer
> +*
> +*@param buf    Buffer Handle to the scatter-gather list of buffer
> +*
> +*@param tail   Buffer Handle to the buffer which is appended
> +*
> +*@return       1 if success 0 otherwise
> +**/
> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
> +
> +/**
> +* Add a buffer at the head of a existing Scatter-gather Buffer
> +*
> +*@param buf    Buffer Handle to the scatter-gather list of buffer
> +*
> +*@param head   Buffer Handle to the buffer which is added at the head
> +*
> +*@return       1 if success 0 otherwise
> +**/
> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>
>  #ifdef __cplusplus
>  }
> --
> 1.7.9.5
>
>
Ciprian Barbu June 19, 2014, 9:20 a.m. UTC | #2
Hi,


On Tue, Jun 17, 2014 at 2:51 AM, Bala Manoharan <bala.manoharan@linaro.org>
wrote:

> Hi All,
>
> This patch is meant for discussion on scatter-gather buffer support.
> The implementation of these functions will be submitted once the proposed
> APIs are finalised.
>
> Regards,
> Bala
>
>
> On 16 June 2014 16:11, <bala.manoharan@linaro.org> wrote:
>
>> From: Bala Manoharan <bala.manoharan@linaro.org>
>>
>> This patch contains the initial draft of Buffer Management with support
>> for scatter-gather list
>>
>> Regards,
>> Bala
>>
>> Signed-off-by: Bala Manoharan <bala.manoharan@linaro.org>
>> ---
>>  include/odp_buffer.h |   73
>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 73 insertions(+)
>>
>> diff --git a/include/odp_buffer.h b/include/odp_buffer.h
>> index d79e76d..c313168 100644
>> --- a/include/odp_buffer.h
>> +++ b/include/odp_buffer.h
>> @@ -92,6 +92,79 @@ int odp_buffer_is_valid(odp_buffer_t buf);
>>   */
>>  void odp_buffer_print(odp_buffer_t buf);
>>
>> +/**
>> +*Number of segments in this scatter-gather List
>> +*
>> +*@param buf    Buffer Handle
>> +*
>> +*@return       Total number of segments in this scatter-gather List.
>> +*
>> +**/
>> +int odp_buffer_segment_count(odp_buffer_t buf)
>> +
>> +/**
>> +*Address of the segment in the buffer list.
>> +*
>> +*@param buf    Buffer Handle
>> +*@param n      Index number for the segment in the SG list
>> +*@param size   Returns the size of the current addressable segment
>> +
>> +*@return       Segment start address
>> +**/
>> +
>> +void* odp_buffer_segment_addr(odp_buffer_t buf, int n, size_t* size);
>> +
>> +/*
>> +*Creates ODP Buffer from a memory region
>> +*
>> +*@param addr   Address of the memory region
>> +*@param size    Size of the memory region
>> +*
>> +*@return       Buffer Handle to the newly create odp buffer
>> +*/
>> +odp_buffer_t     odp_buffer_from_memory_region(void* addr, int size );
>>
>
We should keep consistent with buffer sizes, odp_buffer_size for instance
returns a size_t. Also, does this assume that the data will be copied, so
that the user can safely free the memory area pointed to by addr?

+
>> +/**
>> +* Merge Buffer list into a singe buffer
>> +*@param buf    Array of ODP Buffer Handles
>> +*@param num    Number of Buffers in the buf Array
>> +
>> +*@return       Buffer Handle to the newly created odp buffer
>> +**/
>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>> +
>>
>
Which pool should the resulting buffer be allocated from? Will there be an
SG list in the resulting buffer or just one big chunk?


> +/**
>> +* Split a single Buffer into a list of odp buffers
>> +*
>> +*@param buf    Buffer Handle
>> +*
>> +*@param        size    Maximum size of the individual buffers
>> +*
>> +*@return       Array of newly created Buffer Handle
>> +**/
>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>
>
This doesn't seem entirely related to SG support. Is there zero-copy here?

> +
>> +/**
>> +* Append a buffer at the end of a scatter-gather list of buffer
>> +*
>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>> +*
>> +*@param tail   Buffer Handle to the buffer which is appended
>> +*
>> +*@return       1 if success 0 otherwise
>> +**/
>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>
> +
>> +/**
>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>> +*
>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>> +*
>> +*@param head   Buffer Handle to the buffer which is added at the head
>> +*
>> +*@return       1 if success 0 otherwise
>> +**/
>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>
>
It's not clear to me whether we should support scatter-gather lists made
out of odp buffers or random memory. Surely it is easier to work with odp
buffers only, but that may not be enough for our purposes.

/Ciprian


>>  #ifdef __cplusplus
>>  }
>> --
>> 1.7.9.5
>>
>>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
Balasubramanian Manoharan June 19, 2014, 4:32 p.m. UTC | #3
Hi Ciprian,

Pls find my reply inline

We should keep consistent with buffer sizes, odp_buffer_size for instance
returns a size_t. Also, does this assume that the data will be copied, so
that the user can safely free the memory area pointed to by addr?

[Bala] Agreed. The return should be size_t. The data will be associated
with the Buffer Handle returned by the function. Hence it will get freed
when the buffer Handle is freed.

> +
>> +/**
>> +* Merge Buffer list into a singe buffer
>> +*@param buf    Array of ODP Buffer Handles
>> +*@param num    Number of Buffers in the buf Array
>> +
>> +*@return       Buffer Handle to the newly created odp buffer
>> +**/
>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>> +
>>
>
Which pool should the resulting buffer be allocated from? Will there be an
SG list in the resulting buffer or just one big chunk?
 [Bala] During Merging the individual buffers will be converted into a SG
list. There will not be any requirement for a buffer pool.

 +/**
>> +* Split a single Buffer into a list of odp buffers
>> +*
>> +*@param buf    Buffer Handle
>> +*
>> +*@param        size    Maximum size of the individual buffers
>> +*
>> +*@return       Array of newly created Buffer Handle
>> +**/
>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>
>
This doesn't seem entirely related to SG support. Is there zero-copy here?
[Bala]  This requirement is to support the scenario for fragmenting a
packet.
Ideally this should be implemented using zero-copy but we can get opinion
of all the HW vendors and finalize the same.

>  +
>> +/**
>> +* Append a buffer at the end of a scatter-gather list of buffer
>> +*
>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>> +*
>> +*@param tail   Buffer Handle to the buffer which is appended
>> +*
>> +*@return       1 if success 0 otherwise
>> +**/
>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>
>  +
>> +/**
>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>> +*
>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>> +*
>> +*@param head   Buffer Handle to the buffer which is added at the head
>> +*
>> +*@return       1 if success 0 otherwise
>> +**/
>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>
>
It's not clear to me whether we should support scatter-gather lists made
out of odp buffers or random memory. Surely it is easier to work with odp
buffers only, but that may not be enough for our purposes.
[Bala]  Scatter-gather lists were considered to be made up of odp buffers.
If you have any additional requirements or suggestions pls provide.


Regards,
Bala


On 19 June 2014 02:20, Ciprian Barbu <ciprian.barbu@linaro.org> wrote:

> Hi,
>
>
> On Tue, Jun 17, 2014 at 2:51 AM, Bala Manoharan <bala.manoharan@linaro.org
> > wrote:
>
>> Hi All,
>>
>> This patch is meant for discussion on scatter-gather buffer support.
>> The implementation of these functions will be submitted once the proposed
>> APIs are finalised.
>>
>> Regards,
>> Bala
>>
>>
>> On 16 June 2014 16:11, <bala.manoharan@linaro.org> wrote:
>>
>>> From: Bala Manoharan <bala.manoharan@linaro.org>
>>>
>>> This patch contains the initial draft of Buffer Management with support
>>> for scatter-gather list
>>>
>>> Regards,
>>> Bala
>>>
>>> Signed-off-by: Bala Manoharan <bala.manoharan@linaro.org>
>>> ---
>>>  include/odp_buffer.h |   73
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 73 insertions(+)
>>>
>>> diff --git a/include/odp_buffer.h b/include/odp_buffer.h
>>> index d79e76d..c313168 100644
>>> --- a/include/odp_buffer.h
>>> +++ b/include/odp_buffer.h
>>> @@ -92,6 +92,79 @@ int odp_buffer_is_valid(odp_buffer_t buf);
>>>   */
>>>  void odp_buffer_print(odp_buffer_t buf);
>>>
>>> +/**
>>> +*Number of segments in this scatter-gather List
>>> +*
>>> +*@param buf    Buffer Handle
>>> +*
>>> +*@return       Total number of segments in this scatter-gather List.
>>> +*
>>> +**/
>>> +int odp_buffer_segment_count(odp_buffer_t buf)
>>> +
>>> +/**
>>> +*Address of the segment in the buffer list.
>>> +*
>>> +*@param buf    Buffer Handle
>>> +*@param n      Index number for the segment in the SG list
>>> +*@param size   Returns the size of the current addressable segment
>>> +
>>> +*@return       Segment start address
>>> +**/
>>> +
>>> +void* odp_buffer_segment_addr(odp_buffer_t buf, int n, size_t* size);
>>> +
>>> +/*
>>> +*Creates ODP Buffer from a memory region
>>> +*
>>> +*@param addr   Address of the memory region
>>> +*@param size    Size of the memory region
>>> +*
>>> +*@return       Buffer Handle to the newly create odp buffer
>>> +*/
>>> +odp_buffer_t     odp_buffer_from_memory_region(void* addr, int size );
>>>
>>
> We should keep consistent with buffer sizes, odp_buffer_size for instance
> returns a size_t. Also, does this assume that the data will be copied, so
> that the user can safely free the memory area pointed to by addr?
>
> +
>>> +/**
>>> +* Merge Buffer list into a singe buffer
>>> +*@param buf    Array of ODP Buffer Handles
>>> +*@param num    Number of Buffers in the buf Array
>>> +
>>> +*@return       Buffer Handle to the newly created odp buffer
>>> +**/
>>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>>> +
>>>
>>
> Which pool should the resulting buffer be allocated from? Will there be an
> SG list in the resulting buffer or just one big chunk?
>
>
>> +/**
>>> +* Split a single Buffer into a list of odp buffers
>>> +*
>>> +*@param buf    Buffer Handle
>>> +*
>>> +*@param        size    Maximum size of the individual buffers
>>> +*
>>> +*@return       Array of newly created Buffer Handle
>>> +**/
>>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>>
>>
> This doesn't seem entirely related to SG support. Is there zero-copy here?
>
>>  +
>>> +/**
>>> +* Append a buffer at the end of a scatter-gather list of buffer
>>> +*
>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>> +*
>>> +*@param tail   Buffer Handle to the buffer which is appended
>>> +*
>>> +*@return       1 if success 0 otherwise
>>> +**/
>>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>>
>>  +
>>> +/**
>>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>>> +*
>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>> +*
>>> +*@param head   Buffer Handle to the buffer which is added at the head
>>> +*
>>> +*@return       1 if success 0 otherwise
>>> +**/
>>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>>
>>
> It's not clear to me whether we should support scatter-gather lists made
> out of odp buffers or random memory. Surely it is easier to work with odp
> buffers only, but that may not be enough for our purposes.
>
> /Ciprian
>
>
>>>  #ifdef __cplusplus
>>>  }
>>> --
>>> 1.7.9.5
>>>
>>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>>
>
Ciprian Barbu June 20, 2014, 9:42 a.m. UTC | #4
On Thu, Jun 19, 2014 at 7:32 PM, Bala Manoharan <bala.manoharan@linaro.org>
wrote:

> Hi Ciprian,
>
> Pls find my reply inline
>
>
> We should keep consistent with buffer sizes, odp_buffer_size for instance
> returns a size_t. Also, does this assume that the data will be copied, so
> that the user can safely free the memory area pointed to by addr?
>
> [Bala] Agreed. The return should be size_t. The data will be associated
> with the Buffer Handle returned by the function. Hence it will get freed
> when the buffer Handle is freed.
>

Just a clarification, the parameter size should pe of type size_t.
About freeing the memory, if the memory region passed as parameter is not
expected to be of some type, then freeing it (when the resulting buffer is
not needed anymore) should be done through a callback, because only the
user knows how it was allocated (if it was even allocated). This also
introduces problems with ownership and process context.

 +
>>> +/**
>>> +* Merge Buffer list into a singe buffer
>>> +*@param buf    Array of ODP Buffer Handles
>>> +*@param num    Number of Buffers in the buf Array
>>> +
>>> +*@return       Buffer Handle to the newly created odp buffer
>>> +**/
>>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>>> +
>>>
>>
> Which pool should the resulting buffer be allocated from? Will there be an
> SG list in the resulting buffer or just one big chunk?
>  [Bala] During Merging the individual buffers will be converted into a SG
> list. There will not be any requirement for a buffer pool.
>

Yes but you still need to allocate the odp_buffer_t from somewhere, the
metadata of the buffer has to exist somewhere even if the payload is
referenced through a pointer.

>
>  +/**
>>> +* Split a single Buffer into a list of odp buffers
>>> +*
>>> +*@param buf    Buffer Handle
>>> +*
>>> +*@param        size    Maximum size of the individual buffers
>>> +*
>>> +*@return       Array of newly created Buffer Handle
>>> +**/
>>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>>
>>
> This doesn't seem entirely related to SG support. Is there zero-copy here?
> [Bala]  This requirement is to support the scenario for fragmenting a
> packet.
> Ideally this should be implemented using zero-copy but we can get opinion
> of all the HW vendors and finalize the same.
>

If this results in a buffer that contains an SG list, then it would be
better to return the handle to that buffer, rather than an array of
buffers. Is that the intent?


>  +
>>> +/**
>>> +* Append a buffer at the end of a scatter-gather list of buffer
>>> +*
>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>> +*
>>> +*@param tail   Buffer Handle to the buffer which is appended
>>> +*
>>> +*@return       1 if success 0 otherwise
>>> +**/
>>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>>
>>  +
>>> +/**
>>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>>> +*
>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>> +*
>>> +*@param head   Buffer Handle to the buffer which is added at the head
>>> +*
>>> +*@return       1 if success 0 otherwise
>>> +**/
>>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>>
>>
> It's not clear to me whether we should support scatter-gather lists made
> out of odp buffers or random memory. Surely it is easier to work with odp
> buffers only, but that may not be enough for our purposes.
> [Bala]  Scatter-gather lists were considered to be made up of odp buffers.
> If you have any additional requirements or suggestions pls provide.
>

It wasn't clear to me that the SG fragments are made up of odp buffers.
Even if they are random memory that are pointed to by an odp buffer, I
think it would still work better to return the buffer, rather than a
pointer like it is the case with odp_buffer_segment_addr. This function
should in fact return the nth buffer in a SG odp buffer and additionally
introduce an API (if there isn't already one that we can use for that) for
getting a pointer to the payload from a buffer. It would make it clear IMO
that SG support is constructed over odp buffers.

/Ciprian

>
>
> Regards,
> Bala
>
>
> On 19 June 2014 02:20, Ciprian Barbu <ciprian.barbu@linaro.org> wrote:
>
>> Hi,
>>
>>
>> On Tue, Jun 17, 2014 at 2:51 AM, Bala Manoharan <
>> bala.manoharan@linaro.org> wrote:
>>
>>> Hi All,
>>>
>>> This patch is meant for discussion on scatter-gather buffer support.
>>> The implementation of these functions will be submitted once the
>>> proposed APIs are finalised.
>>>
>>> Regards,
>>> Bala
>>>
>>>
>>> On 16 June 2014 16:11, <bala.manoharan@linaro.org> wrote:
>>>
>>>> From: Bala Manoharan <bala.manoharan@linaro.org>
>>>>
>>>> This patch contains the initial draft of Buffer Management with support
>>>> for scatter-gather list
>>>>
>>>> Regards,
>>>> Bala
>>>>
>>>> Signed-off-by: Bala Manoharan <bala.manoharan@linaro.org>
>>>> ---
>>>>  include/odp_buffer.h |   73
>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>  1 file changed, 73 insertions(+)
>>>>
>>>> diff --git a/include/odp_buffer.h b/include/odp_buffer.h
>>>> index d79e76d..c313168 100644
>>>> --- a/include/odp_buffer.h
>>>> +++ b/include/odp_buffer.h
>>>> @@ -92,6 +92,79 @@ int odp_buffer_is_valid(odp_buffer_t buf);
>>>>   */
>>>>  void odp_buffer_print(odp_buffer_t buf);
>>>>
>>>> +/**
>>>> +*Number of segments in this scatter-gather List
>>>> +*
>>>> +*@param buf    Buffer Handle
>>>> +*
>>>> +*@return       Total number of segments in this scatter-gather List.
>>>> +*
>>>> +**/
>>>> +int odp_buffer_segment_count(odp_buffer_t buf)
>>>> +
>>>> +/**
>>>> +*Address of the segment in the buffer list.
>>>> +*
>>>> +*@param buf    Buffer Handle
>>>> +*@param n      Index number for the segment in the SG list
>>>> +*@param size   Returns the size of the current addressable segment
>>>> +
>>>> +*@return       Segment start address
>>>> +**/
>>>> +
>>>> +void* odp_buffer_segment_addr(odp_buffer_t buf, int n, size_t* size);
>>>> +
>>>> +/*
>>>> +*Creates ODP Buffer from a memory region
>>>> +*
>>>> +*@param addr   Address of the memory region
>>>> +*@param size    Size of the memory region
>>>> +*
>>>> +*@return       Buffer Handle to the newly create odp buffer
>>>> +*/
>>>> +odp_buffer_t     odp_buffer_from_memory_region(void* addr, int size );
>>>>
>>>
>> We should keep consistent with buffer sizes, odp_buffer_size for instance
>> returns a size_t. Also, does this assume that the data will be copied, so
>> that the user can safely free the memory area pointed to by addr?
>>
>> +
>>>> +/**
>>>> +* Merge Buffer list into a singe buffer
>>>> +*@param buf    Array of ODP Buffer Handles
>>>> +*@param num    Number of Buffers in the buf Array
>>>> +
>>>> +*@return       Buffer Handle to the newly created odp buffer
>>>> +**/
>>>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>>>> +
>>>>
>>>
>> Which pool should the resulting buffer be allocated from? Will there be
>> an SG list in the resulting buffer or just one big chunk?
>>
>>
>>> +/**
>>>> +* Split a single Buffer into a list of odp buffers
>>>> +*
>>>> +*@param buf    Buffer Handle
>>>> +*
>>>> +*@param        size    Maximum size of the individual buffers
>>>> +*
>>>> +*@return       Array of newly created Buffer Handle
>>>> +**/
>>>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>>>
>>>
>> This doesn't seem entirely related to SG support. Is there zero-copy here?
>>
>>>  +
>>>> +/**
>>>> +* Append a buffer at the end of a scatter-gather list of buffer
>>>> +*
>>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>>> +*
>>>> +*@param tail   Buffer Handle to the buffer which is appended
>>>> +*
>>>> +*@return       1 if success 0 otherwise
>>>> +**/
>>>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>>>
>>>  +
>>>> +/**
>>>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>>>> +*
>>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>>> +*
>>>> +*@param head   Buffer Handle to the buffer which is added at the head
>>>> +*
>>>> +*@return       1 if success 0 otherwise
>>>> +**/
>>>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>>>
>>>
>> It's not clear to me whether we should support scatter-gather lists made
>> out of odp buffers or random memory. Surely it is easier to work with odp
>> buffers only, but that may not be enough for our purposes.
>>
>> /Ciprian
>>
>>
>>>>  #ifdef __cplusplus
>>>>  }
>>>> --
>>>> 1.7.9.5
>>>>
>>>>
>>>
>>> _______________________________________________
>>> lng-odp mailing list
>>> lng-odp@lists.linaro.org
>>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>>
>>
>
Balasubramanian Manoharan June 20, 2014, 4:58 p.m. UTC | #5
Hi,

Reply inline.

Regards,
Bala

Hi Ciprian,
>
> Pls find my reply inline
>
>
> We should keep consistent with buffer sizes, odp_buffer_size for instance
> returns a size_t. Also, does this assume that the data will be copied, so
> that the user can safely free the memory area pointed to by addr?
>
> [Bala] Agreed. The return should be size_t. The data will be associated
> with the Buffer Handle returned by the function. Hence it will get freed
> when the buffer Handle is freed.
>

Just a clarification, the parameter size should pe of type size_t.
About freeing the memory, if the memory region passed as parameter is not
expected to be of some type, then freeing it (when the resulting buffer is
not needed anymore) should be done through a callback, because only the
user knows how it was allocated (if it was even allocated). This also
introduces problems with ownership and process context.

[Bala] Callback mechanism is not supported in ODP. Once the user has
provided the memory region to be converted into a odp_buffer_t, the
ownership of the memory region should be with the implementation rather
than the application as otherwise it creates an issue of how to initiate
the control back to the application once the memory gets freed.
The implementation can create a buffer pool with a single buffer in the
pool out of the given memory region and allocate the odp_buffer_t from it.
 This is my opinion and I am open to other view points.

>  +
>>> +/**
>>> +* Merge Buffer list into a singe buffer
>>> +*@param buf    Array of ODP Buffer Handles
>>> +*@param num    Number of Buffers in the buf Array
>>> +
>>> +*@return       Buffer Handle to the newly created odp buffer
>>> +**/
>>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>>> +
>>>
>>
> Which pool should the resulting buffer be allocated from? Will there be an
> SG list in the resulting buffer or just one big chunk?
>  [Bala] During Merging the individual buffers will be converted into a SG
> list. There will not be any requirement for a buffer pool.
>

Yes but you still need to allocate the odp_buffer_t from somewhere, the
metadata of the buffer has to exist somewhere even if the payload is
referenced through a pointer.
[Bala] The meta-data of the buffer is kept hidden from the application and
the implementation can use any one of the given odp_buffer_t metadata to
fill the information about the remaining odp segments. Basically the
implementation can convert a single odp_buffer_t meta-data to contain the
information of the SG list. zero-copy merging of the buffer will be the
preferred method as there will not be any additional delay involved.

>
>  +/**
>>> +* Split a single Buffer into a list of odp buffers
>>> +*
>>> +*@param buf    Buffer Handle
>>> +*
>>> +*@param        size    Maximum size of the individual buffers
>>> +*
>>> +*@return       Array of newly created Buffer Handle
>>> +**/
>>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>>
>>
> This doesn't seem entirely related to SG support. Is there zero-copy here?
> [Bala]  This requirement is to support the scenario for fragmenting a
> packet.
> Ideally this should be implemented using zero-copy but we can get opinion
> of all the HW vendors and finalize the same.
>

If this results in a buffer that contains an SG list, then it would be
better to return the handle to that buffer, rather than an array of
buffers. Is that the intent?
[Bala] The result of this operation is creation of multiple odp_buffer_t
handles. The idea was to create multiple buffers from the same pool from
which the input buffer was available and create multiple smaller buffers.
If there is a use-case to create multiple buffers from a pool which is
different than the pool of the input buffer, we can add the pool
information as input parameter and create a default value which will be the
same pool as the input buffer.



>  +
>>> +/**
>>> +* Append a buffer at the end of a scatter-gather list of buffer
>>> +*
>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>> +*
>>> +*@param tail   Buffer Handle to the buffer which is appended
>>> +*
>>> +*@return       1 if success 0 otherwise
>>> +**/
>>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>>
>>  +
>>> +/**
>>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>>> +*
>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>> +*
>>> +*@param head   Buffer Handle to the buffer which is added at the head
>>> +*
>>> +*@return       1 if success 0 otherwise
>>> +**/
>>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>>
>>
> It's not clear to me whether we should support scatter-gather lists made
> out of odp buffers or random memory. Surely it is easier to work with odp
> buffers only, but that may not be enough for our purposes.
> [Bala]  Scatter-gather lists were considered to be made up of odp buffers.
> If you have any additional requirements or suggestions pls provide.
>

It wasn't clear to me that the SG fragments are made up of odp buffers.
Even if they are random memory that are pointed to by an odp buffer, I
think it would still work better to return the buffer, rather than a
pointer like it is the case with odp_buffer_segment_addr. This function
should in fact return the nth buffer in a SG odp buffer and additionally
introduce an API (if there isn't already one that we can use for that) for
getting a pointer to the payload from a buffer. It would make it clear IMO
that SG support is constructed over odp buffers.

[Bala] The idea behind this API proposal is to hide the internal details of
the SG list from the application which is a general use-case as the
application does not need to know about the header information within each
of the SG segments but it only needs to know the meta-data in the first
buffer. This proposal maps well with the HWs since the Scatter-gather list
is created from the HW and usually the application does not care about the
internals of each segment header. The application only needs to know the
valid start address and the size of the buffer for the next segment.
If we introduce odp_buffer_t header for each segment of SG list then there
will be additional information stored per segment which is not needed.

These APIs maps well for use-case where the implementation stores the
scatter-gather as a list of complete odp_buffer_t as in those case also the
implementation can manipulate the meta-data and provide the application
with the start of the valid address in each segment and the size which can
be written in each segment.

Regards,
Bala


On 20 June 2014 02:42, Ciprian Barbu <ciprian.barbu@linaro.org> wrote:

>
>
>
> On Thu, Jun 19, 2014 at 7:32 PM, Bala Manoharan <bala.manoharan@linaro.org
> > wrote:
>
>> Hi Ciprian,
>>
>> Pls find my reply inline
>>
>>
>> We should keep consistent with buffer sizes, odp_buffer_size for instance
>> returns a size_t. Also, does this assume that the data will be copied, so
>> that the user can safely free the memory area pointed to by addr?
>>
>> [Bala] Agreed. The return should be size_t. The data will be associated
>> with the Buffer Handle returned by the function. Hence it will get freed
>> when the buffer Handle is freed.
>>
>
> Just a clarification, the parameter size should pe of type size_t.
> About freeing the memory, if the memory region passed as parameter is not
> expected to be of some type, then freeing it (when the resulting buffer is
> not needed anymore) should be done through a callback, because only the
> user knows how it was allocated (if it was even allocated). This also
> introduces problems with ownership and process context.
>
>  +
>>>> +/**
>>>> +* Merge Buffer list into a singe buffer
>>>> +*@param buf    Array of ODP Buffer Handles
>>>> +*@param num    Number of Buffers in the buf Array
>>>> +
>>>> +*@return       Buffer Handle to the newly created odp buffer
>>>> +**/
>>>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>>>> +
>>>>
>>>
>> Which pool should the resulting buffer be allocated from? Will there be
>> an SG list in the resulting buffer or just one big chunk?
>>  [Bala] During Merging the individual buffers will be converted into a SG
>> list. There will not be any requirement for a buffer pool.
>>
>
> Yes but you still need to allocate the odp_buffer_t from somewhere, the
> metadata of the buffer has to exist somewhere even if the payload is
> referenced through a pointer.
>
>>
>>  +/**
>>>> +* Split a single Buffer into a list of odp buffers
>>>> +*
>>>> +*@param buf    Buffer Handle
>>>> +*
>>>> +*@param        size    Maximum size of the individual buffers
>>>> +*
>>>> +*@return       Array of newly created Buffer Handle
>>>> +**/
>>>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>>>
>>>
>> This doesn't seem entirely related to SG support. Is there zero-copy here?
>> [Bala]  This requirement is to support the scenario for fragmenting a
>> packet.
>> Ideally this should be implemented using zero-copy but we can get opinion
>> of all the HW vendors and finalize the same.
>>
>
> If this results in a buffer that contains an SG list, then it would be
> better to return the handle to that buffer, rather than an array of
> buffers. Is that the intent?
>
>
>>  +
>>>> +/**
>>>> +* Append a buffer at the end of a scatter-gather list of buffer
>>>> +*
>>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>>> +*
>>>> +*@param tail   Buffer Handle to the buffer which is appended
>>>> +*
>>>> +*@return       1 if success 0 otherwise
>>>> +**/
>>>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>>>
>>>  +
>>>> +/**
>>>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>>>> +*
>>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>>> +*
>>>> +*@param head   Buffer Handle to the buffer which is added at the head
>>>> +*
>>>> +*@return       1 if success 0 otherwise
>>>> +**/
>>>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>>>
>>>
>> It's not clear to me whether we should support scatter-gather lists made
>> out of odp buffers or random memory. Surely it is easier to work with odp
>> buffers only, but that may not be enough for our purposes.
>> [Bala]  Scatter-gather lists were considered to be made up of odp
>> buffers. If you have any additional requirements or suggestions pls provide.
>>
>
> It wasn't clear to me that the SG fragments are made up of odp buffers.
> Even if they are random memory that are pointed to by an odp buffer, I
> think it would still work better to return the buffer, rather than a
> pointer like it is the case with odp_buffer_segment_addr. This function
> should in fact return the nth buffer in a SG odp buffer and additionally
> introduce an API (if there isn't already one that we can use for that) for
> getting a pointer to the payload from a buffer. It would make it clear IMO
> that SG support is constructed over odp buffers.
>
> /Ciprian
>
>>
>>
>> Regards,
>> Bala
>>
>>
>> On 19 June 2014 02:20, Ciprian Barbu <ciprian.barbu@linaro.org> wrote:
>>
>>> Hi,
>>>
>>>
>>> On Tue, Jun 17, 2014 at 2:51 AM, Bala Manoharan <
>>> bala.manoharan@linaro.org> wrote:
>>>
>>>> Hi All,
>>>>
>>>> This patch is meant for discussion on scatter-gather buffer support.
>>>> The implementation of these functions will be submitted once the
>>>> proposed APIs are finalised.
>>>>
>>>> Regards,
>>>> Bala
>>>>
>>>>
>>>> On 16 June 2014 16:11, <bala.manoharan@linaro.org> wrote:
>>>>
>>>>> From: Bala Manoharan <bala.manoharan@linaro.org>
>>>>>
>>>>> This patch contains the initial draft of Buffer Management with
>>>>> support for scatter-gather list
>>>>>
>>>>> Regards,
>>>>> Bala
>>>>>
>>>>> Signed-off-by: Bala Manoharan <bala.manoharan@linaro.org>
>>>>> ---
>>>>>  include/odp_buffer.h |   73
>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>  1 file changed, 73 insertions(+)
>>>>>
>>>>> diff --git a/include/odp_buffer.h b/include/odp_buffer.h
>>>>> index d79e76d..c313168 100644
>>>>> --- a/include/odp_buffer.h
>>>>> +++ b/include/odp_buffer.h
>>>>> @@ -92,6 +92,79 @@ int odp_buffer_is_valid(odp_buffer_t buf);
>>>>>   */
>>>>>  void odp_buffer_print(odp_buffer_t buf);
>>>>>
>>>>> +/**
>>>>> +*Number of segments in this scatter-gather List
>>>>> +*
>>>>> +*@param buf    Buffer Handle
>>>>> +*
>>>>> +*@return       Total number of segments in this scatter-gather List.
>>>>> +*
>>>>> +**/
>>>>> +int odp_buffer_segment_count(odp_buffer_t buf)
>>>>> +
>>>>> +/**
>>>>> +*Address of the segment in the buffer list.
>>>>> +*
>>>>> +*@param buf    Buffer Handle
>>>>> +*@param n      Index number for the segment in the SG list
>>>>> +*@param size   Returns the size of the current addressable segment
>>>>> +
>>>>> +*@return       Segment start address
>>>>> +**/
>>>>> +
>>>>> +void* odp_buffer_segment_addr(odp_buffer_t buf, int n, size_t* size);
>>>>> +
>>>>> +/*
>>>>> +*Creates ODP Buffer from a memory region
>>>>> +*
>>>>> +*@param addr   Address of the memory region
>>>>> +*@param size    Size of the memory region
>>>>> +*
>>>>> +*@return       Buffer Handle to the newly create odp buffer
>>>>> +*/
>>>>> +odp_buffer_t     odp_buffer_from_memory_region(void* addr, int size );
>>>>>
>>>>
>>> We should keep consistent with buffer sizes, odp_buffer_size for
>>> instance returns a size_t. Also, does this assume that the data will be
>>> copied, so that the user can safely free the memory area pointed to by addr?
>>>
>>> +
>>>>> +/**
>>>>> +* Merge Buffer list into a singe buffer
>>>>> +*@param buf    Array of ODP Buffer Handles
>>>>> +*@param num    Number of Buffers in the buf Array
>>>>> +
>>>>> +*@return       Buffer Handle to the newly created odp buffer
>>>>> +**/
>>>>> +odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
>>>>> +
>>>>>
>>>>
>>> Which pool should the resulting buffer be allocated from? Will there be
>>> an SG list in the resulting buffer or just one big chunk?
>>>
>>>
>>>> +/**
>>>>> +* Split a single Buffer into a list of odp buffers
>>>>> +*
>>>>> +*@param buf    Buffer Handle
>>>>> +*
>>>>> +*@param        size    Maximum size of the individual buffers
>>>>> +*
>>>>> +*@return       Array of newly created Buffer Handle
>>>>> +**/
>>>>> +odp_buffer_t[] odp_buffer_split(odp_buffer_t buf, int size);
>>>>>
>>>>
>>> This doesn't seem entirely related to SG support. Is there zero-copy
>>> here?
>>>
>>>>  +
>>>>> +/**
>>>>> +* Append a buffer at the end of a scatter-gather list of buffer
>>>>> +*
>>>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>>>> +*
>>>>> +*@param tail   Buffer Handle to the buffer which is appended
>>>>> +*
>>>>> +*@return       1 if success 0 otherwise
>>>>> +**/
>>>>> +int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
>>>>
>>>>  +
>>>>> +/**
>>>>> +* Add a buffer at the head of a existing Scatter-gather Buffer
>>>>> +*
>>>>> +*@param buf    Buffer Handle to the scatter-gather list of buffer
>>>>> +*
>>>>> +*@param head   Buffer Handle to the buffer which is added at the head
>>>>> +*
>>>>> +*@return       1 if success 0 otherwise
>>>>> +**/
>>>>> +int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
>>>>>
>>>>
>>> It's not clear to me whether we should support scatter-gather lists made
>>> out of odp buffers or random memory. Surely it is easier to work with odp
>>> buffers only, but that may not be enough for our purposes.
>>>
>>> /Ciprian
>>>
>>>
>>>>>  #ifdef __cplusplus
>>>>>  }
>>>>> --
>>>>> 1.7.9.5
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> lng-odp mailing list
>>>> lng-odp@lists.linaro.org
>>>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>>>
>>>>
>>>
>>
>
diff mbox

Patch

diff --git a/include/odp_buffer.h b/include/odp_buffer.h
index d79e76d..c313168 100644
--- a/include/odp_buffer.h
+++ b/include/odp_buffer.h
@@ -92,6 +92,79 @@  int odp_buffer_is_valid(odp_buffer_t buf);
  */
 void odp_buffer_print(odp_buffer_t buf);
 
+/**
+*Number of segments in this scatter-gather List
+*
+*@param buf	Buffer Handle
+*
+*@return 	Total number of segments in this scatter-gather List. 
+*
+**/
+int odp_buffer_segment_count(odp_buffer_t buf)
+
+/**
+*Address of the segment in the buffer list.
+*
+*@param buf	Buffer Handle
+*@param n	Index number for the segment in the SG list
+*@param size	Returns the size of the current addressable segment
+
+*@return	Segment start address
+**/
+
+void* odp_buffer_segment_addr(odp_buffer_t buf, int n, size_t* size);
+
+/* 
+*Creates ODP Buffer from a memory region
+*
+*@param addr	Address of the memory region
+*@param size    Size of the memory region
+*
+*@return 	Buffer Handle to the newly create odp buffer
+*/
+odp_buffer_t     odp_buffer_from_memory_region(void* addr, int size );
+
+/**
+* Merge Buffer list into a singe buffer
+*@param buf	Array of ODP Buffer Handles
+*@param num	Number of Buffers in the buf Array
+
+*@return	Buffer Handle to the newly created odp buffer
+**/
+odp_buffer_t    odp_buffer_merge(odp_buffer_t[] buf, int num);
+
+/**
+* Split a single Buffer into a list of odp buffers
+*
+*@param buf	Buffer Handle
+*
+*@param	size	Maximum size of the individual buffers
+*
+*@return 	Array of newly created Buffer Handle
+**/
+odp_buffer_t[]	odp_buffer_split(odp_buffer_t buf, int size);
+
+/**
+* Append a buffer at the end of a scatter-gather list of buffer
+*
+*@param buf	Buffer Handle to the scatter-gather list of buffer
+*
+*@param tail	Buffer Handle to the buffer which is appended
+*
+*@return	1 if success 0 otherwise
+**/
+int odp_buffer_append(odp_buffer_t buf, odp_buffer_t tail );
+
+/**
+* Add a buffer at the head of a existing Scatter-gather Buffer
+*
+*@param buf	Buffer Handle to the scatter-gather list of buffer
+*
+*@param head	Buffer Handle to the buffer which is added at the head
+*
+*@return	1 if success 0 otherwise
+**/
+int odp_buffer_insert_at_head(odp_buffer_t buf, odp_buffer_t head);
 
 #ifdef __cplusplus
 }