summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Jensen <jonas.jensen@gmail.com>2014-08-25 16:22:22 +0200
committerDavid S. Miller <davem@davemloft.net>2014-08-25 17:25:39 -0700
commit9fe1b3bc8d9182e950a744e4a47187420efa67f3 (patch)
tree1284841770135bf6cdc76f5aeb102a8fa43f0648
parentb853f31940c84cce6a3f5cb4f529b029906ee69c (diff)
net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
build_skb() is used to make skbs out of existing RX ring memory which is bad because the RX ring is allocated only once, on probe. Memory corruption occur because said memory is reclaimed, i.e. __kfree_skb() (and eventually put_page()). Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy(). Remove SKB_DATA_ALIGN() from RX buffer size while we're at it. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041 Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/moxa/moxart_ether.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index eed70d9f0d9d..d66058d5c429 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
if (len > RX_BUF_SIZE)
len = RX_BUF_SIZE;
- skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+ skb = netdev_alloc_skb_ip_align(ndev, len);
+
if (unlikely(!skb)) {
- net_dbg_ratelimited("build_skb failed\n");
+ net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
priv->stats.rx_dropped++;
priv->stats.rx_errors++;
}
+ memcpy(skb->data, priv->rx_buf[rx_head], len);
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, ndev);
napi_gro_receive(&priv->napi, skb);
@@ -464,8 +466,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
spin_lock_init(&priv->txlock);
priv->tx_buf_size = TX_BUF_SIZE;
- priv->rx_buf_size = RX_BUF_SIZE +
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ priv->rx_buf_size = RX_BUF_SIZE;
priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE *
TX_DESC_NUM, &priv->tx_base,