Re: [PATCH v2] mbuf: optimize rte_mbuf_refcnt_update
From: Olivier MATZ <hidden>
Date: 2016-01-04 13:53:37
Hi Hanoch, Please find some comments below. On 12/27/2015 10:39 AM, Hanoch Haim (hhaim) wrote:
Hi Bruce, I'm Hanoch from Cisco Systems works for the https://github.com/cisco-system-traffic-generator/trex-core traffic generator project. While upgrading from DPDK 1.8 to 2.2 Ido found that the following commit creates a mbuf corruption and result in Tx hang commit f20b50b946da9070d21e392e4dbc7d9f68bc983e Author: Olivier Matz [off-list ref] Date: Mon Jun 8 16:57:22 2015 +0200 Looking at the change it is clear why there is an issue, wanted to get your input. Init ----- alloc const mbuf ==> mbuf-a (ref=1) Simple case that works --------------------- thread 1 , tx: alloc-mbuf->attach(mbuf-a) (ref=2) inc- non atomic thread 1 , tx: alloc-mbuf->attach(mbuf-a) (ref32) inc- atomic
do you mean "(ref=3)" ?
thread 1 , drv : free() (ref=2) dec- atomic thread 1 , drv : free() (ref=3) dec - non atomic
do you mean "(ref=1)" ?
Simple case that does not work --------------------- Both do that in parallel thread 2 tx : alloc-mbuf->attach(mbuf-a) (ref=2) inc- non atomic thread 1 tx : alloc-mbuf->attach(mbuf-a) (ref=2) inc- non atomic
It is not allowed to call a function from the mbuf API in parallel. Example: core0 | core1 --------------------------------|--------------------------------------- m = rte_pktmbuf_alloc(m); | enqueue(m); | |m = dequeue(); do_something(m); |do_something(m); do_something() is not allowed because it accesses the same mbuf structure. do_something() can be any function of mbuf API: rte_pktmbuf_prepend(), rte_pktmbuf_attach(), ... This is allowed: core0 | core1 --------------------------------|--------------------------------------- m = rte_pktmbuf_alloc(m); | m2 = rte_pktmbuf_attach(m); | enqueue(m2); | |m2 = dequeue(); do_something(m); |do_something(m2); Regards, Olivier