diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 8dcc17774b..8bf17f629c 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -219,8 +219,9 @@ static inline void fe_set_txd(struct fe_tx_dma *txd, struct fe_tx_dma *dma_txd) static void fe_clean_rx(struct fe_priv *priv) { - int i; struct fe_rx_ring *ring = &priv->rx_ring; + struct page *page; + int i; if (ring->rx_data) { for (i = 0; i < ring->rx_ring_size; i++) @@ -244,6 +245,13 @@ static void fe_clean_rx(struct fe_priv *priv) ring->rx_phys); ring->rx_dma = NULL; } + + if (!ring->frag_cache.va) + return; + + page = virt_to_page(ring->frag_cache.va); + __page_frag_cache_drain(page, ring->frag_cache.pagecnt_bias); + memset(&ring->frag_cache, 0, sizeof(ring->frag_cache)); } static int fe_alloc_rx(struct fe_priv *priv) @@ -258,7 +266,9 @@ static int fe_alloc_rx(struct fe_priv *priv) goto no_rx_mem; for (i = 0; i < ring->rx_ring_size; i++) { - ring->rx_data[i] = netdev_alloc_frag(ring->frag_size); + ring->rx_data[i] = page_frag_alloc(&ring->frag_cache, + ring->frag_size, + GFP_KERNEL); if (!ring->rx_data[i]) goto no_rx_mem; } @@ -881,7 +891,8 @@ static int fe_poll_rx(struct napi_struct *napi, int budget, break; /* alloc new buffer */ - new_data = netdev_alloc_frag(ring->frag_size); + new_data = page_frag_alloc(&ring->frag_cache, ring->frag_size, + GFP_ATOMIC); if (unlikely(!new_data)) { stats->rx_dropped++; goto release_desc; diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h index 517d8ba4dc..c42126116f 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -454,6 +454,7 @@ struct fe_tx_ring { }; struct fe_rx_ring { + struct page_frag_cache frag_cache; struct fe_rx_dma *rx_dma; u8 **rx_data; dma_addr_t rx_phys;