On Mon, Oct 16, 2017 at 05:34:36PM +0530, Pavan Nikhilesh Bhagavatula wrote:
> On Mon, Oct 09, 2017 at 08:30:35PM +0000, Carrillo, Erik G wrote:
> > > >
> > > > The second big change is to replace API parameters specifying pointer
> > > > to rte_event_timer_adapter with ids, which seems more common
> > > > throughout DPDK.
> > > >
> > > > Other changes include:
> > > >  - removed rte_event_timer_adapter_lookup() function, since APIs no
> > > longer
> > > >    accept pointer to rte_event_timer_adapter
> > >
> > > There is one difference between ethdev rx adapter, where we have
> > > rte_event_timer_arm_burst(), rte_event_timer_arm_tmo_tick_burst(),
> > > rte_event_timer_cancel_burst(),
> > > APIs in fastpath. So any multi process scheme where resolving the fastpath
> > > API functions in _one_ or zero redirection is fine.
> >
> > I see, makes sense.
> >
> > >
> > > I guess in we may need 2 or 3 indirection to resolve the fastpath 
> > > functions
> > > with id scheme. Please choose scheme with one 1 or no redirection.
> > > I think,
> > > - By allocating adapter memory from the heap and
> >
> > Just to check, are you talking about the heap (e.g., rte_malloc) in 
> > hugepage memory?
>
> Yes, If we use rte_memzone_reserve and create the adapter in the primary
> process, the name can be used to do a lookup in the secondary.
> >
> > > - adapter hold the function pointers for multi process and
> > > - mempool kind of pointer object scheme without id and lookup() Can
> > > resolve function pointers without any indirection.
> > >
> >
> > Can you elaborate here?  In the mempool implementation, it looks like 
> > there's a per-process array of ops objects, and each mempool instance has 
> > an index into the array that it uses to select the ops object to call 
> > through.  Since the ops structures are initialized per-process, they get 
> > function pointers valid in that process - which relates to the second point 
> > above. If the adapter holds function pointers for a primary process (for 
> > example), they'll be invalid in the secondary.  Am I missing something?
> >
>
> Once adapter is created using memzone in the Primary process, the secondary
> process can use the memzone name to get the pointer to the adapter and use 
> data
> such as ops_id stored in the memzone to fixup the fastpath function pointers.
> The slowpath could still use ops_id based function pointers(mempool).
>
> > Thanks,
> > Gabriel
> >
> > > So please analyze on those lines as well.
> > >
> > >
> >
>
> Pavan

Adding to this

Have a two level scheme such as:

--Allocate this structure from a global array based on the adapter ID:

struct rte_event_timer_wheel {
    event_timer_arm_burst arm_burst;
    /**< Pointer to driver arm_burst function. */
    event_timer_arm_tmo_tick_burst arm_tmo_tick_burst;
    /**< Pointer to driver arm_tmo_tick_burst function. */
    event_timer_cancel_burst cancel_burst;
    /**< Pointer to driver cancel function. */

--Allocate the data section using memzone reserve.
    struct rte_event_timer_wheel_data *data;


    /**< Pointer to timer wheel data*/
    struct rte_event_timer_wheel_ops *ops;
    /**< Driver specific ops */
} __rte_cache_aligned;

/**
 * Timer wheel data structure.
 */
struct rte_event_timer_wheel_data {
    void *wheel_priv;
    /**< Timer wheel private data*/
    uint8_t ops_index;
    /**< Timer wheel ops index id. */
    uint8_t wheel_id;
    /**< Timer wheel id. */
    uint8_t event_port_id;
    /**< Optional Event port used when the inbuilt port is absent.*/
    const struct rte_memzone *mz;
    /**< Timer wheel memzone pointer. */
    struct rte_event_timer_wheel_config conf;
    /**< Configuration used to configure the wheel. */

    RTE_STD_C11
    uint8_t started : 1;
    /**< Flag to indicate wheel started. */
} __rte_cache_aligned;

/* Primary process */
*_create(wheel_id, ...)
{
        struct rte_event_timer_wheel *wl;

        /* do checks */
        ...

        wl = &rte_event_timer_wheels[wheel_id];

        ...
        /* Get ops ID based on eventdev */
        ...
        ret = rte_event_dev_get_timer_wheel_capability(event_dev_id, &flags,
                &ops_id);

        mz = rte_memzone_reserve(name, ...);
        ...
        /* fill in data */
        data = mz->addr;
        ...

        data = ops_id;
        ...
        /* Call the driver specific functions. */
}

/*Secondaty process*/
struct rte_event_timer_wheel *
rte_event_timer_wheel_lookup(uint16_t wheel_id)
{
        ...
        struct rte_event_timer_wheel *wl;
        struct rte_event_timer_wheel_data *data;
        ...

        /* Do checks*/
        ...
        /* Look up memzone created in primary. */
        mz = rte_memzone_lookup(name);

        data = mz->addr;

        /* Setup up global array in secondary */
        wl = &rte_event_timer_wheels[data->wheel_id];
        wl->data = data;
        ...
        /* Use the ops_id set in primary to get the ops in secondary*/
        wl->ops = rte_event_timer_wheel_get_ops(data->ops_index);

        /* Reset the ops*/
        (*wl->ops->set_ops)(wl);

        return wl;
}

Hope this clears few things up.

Reply via email to