aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/myri10ge/myri10ge.c
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2008-11-10 07:58:41 -0500
committerJeff Garzik <jgarzik@redhat.com>2008-11-11 03:49:53 -0500
commit8c2f5fa51e1b22db53acf4f3918b6f590b4a35a1 (patch)
tree47d8a786fa02c5c371287e7325015a604e8e285b /drivers/net/myri10ge/myri10ge.c
parentdf02c6ff2e3937379b31ea161b53229134fe92f7 (diff)
myri10ge: fix stop/go ordering even more
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>
Diffstat (limited to 'drivers/net/myri10ge/myri10ge.c')
-rw-r--r--drivers/net/myri10ge/myri10ge.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index a5f428bcc0eb..b37867097308 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -75,7 +75,7 @@
75#include "myri10ge_mcp.h" 75#include "myri10ge_mcp.h"
76#include "myri10ge_mcp_gen_header.h" 76#include "myri10ge_mcp_gen_header.h"
77 77
78#define MYRI10GE_VERSION_STR "1.4.3-1.375" 78#define MYRI10GE_VERSION_STR "1.4.3-1.378"
79 79
80MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); 80MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
81MODULE_AUTHOR("Maintainer: help@myri.com"); 81MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -1393,6 +1393,7 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
1393 if (tx->req == tx->done) { 1393 if (tx->req == tx->done) {
1394 tx->queue_active = 0; 1394 tx->queue_active = 0;
1395 put_be32(htonl(1), tx->send_stop); 1395 put_be32(htonl(1), tx->send_stop);
1396 mb();
1396 mmiowb(); 1397 mmiowb();
1397 } 1398 }
1398 __netif_tx_unlock(dev_queue); 1399 __netif_tx_unlock(dev_queue);
@@ -2865,6 +2866,7 @@ again:
2865 if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) { 2866 if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) {
2866 tx->queue_active = 1; 2867 tx->queue_active = 1;
2867 put_be32(htonl(1), tx->send_go); 2868 put_be32(htonl(1), tx->send_go);
2869 mb();
2868 mmiowb(); 2870 mmiowb();
2869 } 2871 }
2870 tx->pkt_start++; 2872 tx->pkt_start++;