From: Stanislaw Gruszka <sgruszka@redhat.com>
To: Michael Chan <mchan@broadcom.com>
Cc: Vladislav Zolotarov <vladz@broadcom.com>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"davem@davemloft.net" <davem@davemloft.net>,
Eilon Greenstein <eilong@broadcom.com>,
Matthew Carlson <mcarlson@broadcom.com>
Subject: Re: [PATCH 1/1] bnx2x: Tx barriers and locks
Date: Tue, 2 Mar 2010 12:30:33 +0100 [thread overview]
Message-ID: <20100302113032.GA2362@dhcp-lab-161.englab.brq.redhat.com> (raw)
In-Reply-To: <1267466347.19491.31.camel@nseg_linux_HP1.broadcom.com>
On Mon, Mar 01, 2010 at 09:59:07AM -0800, Michael Chan wrote:
> > There is still difference between what we have in bnx2x and bnx2/tg3
> > regarding memory barriers in tx_poll/start_xmit code. Mainly we have
> > smp_mb() in bnx2/tg3_tx_avail(), and in bnx2/tg3_tx_int() is smp_mb()
> > not smp_wmb(). I do not see that bnx2x is wrong, but would like to know
> > why there is a difference, maybe bnx2/tg3 should be changed?
> >
>
> The memory barrier in tx_int() is to make the tx index update happen
> before the netif_tx_queue_stopped() check. The barrier is to prevent a
> situation like this:
>
> CPU0 CPU1
> start_xmit()
> if (tx_ring_full) {
> tx_int()
> if (!netif_tx_queue_stopped)
> netif_tx_stop_queue()
> if (!tx_ring_full)
> update_tx_index
> netif_tx_wake_queue()
> }
>
>
> The update_tx_index code is before the if statement in program order,
> but the CPU and/or compiler can reorder it as shown above. smp_mb() will
> prevent that. Will smp_wmb() prevent that as well?
No. smp_wmb() affect only write orders on CPU1 performing tx_int(), so
that should be fixed in bnx2x.
Regarding memory barrier in tx_avail(), I don't think it its needed for
anything, except maybe usage at the beginning of start_xmit(), but we can
just remove that like in the patch below. I going to post "official"
patches for tg3, bnx2 and bnx2x, if no nobody has nothing against.
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index ed785a3..0f406b8 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -893,7 +893,6 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
u16 prod;
u16 cons;
- barrier(); /* Tell compiler that prod and cons can change */
prod = fp->tx_bd_prod;
cons = fp->tx_bd_cons;
@@ -963,9 +962,8 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp)
* start_xmit() will miss it and cause the queue to be stopped
* forever.
*/
- smp_wmb();
+ smp_mb();
- /* TBD need a thresh? */
if (unlikely(netif_tx_queue_stopped(txq))) {
/* Taking tx_lock() is needed to prevent reenabling the queue
* while it's empty. This could have happen if rx_action() gets
@@ -11177,10 +11175,9 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
struct eth_tx_parse_bd *pbd = NULL;
u16 pkt_prod, bd_prod;
- int nbd, fp_index;
+ int nbd, fp_index, i, ret;
dma_addr_t mapping;
u32 xmit_type = bnx2x_xmit_type(bp, skb);
- int i;
u8 hlen = 0;
__le16 pkt_size = 0;
@@ -11195,10 +11192,9 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
fp = &bp->fp[fp_index];
if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) {
- fp->eth_q_stats.driver_xoff++;
- netif_tx_stop_queue(txq);
BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
- return NETDEV_TX_BUSY;
+ ret = NETDEV_TX_BUSY;
+ goto stop_queue;
}
DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)"
@@ -11426,19 +11422,24 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
mmiowb();
fp->tx_bd_prod += nbd;
-
- if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
- netif_tx_stop_queue(txq);
- /* We want bnx2x_tx_int to "see" the updated tx_bd_prod
- if we put Tx into XOFF state. */
- smp_mb();
- fp->eth_q_stats.driver_xoff++;
- if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
- netif_tx_wake_queue(txq);
- }
fp->tx_pkt++;
+
+ ret = NETDEV_TX_OK;
+ if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3))
+ goto stop_queue;
+
+ return ret;
- return NETDEV_TX_OK;
+stop_queue:
+ netif_tx_stop_queue(txq);
+ /* paired barrier is in bnx2x_tx_int(), update of tx_bd_cons
+ * have to be visable here, after we XOFF bit setting */
+ smp_mb();
+ fp->eth_q_stats.driver_xoff++;
+ if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
+ netif_tx_wake_queue(txq);
+
+ return ret;
}
/* called with rtnl_lock */
next prev parent reply other threads:[~2010-03-02 11:32 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-28 10:12 [PATCH 1/1] bnx2x: Tx barriers and locks Vladislav Zolotarov
2010-03-01 2:49 ` David Miller
2010-03-01 13:33 ` Stanislaw Gruszka
2010-03-01 17:59 ` Michael Chan
2010-03-02 10:38 ` Vladislav Zolotarov
2010-03-02 11:38 ` Stanislaw Gruszka
2010-03-02 11:30 ` Stanislaw Gruszka [this message]
2010-03-02 12:50 ` Vladislav Zolotarov
2010-03-02 13:55 ` Stanislaw Gruszka
2010-03-02 16:18 ` Michael Chan
2010-03-02 16:59 ` Stanislaw Gruszka
2010-03-02 17:26 ` Michael Chan
2010-03-08 15:38 ` Stanislaw Gruszka
2010-03-02 16:21 ` Vladislav Zolotarov
-- strict thread matches above, loose matches on Subject: below --
2010-02-28 10:03 Vladislav Zolotarov
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=20100302113032.GA2362@dhcp-lab-161.englab.brq.redhat.com \
--to=sgruszka@redhat.com \
--cc=davem@davemloft.net \
--cc=eilong@broadcom.com \
--cc=mcarlson@broadcom.com \
--cc=mchan@broadcom.com \
--cc=netdev@vger.kernel.org \
--cc=vladz@broadcom.com \
/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;
as well as URLs for NNTP newsgroup(s).