]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
myri10ge: fix stop/go ordering even more
authorBrice Goglin <brice@myri.com>
Mon, 10 Nov 2008 12:58:41 +0000 (13:58 +0100)
committerJeff Garzik <jgarzik@redhat.com>
Tue, 11 Nov 2008 08:49:53 +0000 (03:49 -0500)
The doorbell writes may be seen out of order by the firmware if they
are in WC memory since the tx spin(un)lock does not flush WC writes.
Hence if the "stop" is written on a different CPU than the "go", it
is possible that the stop will arrive after the go unless we add an
explicit memory barrier (and mmiowb() is not enough).

It fixes transmit hangs in multi tx queue mode.

Signed-off-by: Brice Goglin <brice@myri.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/net/myri10ge/myri10ge.c

index a5f428bcc0ebb28011efb551534584e768c4a6e9..b3786709730811c2b6467cabda06c55d2203ddb1 100644 (file)
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.4.3-1.375"
+#define MYRI10GE_VERSION_STR "1.4.3-1.378"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -1393,6 +1393,7 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
                if (tx->req == tx->done) {
                        tx->queue_active = 0;
                        put_be32(htonl(1), tx->send_stop);
+                       mb();
                        mmiowb();
                }
                __netif_tx_unlock(dev_queue);
@@ -2865,6 +2866,7 @@ again:
        if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) {
                tx->queue_active = 1;
                put_be32(htonl(1), tx->send_go);
+               mb();
                mmiowb();
        }
        tx->pkt_start++;