skge: fix broken driver
authorMikulas Patocka <mpatocka@redhat.com>
Thu, 19 Sep 2013 18:13:17 +0000 (14:13 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 19 Sep 2013 18:15:15 +0000 (14:15 -0400)
The patch 136d8f377e1575463b47840bc5f1b22d94bf8f63 broke the skge driver.
Note this part of the patch:
+               if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) {
+                       dev_kfree_skb(nskb);
+                       goto resubmit;
+               }
+
                pci_unmap_single(skge->hw->pdev,
                                 dma_unmap_addr(e, mapaddr),
                                 dma_unmap_len(e, maplen),
                                 PCI_DMA_FROMDEVICE);
                skb = e->skb;
                prefetch(skb->data);
-               skge_rx_setup(skge, e, nskb, skge->rx_buf_size);

The function skge_rx_setup modifies e->skb to point to the new skb. Thus,
after this change, the new buffer, not the old, is returned to the
networking stack.

This bug is present in kernels 3.11, 3.11.1 and 3.12-rc1. The patch should
be queued for 3.11-stable.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: Vasiliy Glazov <vascom2@gmail.com>
Tested-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/skge.c

index ef94a591f9e550ed31d654c2cc1fa2ba7bc1bef9..1a9c4f6269ea8a3422781bc14f2f7164b57ff7bf 100644 (file)
@@ -3092,6 +3092,9 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
                if (!nskb)
                        goto resubmit;
 
+               skb = e->skb;
+               prefetch(skb->data);
+
                if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) {
                        dev_kfree_skb(nskb);
                        goto resubmit;
@@ -3101,8 +3104,6 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
                                 dma_unmap_addr(e, mapaddr),
                                 dma_unmap_len(e, maplen),
                                 PCI_DMA_FROMDEVICE);
-               skb = e->skb;
-               prefetch(skb->data);
        }
 
        skb_put(skb, len);