[dpdk-dev] [PATCH] kni: use bulk functions to allocate and free mbufs

Olivier MATZ olivier.matz at 6wind.com
Wed Jan 11 17:38:25 CET 2017


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


More information about the dev mailing list