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.