Hi, On Thu, 19 Jan 2017 11:46:58 +0700, Sergey Vyazmitinov <s.vyazmiti...@brain4net.com> wrote: > Suggested-by: Stephen Hemminger <step...@networkplumber.org> > Signed-off-by: Sergey Vyazmitinov <s.vyazmiti...@brain4net.com> > --- > v3: > * Fixed issue with possible different mempools in buffer list. > * Fixed issue with wrong rte_pktmbuf_alloc_bulk function return value > processing in the kni_allocate_mbufs. > --- > lib/librte_mbuf/rte_mbuf.h | 49 > ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 > insertions(+) > > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h > index 4476d75..69d314f 100644 > --- a/lib/librte_mbuf/rte_mbuf.h > +++ b/lib/librte_mbuf/rte_mbuf.h > @@ -306,6 +306,9 @@ extern "C" { > /** Alignment constraint of mbuf private area. */ > #define RTE_MBUF_PRIV_ALIGN 8 > > +/** Maximum number of mbufs freed in bulk. */ > +#define RTE_MBUF_BULK_FREE 64 > + > /** > * Get the name of a RX offload flag > * > @@ -1261,6 +1264,52 @@ static inline void rte_pktmbuf_free(struct > rte_mbuf *m) } > > /** > + * Free n packets mbuf back into its original mempool. > + * > + * Free each mbuf, and all its segments in case of chained buffers. > Each > + * segment is added back into its original mempool. > + * > + * @param mp > + * The packets mempool.
This parameter was removed, it could be removed from the API comment. > + * @param mbufs > + * The packets mbufs array to be freed. > + * @param n > + * Number of packets. > + */ > +static inline void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, > + unsigned int n) I suggest we could use mbuf instead of pktmbuf in the function name. It's a bit shorter, and the function would also apply on ctrlmbuf. Also, the struct rte_mbuf **mbufs could probably be replaced by struct rte_mbuf * const *mbufs. > +{ > + void *tofree[RTE_MBUF_BULK_FREE]; > + struct rte_mempool *mp = NULL; > + unsigned int i, count = 0; > + > + for (i = 0; i < n; i++) { > + struct rte_mbuf *m, *m_next; > + > + for (m = mbufs[i]; m; m = m_next) { > + m_next = m->next; > + > + if (count > 0 && > + (unlikely(m->pool != mp || > + count == RTE_MBUF_BULK_FREE))) { > + rte_mempool_put_bulk(mp, tofree, > count); > + count = 0; > + } > + > + mp = m->pool; > + > + if (likely(__rte_pktmbuf_prefree_seg(m) != > NULL)) { > + m->next = NULL; > + tofree[count++] = m; > + } > + } > + } > + > + if (likely(count > 0)) > + rte_mempool_put_bulk(mp, tofree, count); > +} > + > +/** > * Creates a "clone" of the given packet mbuf. > * The function looks good to me, thank you. It looks also better than what I've suggested in [1], since it properly manage mbuf chains. On the other hand, I think my proposal could also help in drivers, where segments are already unchained. I'll submit it in a RFC. [1] http://dpdk.org/ml/archives/dev/2017-January/054538.html One more thing, maybe it's worth adding a basic test in app/test/test_mbuf.c. Thanks, Olivier