On Wed, 11 Jan 2017 08:17:59 -0800, Stephen Hemminger
<step...@networkplumber.org> wrote:
> On Fri, 30 Dec 2016 04:50:16 +0700
> Sergey Vyazmitinov <s.vyazmiti...@brain4net.com> 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

Reply via email to