On Wed, 11 Jan 2017 08:17:59 -0800, Stephen Hemminger
<[email protected]> wrote:
> On Fri, 30 Dec 2016 04:50:16 +0700
> Sergey Vyazmitinov <[email protected]> wrote:
>
> > /**
> > + * 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.
> > + * @param mbufs
> > + * The packets mbufs array to be freed.
> > + * @param n
> > + * Number of packets.
> > + */
> > +static inline void rte_pktmbuf_free_bulk(struct rte_mempool *mp,
> > + struct rte_mbuf **mbufs, unsigned n)
> > +{
> > + struct rte_mbuf *mbuf, *m_next;
> > + unsigned i;
> > + for (i = 0; i < n; ++i) {
> > + mbuf = mbufs[i];
> > + __rte_mbuf_sanity_check(mbuf, 1);
> > +
> > + mbuf = mbuf->next;
> > + while (mbuf != NULL) {
> > + m_next = mbuf->next;
> > + rte_pktmbuf_free_seg(mbuf);
> > + mbuf = m_next;
> > + }
> > + }
> > + rte_mempool_put_bulk(mp, (void * const *)mbufs, n);
> > +}
>
> The mbufs may come from different pools. You need to handle that.
I have an implementation for that in an endless-work-in-progress
patchset:
/**
+ * Free several mbufs segments.
+ *
+ * This function frees a table of mbufs, ensuring that each mbuf is
+ * returned into its original pool. It is the equivalent of calling
+ * rte_pktmbuf_free_seg() on all mbuf of the table.
+ *
+ * @param mbufs
+ * Array of mbuf pointers.
+ * @param n
+ * Array size.
+ */
+static inline void
+rte_pktmbuf_free_seg_bulk(struct rte_mbuf * const *m_tab, unsigned n)
+{
+ struct rte_mbuf *m;
+ struct rte_mbuf * const *start = NULL;
+ unsigned n_free = 0, i;
+ struct rte_mempool *free_pool = NULL;
+
+ for (i = 0; i < n; i++) {
+ m = m_tab[i];
+
+ if (__rte_pktmbuf_prefree_seg(m) == NULL) {
+ if (n_free != 0)
+ rte_mempool_put_bulk(free_pool,
+ (void * const *)start, n_free);
+
+ free_pool = NULL;
+ n_free = 0;
+ continue;
+ }
+
+ if (unlikely(m->pool != free_pool)) {
+ if (n_free != 0)
+ rte_mempool_put_bulk(free_pool,
+ (void * const *)start, n_free);
+
+ free_pool = m->pool;
+ start = &m_tab[i];
+ n_free = 1;
+ } else {
+ n_free++;
+ }
+ }
+
+ if (n_free != 0)
+ rte_mempool_put_bulk(free_pool,
+ (void * const *)start, n_free);
+}
In the same patch, I also remove the tx_free_bulk_mbuf() functions
that does almost the same job in specific drivers. Unfortunately,
this patch needs to be rebased and better tested, so it's not ready yet.
Regards,
Olivier