Hi David, Some comments below.
On 06/10/2016 05:16 PM, David Hunt wrote: > Until now, the objects stored in a mempool were internally stored in a > ring. This patch introduces the possibility to register external handlers > replacing the ring. > > The default behavior remains unchanged, but calling the new function > rte_mempool_set_handler() right after rte_mempool_create_empty() allows > the user to change the handler that will be used when populating > the mempool. > > This patch also adds a set of default ops (function callbacks) based > on rte_ring. > > Signed-off-by: Olivier Matz <olivier.matz at 6wind.com> > Signed-off-by: David Hunt <david.hunt at intel.com> > > ... > @@ -386,10 +352,14 @@ rte_mempool_populate_phys(struct rte_mempool *mp, char > *vaddr, > int ret; > > /* create the internal ring if not already done */ > - if ((mp->flags & MEMPOOL_F_RING_CREATED) == 0) { > - ret = rte_mempool_ring_create(mp); > - if (ret < 0) > - return ret; > + if ((mp->flags & MEMPOOL_F_POOL_CREATED) == 0) { > + rte_errno = 0; > + ret = rte_mempool_ops_alloc(mp); > + if (ret != 0) { > + if (rte_errno == 0) > + return -EINVAL; > + return -rte_errno; > + } > } The rte_errno should be removed. Just return the error code from rte_mempool_ops_alloc() on failure. > +/** Structure defining mempool operations structure */ > +struct rte_mempool_ops { > + char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct */ > + rte_mempool_alloc_t alloc; /**< Allocate private data */ > + rte_mempool_free_t free; /**< Free the external pool. */ > + rte_mempool_put_t put; /**< Put an object. */ > + rte_mempool_get_t get; /**< Get an object. */ > + rte_mempool_get_count get_count; /**< Get qty of available objs. */ > +} __rte_cache_aligned; > + Sorry, I missed that in the previous reviews, but since the get/put functions have been renamed in dequeue/enqueue, I think the same change should also be done here. > +/** > + * Prototype for implementation specific data provisioning function. > + * > + * The function should provide the implementation specific memory for > + * for use by the other mempool ops functions in a given mempool ops struct. > + * E.g. the default ops provides an instance of the rte_ring for this > purpose. > + * it will most likely point to a different type of data structure, and > + * will be transparent to the application programmer. > + */ > +typedef int (*rte_mempool_alloc_t)(struct rte_mempool *mp); A comment saying that this function should set mp->pool_data would be nice here, I think. > +/* wrapper to allocate an external mempool's private (pool) data */ > +int > +rte_mempool_ops_alloc(struct rte_mempool *mp) > +{ > + struct rte_mempool_ops *ops; > + > + ops = rte_mempool_ops_get(mp->ops_index); > + if (ops->alloc == NULL) > + return -ENOMEM; > + return ops->alloc(mp); > +} Now that we check that ops->alloc != NULL in the register function, I wonder if we should keep this test or not. Yes, it doesn't hurt, but for consistency with the other functions (get/put/get_count), we may remove it. This would be a good thing because it would prevent any confusion with rte_mempool_ops_get(), which returns a pointer to the ops struct (and has nothing to do with ops->get()). Regards, Olivier