bnx2: Fix panic in bnx2_poll_work().
Add barrier() to bnx2_get_hw_{tx|rx}_cons() to fix this issue: http://bugzilla.kernel.org/show_bug.cgi?id=12698 This issue was reported by multiple i386 users. Without barrier(), the compiled code looks like the following where %eax contains the address of the tx_cons or rx_cons in the DMA status block. The status block contents can change between the cmpb and the movzwl instruction. The driver would crash if the value was not 0xff during the cmpb instruction, but changed to 0xff during the movzwl instruction. 6828: 80 38 ff cmpb $0xff,(%eax) 682b: 0f b7 10 movzwl (%eax),%edx With the added barrier(), the compiled code now looks correct: 683d: 0f b7 10 movzwl (%eax),%edx 6840: 0f b6 c2 movzbl %dl,%eax 6843: 3d ff 00 00 00 cmp $0xff,%eax Thanks to Pascal de Bruijn <pmjdebruijn@pcode.nl> for reporting the problem and Holger Noefer <hnoefer@pironet-ndh.com> for patiently testing test patches for us. Also updated version to 2.0.1. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6473990c7f
commit
581daf7e00
|
@ -54,8 +54,8 @@
|
|||
|
||||
#define DRV_MODULE_NAME "bnx2"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "2.0.0"
|
||||
#define DRV_MODULE_RELDATE "April 2, 2009"
|
||||
#define DRV_MODULE_VERSION "2.0.1"
|
||||
#define DRV_MODULE_RELDATE "May 6, 2009"
|
||||
#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw"
|
||||
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw"
|
||||
#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw"
|
||||
|
@ -2600,6 +2600,7 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
|
|||
/* Tell compiler that status block fields can change. */
|
||||
barrier();
|
||||
cons = *bnapi->hw_tx_cons_ptr;
|
||||
barrier();
|
||||
if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT))
|
||||
cons++;
|
||||
return cons;
|
||||
|
@ -2879,6 +2880,7 @@ bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi)
|
|||
/* Tell compiler that status block fields can change. */
|
||||
barrier();
|
||||
cons = *bnapi->hw_rx_cons_ptr;
|
||||
barrier();
|
||||
if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT))
|
||||
cons++;
|
||||
return cons;
|
||||
|
|
Loading…
Reference in New Issue