On 12/08/15 11:55, Bala Manoharan wrote:


On 12 August 2015 at 16:17, Bala Manoharan <[email protected] <mailto:[email protected]>> wrote:



    On 12 August 2015 at 15:37, Zoltan Kiss <[email protected]
    <mailto:[email protected]>> wrote:



        On 12/08/15 07:34, Bala Manoharan wrote:

            Hi,

            Comments inline...

            On 12 August 2015 at 00:01, Zoltan Kiss
            <[email protected] <mailto:[email protected]>
            <mailto:[email protected]
            <mailto:[email protected]>>> wrote:

                Applications can preset certain parts of the buffer or
            user area, so
                when that
                memory will be allocated it starts from a known state.
            If the platform
                allocates the memory during pool creation, it's enough
            to run the
                constructor
                after that. If it's allocating memory on demand, it
            should call the
                constructor each time.


            [Bala] Not sure if I understand the above description
            correctly does it
            mean that if the memory is allocated
            for an existing pool this call should be called only
            during the pool
            creation and not during each and every buffer allocation?

        I'm also not sure I understand the question :) How do you mean
        "if the memory is allocated for an _existing_ pool"? I mean,
        you can't allocate memory for a pool which doesn't exist.
        The key point is "when that memory will be allocated". This
        callback should be called whenever the memory is allocated for
        the buffer. If it is done during pool creation (which I guess
        most sensible implementations do), then it happens then. If
        for some reason the platform allocates memory when someone
        allocates the buffer, it happens then.


    [Bala] Let me try to decrypt my query in a better way :-)

    Usually when application calls odp_pool_create() most
    implementations will allocate a memory region and map them as
    pointers based on a fixed segment size so that when the
    application calls odp_buffer_allocate() the segment of this memory
    pool (segments may be combined depending on the required size of
    the buffer )

No, odp_buffer_alloc() doesn't let you specify you sizes, the buffer size is set when you create the pool. I think you mean packet type pools. In that case there could be segmentation, so a packet could have been the Nth segment of an another packet before.

    will be returned to the user.

    So my understanding of your requirement is that whenever the
    application calls  odp_buffer_alloc() then the user area should be
    reset to a predefined value.

No. "so when that memory will be allocated". The callback is only called when the memory underlying the buffer gets allocated. Beware, allocating a buffer and allocating the memory can be two different things in this context. At least linux-generic and ODP-DPDK allocates the memory when the pool is created, not when the buffer is allocated.


    So in-case that an application does the following
    1. odp_buffer_alloc()
    2. odp_buffer_free()
    3. odp_buffer_alloc()

    For simplicity lets assume the implementation returned the same
    buffer during the second odp_buffer_alloc() call ( Basically the
    buffer gets reused ) then the implementation should have reset the
    user-area of the buffer before returning it to the application. Is
    this the requirement?

No. The only requirement is that "when that memory will be allocated it starts from a known state". The implementation should call the callback only when that memory is allocated. Therefore, if the memory underlying this buffer were not released and reallocated between an alloc and free, this callback shouldn't be called

[Bala] Missed a sentence here
In the above scenario implementation should have reset the user-area before both odp_buffer_alloc() both in step 1 and step 3.


    I have additional query regarding the use-case you have defined
    below but I would like to get clarity on the above first :)

    Regards,
    Bala


            Then it will be applications responsibility to reset the
            user area
            before freeing the buffer? Is this the use-case this API
            is trying to
            address?

        No, the application is not required to reset it at any time.
        It can do that, if it's what it wants. The only requirement is
        that the buffer starts from a known state after its memory was
        allocated.
        The use case is the following: OVS has it's layer to handle
        buffers from different sources, e.g. it has to be able to
        differentiate between packets coming from DPDK and ODP (the
        latter can run DPDK underneath as well, but that's a different
        story ...). It stores a "struct dp_packet" in the user area to
        store data about the packet:

        https://git.linaro.org/lng/odp-ovs.git/blob/HEAD:/lib/dp-packet.h#l41

        Most of these fields will be set during processing to their
        right value, however there are two things we need to set right
        after receive: "source" to DPBUF_ODP and "odp_pkt" to point to
        the odp_packet_t itself. The first value will be the same for
        all ODP packets, every time. And the second is known when the
        underlying memory was allocated.
        Both of them could be set when the pool is created, OVS-DPDK
        does that already, but ODP-OVS has to reset these values after
        every receive. Even when it's only a few cycles to set and
        maybe unnecessary cache loads, it's still a lot of cycles when
        you receive at 10-40-100 Gbps.




                Signed-off-by: Zoltan Kiss <[email protected]
            <mailto:[email protected]>
                <mailto:[email protected]
            <mailto:[email protected]>>>

                ---
                  include/odp/api/pool.h | 20 ++++++++++++++++++++
                  1 file changed, 20 insertions(+)

                diff --git a/include/odp/api/pool.h
            b/include/odp/api/pool.h
                index 2e79a55..1bd19bf 100644
                --- a/include/odp/api/pool.h
                +++ b/include/odp/api/pool.h
                @@ -41,6 +41,20 @@ extern "C" {
                  #define ODP_POOL_NAME_LEN  32

                  /**
                + * Buffer constructor callback function for pools.
                + *
                + * @param pool          Handle of the pool which owns
            the buffer
                + * @param buf_ctor_arg  Opaque pointer defined in
            odp_pool_param_t
                + * @param buf           Pointer to the buffer
                + *
                + * @note If the application specifies this pointer,
            it expects that
                every buffer
                + * is initialized with it when the underlying memory
            is allocated.
                + */
                +typedef void (odp_pool_buf_ctor_t)(odp_pool_t pool,
                + void *buf_ctor_arg,
                + void *buf);
                +


            [Bala] We have avoided call back functions in ODP
            architecture so if the
            requirement can be addressed without a call-back maybe we
            can follow
            that approach. Again I am not clear if this call-back
            function should be
            called only once during pool creation or every time during
            buffer alloc.

                +/**
                   * Pool parameters
                   * Used to communicate pool creation options.
                   */
                @@ -88,6 +102,12 @@ typedef struct odp_pool_param_t {
                                         uint32_t num;
                                 } tmo;
                         };
                +
                +       /** Buffer constructor to initialize every
            buffer. Use NULL
                if no
                +           initialization needed. */
                +       odp_pool_buf_ctor_t *buf_ctor;
                +       /** Opaque pointer passed to buffer constructor */
                +       void *buf_ctor_arg;
                  } odp_pool_param_t;

                  /** Packet pool*/
                --
                1.9.1

            _______________________________________________
                lng-odp mailing list
            [email protected] <mailto:[email protected]>
            <mailto:[email protected]
            <mailto:[email protected]>>
            https://lists.linaro.org/mailman/listinfo/lng-odp


            Regards,
            Bala




_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to