From mboxrd@z Thu Jan 1 00:00:00 1970 From: "vadim.suraev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org" Subject: [PATCH] rte_mbuf: scattered pktmbufs freeing optimization Date: Fri, 27 Feb 2015 01:15:06 +0200 Message-ID: <1424992506-20484-1-git-send-email-vadim.suraev@gmail.com> To: dev-VfR2kkLFssw@public.gmane.org Return-path: List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces-VfR2kkLFssw@public.gmane.org Sender: "dev" From: "vadim.suraev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org" new function - rte_pktmbuf_free_bulk makes freeing long scattered (chained) pktmbufs belonging to the same pool more optimal using rte_mempool_put_bulk rather than calling rte_mempool_put for each segment. Inlike rte_pktmbuf_free, which calls rte_pktmbuf_free_seg, this function calls __rte_pktmbuf_prefree_seg. If non-NULL returned, the pointer is placed in an array. When array is filled or when the last segment is processed, rte_mempool_put_bulk is called. In case of multiple producers, performs 3 times better. Signed-off-by: vadim.suraev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org --- lib/librte_mbuf/rte_mbuf.h | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 17ba791..1d6f848 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -824,6 +824,61 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m) } } +/* This macro defines the size of max bulk of mbufs to free for rte_pktmbuf_free_bulk */ +#define MAX_MBUF_FREE_SIZE 32 + +/* If RTE_LIBRTE_MBUF_DEBUG is enabled, checks if all mbufs must belong to the same mempool */ +#ifdef RTE_LIBRTE_MBUF_DEBUG + +#define RTE_MBUF_MEMPOOL_CHECK1(m) struct rte_mempool *first_buffers_mempool = (m) ? (m)->pool : NULL + +#define RTE_MBUF_MEMPOOL_CHECK2(m) RTE_MBUF_ASSERT(first_buffers_mempool == (m)->pool) + +#else + +#define RTE_MBUF_MEMPOOL_CHECK1(m) + +#define RTE_MBUF_MEMPOOL_CHECK2(m) + +#endif + +/** + * Free chained (scattered) mbuf into its original mempool. + * + * All the mbufs in the chain must belong to the same mempool. + * + * @param head + * The head of mbufs to be freed chain + */ + +static inline void __attribute__((always_inline)) +rte_pktmbuf_free_bulk(struct rte_mbuf *head) +{ + void *mbufs[MAX_MBUF_FREE_SIZE]; + unsigned mbufs_count = 0; + struct rte_mbuf *next; + + RTE_MBUF_MEMPOOL_CHECK1(head); + + while(head) { + next = head->next; + head->next = NULL; + if(__rte_pktmbuf_prefree_seg(head)) { + RTE_MBUF_ASSERT(rte_mbuf_refcnt_read(head) == 0); + RTE_MBUF_MEMPOOL_CHECK2(head); + mbufs[mbufs_count++] = head; + } + head = next; + if(mbufs_count == MAX_MBUF_FREE_SIZE) { + rte_mempool_put_bulk(((struct rte_mbuf *)mbufs[0])->pool,mbufs,mbufs_count); + mbufs_count = 0; + } + } + if(mbufs_count > 0) { + rte_mempool_put_bulk(((struct rte_mbuf *)mbufs[0])->pool,mbufs,mbufs_count); + } +} + /** * Creates a "clone" of the given packet mbuf. * -- 1.7.9.5