Commit f3002c13 authored by hpreg@vmware.com's avatar hpreg@vmware.com Committed by David S. Miller

vmxnet3: use DMA memory barriers where required

The gen bits must be read first from (resp. written last to) DMA memory.
The proper way to enforce this on Linux is to call dma_rmb() (resp.
dma_wmb()).
Signed-off-by: default avatarRegis Duchesne <hpreg@vmware.com>
Acked-by: default avatarRonak Doshi <doshir@vmware.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 61aeecea
...@@ -369,6 +369,11 @@ vmxnet3_tq_tx_complete(struct vmxnet3_tx_queue *tq, ...@@ -369,6 +369,11 @@ vmxnet3_tq_tx_complete(struct vmxnet3_tx_queue *tq,
gdesc = tq->comp_ring.base + tq->comp_ring.next2proc; gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
while (VMXNET3_TCD_GET_GEN(&gdesc->tcd) == tq->comp_ring.gen) { while (VMXNET3_TCD_GET_GEN(&gdesc->tcd) == tq->comp_ring.gen) {
/* Prevent any &gdesc->tcd field from being (speculatively)
* read before (&gdesc->tcd)->gen is read.
*/
dma_rmb();
completed += vmxnet3_unmap_pkt(VMXNET3_TCD_GET_TXIDX( completed += vmxnet3_unmap_pkt(VMXNET3_TCD_GET_TXIDX(
&gdesc->tcd), tq, adapter->pdev, &gdesc->tcd), tq, adapter->pdev,
adapter); adapter);
...@@ -1103,6 +1108,11 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, ...@@ -1103,6 +1108,11 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
gdesc->txd.tci = skb_vlan_tag_get(skb); gdesc->txd.tci = skb_vlan_tag_get(skb);
} }
/* Ensure that the write to (&gdesc->txd)->gen will be observed after
* all other writes to &gdesc->txd.
*/
dma_wmb();
/* finally flips the GEN bit of the SOP desc. */ /* finally flips the GEN bit of the SOP desc. */
gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^ gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^
VMXNET3_TXD_GEN); VMXNET3_TXD_GEN);
...@@ -1298,6 +1308,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, ...@@ -1298,6 +1308,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
*/ */
break; break;
} }
/* Prevent any rcd field from being (speculatively) read before
* rcd->gen is read.
*/
dma_rmb();
BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2 && BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2 &&
rcd->rqID != rq->dataRingQid); rcd->rqID != rq->dataRingQid);
idx = rcd->rxdIdx; idx = rcd->rxdIdx;
...@@ -1528,6 +1544,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, ...@@ -1528,6 +1544,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
ring->next2comp = idx; ring->next2comp = idx;
num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring); num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring);
ring = rq->rx_ring + ring_idx; ring = rq->rx_ring + ring_idx;
/* Ensure that the writes to rxd->gen bits will be observed
* after all other writes to rxd objects.
*/
dma_wmb();
while (num_to_alloc) { while (num_to_alloc) {
vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd, vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd,
&rxCmdDesc); &rxCmdDesc);
......
...@@ -69,12 +69,12 @@ ...@@ -69,12 +69,12 @@
/* /*
* Version numbers * Version numbers
*/ */
#define VMXNET3_DRIVER_VERSION_STRING "1.4.15.0-k" #define VMXNET3_DRIVER_VERSION_STRING "1.4.16.0-k"
/* Each byte of this 32-bit integer encodes a version number in /* Each byte of this 32-bit integer encodes a version number in
* VMXNET3_DRIVER_VERSION_STRING. * VMXNET3_DRIVER_VERSION_STRING.
*/ */
#define VMXNET3_DRIVER_VERSION_NUM 0x01040f00 #define VMXNET3_DRIVER_VERSION_NUM 0x01041000
#if defined(CONFIG_PCI_MSI) #if defined(CONFIG_PCI_MSI)
/* RSS only makes sense if MSI-X is supported. */ /* RSS only makes sense if MSI-X is supported. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment