From: Francois Romieu <romieu-W8zweXLXuWQS+FvcfC7Uqw@public.gmane.org>
To: Lino Sanfilippo <LinoSanfilippo-Mmb7MZpHnFY@public.gmane.org>
Cc: wsy2220-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>,
wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org
Subject: Re: [PATCH v2] ethernet:arc: Fix racing of TX ring buffer
Date: Fri, 20 May 2016 02:31:45 +0200 [thread overview]
Message-ID: <20160520003145.GA22420@electric-eye.fr.zoreil.com> (raw)
In-Reply-To: <573E2D0C.604-Mmb7MZpHnFY@public.gmane.org>
Lino Sanfilippo <LinoSanfilippo-Mmb7MZpHnFY@public.gmane.org> :
[...]
> 2. requires a smp_wmb, while 3. requires a rmb(). AFAIK the mb() implies all we need,
> the dma_rmb() for 1., the smp_wmb() for 2. and the rmb() for 3.
A revalidation of tx_dirty is still needed (see below) despite the rmb()
for 3. The rmb() for 3. is close to useless.
> >> 2. On multi processor systems: ensures that txbd_curr is updated (this is paired
> >> with the smp_mb() at the end of tx_clean).
> >
> > Smells like using barrier side-effects to control smp coherency. It isn't
> > the recommended style.
> >
>
> As I wrote above, the mb() implies the smp_wmb() so this is a regular pairing
> of smp_wmb() in xmit and smb_mb() in tx_clean, nothing uncommon.
Since you are quoting Documentation/memory-barriers.txt:
[...]
CPU MEMORY BARRIERS
-------------------
[...]
Mandatory barriers should not be used to control SMP effects, since mandatory
barriers impose unnecessary overhead on both SMP and UP systems.
> >> - if ((info & FOR_EMAC) || !txbd->data || !skb)
> >> + if (info & FOR_EMAC) {
> >> + /* Make sure we see consistent values for info, skb
> >> + * and data.
> >> + */
> >> + smp_rmb();
> >> break;
> >> + }
> >
> > ?
> >
> > smp_rmb should appear before the variables you want coherency for.
>
> I dont think so. Please take a look into the memory barriers documentation.
> There is an example that is pretty close to the situation that we have in this driver:
>
> http://lxr.free-electrons.com/source/Documentation/memory-barriers.txt#L1819
>
> In that example the barrier is also _between_ the variables that are to be
> ordered, not before.
Err, which barrier ?
- dma_rmb() ?
The device (obviously) set the 'status' member of the descriptor.
dma_rmb() ensures that device-initiated DMA is complete for the 'data'
member as well.
- dma_wmb() ?
It ensures that the updated 'data' member will be set before any
DMA resulting from the change of descriptor ownership takes place.
- wmb() ?
It ensures that the previous write to descriptor (coherent memory)
completes before write is posted to I/O mailbox.
None of these is "pretty close" to the "smp_rmb() before return" situation.
> >> - skb_tx_timestamp(skb);
> >> + /* Make sure info is set after data and skb with respect to
> >> + * other tx_clean().
> >> + */
> >> + smp_wmb();
> >>
> >> *info = cpu_to_le32(FOR_EMAC | FIRST_OR_LAST_MASK | len);
> >
> > Afaik smp_wmb() does not imply wmb(). So priv->txbd[*txbd_curr].data and
> > *info (aka priv->txbd[*txbd_curr].info) are not necessarily written in
> > an orderly manner.
>
> Right, as I already wrote above I changed the smp barriers to mandatory ones.
>
> >
> >>
> >> - /* Make sure info word is set */
> >> - wmb();
> >> -
> >> - priv->tx_buff[*txbd_curr].skb = skb;
> >> -
> >> /* Increment index to point to the next BD */
> >> *txbd_curr = (*txbd_curr + 1) % TX_BD_NUM;
> >
> > With this change it's possible that tx_clean() reads new value for
> > tx_curr and old value (0) for *info.
>
> Even if this could happen, what is the problem? I cant see an issue
> that results from such a scenario.
tx_clean() misunderstands the 0 in *info as a descriptor updated by the
device. tx_clean() thus kfrees the skb before the device DMAed from it.
[...]
> > Xmit thread | Clean thread
> >
> > mb();
> >
> > arc_emac_tx_avail() test with old
> > tx_dirty - tx_clean has not issued
> > any mb yet - and new tx_curr
> >
> > smp_mb();
> >
> > if (netif_queue_stopped(ndev) && ...
> > netif_wake_queue(ndev);
> >
> > netif_stop_queue()
> >
> > -> queue stopped.
> >
>
> Again, the mb() we have now implies the smb_mb() we had before. So nothing
> changed except that we can be sure to see the new value for tx_dirty at
> our first attempt.
Nothing changed except you removed the revalidation part !
The smp_mb() we had before wasn't about seeing tx_dirty in the xmit thread
but about balancing the (read) barrier in the cleaning thread so that the
latter stood a chance to see the new (tx thread updated) tx_curr.
Consider the two lines below:
if (!arc_emac_tx_avail(priv))
netif_stop_queue(ndev);
Nothing prevents a complete run of the cleaning thread between these
two lines. It may or it may not happen but there is one thing sure:
mb() before arc_emac_tx_avail() can't tell the future.
[...]
> New patch is below.
The arc_emac_tx_clean() change is wrong.
tx_drity revalidation is still needed in arc_emac_tx after netif_stop_queue.
A barrier is still missing in arc_emac_tx between descriptor release and
tx_curr increase.
--
Ueimor
next prev parent reply other threads:[~2016-05-20 0:31 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-17 15:25 [PATCH v2] ethernet:arc: Fix racing of TX ring buffer Shuyu Wei
2016-05-17 16:36 ` Aw: " Lino Sanfilippo
2016-05-17 18:24 ` David Miller
[not found] ` <20160517.142456.2247845107325931733.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2016-05-18 0:01 ` Francois Romieu
[not found] ` <20160518000153.GA21757-lmTtMILVy1jWQcoT9B9Ug5SCg42XY1Uw0E9HWUfgJXw@public.gmane.org>
2016-05-18 20:29 ` Lino Sanfilippo
[not found] ` <573CD09D.1060307-Mmb7MZpHnFY@public.gmane.org>
2016-05-18 22:55 ` Francois Romieu
[not found] ` <20160518225529.GA18671-lmTtMILVy1jWQcoT9B9Ug5SCg42XY1Uw0E9HWUfgJXw@public.gmane.org>
2016-05-19 21:15 ` Lino Sanfilippo
[not found] ` <573E2D0C.604-Mmb7MZpHnFY@public.gmane.org>
2016-05-20 0:31 ` Francois Romieu [this message]
2016-05-21 16:09 ` Shuyu Wei
2016-05-21 19:47 ` Francois Romieu
[not found] ` <20160521194733.GA30557-lmTtMILVy1jWQcoT9B9Ug5SCg42XY1Uw0E9HWUfgJXw@public.gmane.org>
2016-05-21 23:04 ` Lino Sanfilippo
[not found] ` <5740E98A.5050803-Mmb7MZpHnFY@public.gmane.org>
2016-05-22 21:21 ` Francois Romieu
2016-05-21 22:58 ` Lino Sanfilippo
2016-05-22 9:17 ` Shuyu Wei
2016-05-22 11:30 ` Lino Sanfilippo
[not found] ` <57419853.9050701-Mmb7MZpHnFY@public.gmane.org>
2016-05-22 22:36 ` Francois Romieu
[not found] ` <20160522223659.GB5086-lmTtMILVy1jWQcoT9B9Ug5SCg42XY1Uw0E9HWUfgJXw@public.gmane.org>
2016-05-24 1:09 ` Lino Sanfilippo
[not found] ` <5743A9DD.8010202-Mmb7MZpHnFY@public.gmane.org>
2016-05-24 19:02 ` Francois Romieu
2016-05-24 23:56 ` Lino Sanfilippo
2016-05-28 6:43 ` Shuyu Wei
2016-05-30 21:41 ` Lino Sanfilippo
2016-06-05 14:02 ` Shuyu Wei
2016-06-08 7:54 ` Lino Sanfilippo
2016-05-23 11:36 ` Shuyu Wei
2016-05-24 1:14 ` Lino Sanfilippo
2016-05-21 13:46 ` Shuyu Wei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160520003145.GA22420@electric-eye.fr.zoreil.com \
--to=romieu-w8zwexlxuwqs+fvcfc7uqw@public.gmane.org \
--cc=LinoSanfilippo-Mmb7MZpHnFY@public.gmane.org \
--cc=davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org \
--cc=heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org \
--cc=linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=wsy2220-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox