[dpdk-dev] Do we need the refcnt set to zero again?

Bruce Richardson bruce.richardson at intel.com
Mon Mar 2 11:16:25 CET 2015


On Sat, Feb 28, 2015 at 06:08:16PM +0000, Wiles, Keith wrote:
> Looking that the code below does the rte_mbuf_refcnt_set(m,0) need to be present?
> 
> static inline struct rte_mbuf* __attribute__((always_inline))
> __rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
> {
> __rte_mbuf_sanity_check(m, 0);
> 
> if (likely (rte_mbuf_refcnt_read(m) == 1) ||
> likely (rte_mbuf_refcnt_update(m, -1) == 0)) {
> 
> rte_mbuf_refcnt_set(m, 0);
> 
> /* if this is an indirect mbuf, then
> *  - detach mbuf
> *  - free attached mbuf segment
> */
> if (RTE_MBUF_INDIRECT(m)) {
> struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr);
> rte_pktmbuf_detach(m);
> if (rte_mbuf_refcnt_update(md, -1) == 0)
> __rte_mbuf_raw_free(md);
> }
> return(m);
> }
> return (NULL);
> }
> 
> It seems like the code could be this or did I miss a race-condition?

What you are really missing is the initial check for refcnt == 1. In the case
of the atomic refcnt, this allows us to skip the atomic decrement operation, 
which is very expensive, and instead just do a regular assignment of the refcnt
to zero, in the refcnt_set call.


/Bruce

> 
> static inline struct rte_mbuf* __attribute__((always_inline))
> __rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
> {
> __rte_mbuf_sanity_check(m, 0);
> 
> /* The sanity check above should have checked for refcnt being zero */
> if ( likely (rte_mbuf_refcnt_update(m, -1) == 0 ) {
> 
> /* if this is an indirect mbuf, then
>  *  - detach mbuf
>  *  - free attached mbuf segment
>  */
> if (RTE_MBUF_INDIRECT(m)) {
> struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr);
> rte_pktmbuf_detach(m);
> if (rte_mbuf_refcnt_update(md, -1) == 0)
> __rte_mbuf_raw_free(md);
> }
> return(m);
> }
> return (NULL);
> }
> 


More information about the dev mailing list