aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch')
-rw-r--r--target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch347
1 files changed, 0 insertions, 347 deletions
diff --git a/target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch b/target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch
deleted file mode 100644
index 80d44ec981..0000000000
--- a/target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch
+++ /dev/null
@@ -1,347 +0,0 @@
-From d27de0ef5ef995df2cc5f5c006c0efcf0a62b6af Mon Sep 17 00:00:00 2001
-From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
-Date: Wed, 6 Jan 2021 22:42:07 +0800
-Subject: [PATCH 6/7] bcm63xx_enet: convert to build_skb
-
-We can increase the efficiency of rx path by using buffers to receive
-packets then build SKBs around them just before passing into the network
-stack. In contrast, preallocating SKBs too early reduces CPU cache
-efficiency.
-
-Check if we're in NAPI context when refilling RX. Normally we're almost
-always running in NAPI context. Dispatch to napi_alloc_frag directly
-instead of relying on netdev_alloc_frag which does the same but
-with the overhead of local_bh_disable/enable.
-
-Tested on BCM6328 320 MHz and iperf3 -M 512 to measure packet/sec
-performance. Included netif_receive_skb_list and NET_IP_ALIGN
-optimizations.
-
-Before:
-[ ID] Interval Transfer Bandwidth Retr
-[ 4] 0.00-10.00 sec 49.9 MBytes 41.9 Mbits/sec 197 sender
-[ 4] 0.00-10.00 sec 49.3 MBytes 41.3 Mbits/sec receiver
-
-After:
-[ ID] Interval Transfer Bandwidth Retr
-[ 4] 0.00-30.00 sec 171 MBytes 47.8 Mbits/sec 272 sender
-[ 4] 0.00-30.00 sec 170 MBytes 47.6 Mbits/sec receiver
-
-Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 111 ++++++++++---------
- drivers/net/ethernet/broadcom/bcm63xx_enet.h | 14 ++-
- 2 files changed, 71 insertions(+), 54 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
-+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
-@@ -221,7 +221,7 @@ static void bcm_enet_mdio_write_mii(stru
- /*
- * refill rx queue
- */
--static int bcm_enet_refill_rx(struct net_device *dev)
-+static int bcm_enet_refill_rx(struct net_device *dev, bool napi_mode)
- {
- struct bcm_enet_priv *priv;
-
-@@ -229,29 +229,29 @@ static int bcm_enet_refill_rx(struct net
-
- while (priv->rx_desc_count < priv->rx_ring_size) {
- struct bcm_enet_desc *desc;
-- struct sk_buff *skb;
-- dma_addr_t p;
- int desc_idx;
- u32 len_stat;
-
- desc_idx = priv->rx_dirty_desc;
- desc = &priv->rx_desc_cpu[desc_idx];
-
-- if (!priv->rx_skb[desc_idx]) {
-- if (priv->enet_is_sw)
-- skb = netdev_alloc_skb_ip_align(dev, priv->rx_skb_size);
-+ if (!priv->rx_buf[desc_idx]) {
-+ void *buf;
-+
-+ if (likely(napi_mode))
-+ buf = napi_alloc_frag(priv->rx_frag_size);
- else
-- skb = netdev_alloc_skb(dev, priv->rx_skb_size);
-- if (!skb)
-+ buf = netdev_alloc_frag(priv->rx_frag_size);
-+ if (unlikely(!buf))
- break;
-- priv->rx_skb[desc_idx] = skb;
-- p = dma_map_single(&priv->pdev->dev, skb->data,
-- priv->rx_skb_size,
-- DMA_FROM_DEVICE);
-- desc->address = p;
-+ priv->rx_buf[desc_idx] = buf;
-+ desc->address = dma_map_single(&priv->pdev->dev,
-+ buf + priv->rx_buf_offset,
-+ priv->rx_buf_size,
-+ DMA_FROM_DEVICE);
- }
-
-- len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
-+ len_stat = priv->rx_buf_size << DMADESC_LENGTH_SHIFT;
- len_stat |= DMADESC_OWNER_MASK;
- if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
- len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
-@@ -291,7 +291,7 @@ static void bcm_enet_refill_rx_timer(str
- struct net_device *dev = priv->net_dev;
-
- spin_lock(&priv->rx_lock);
-- bcm_enet_refill_rx(dev);
-+ bcm_enet_refill_rx(dev, false);
- spin_unlock(&priv->rx_lock);
- }
-
-@@ -321,6 +321,7 @@ static int bcm_enet_receive_queue(struct
- int desc_idx;
- u32 len_stat;
- unsigned int len;
-+ void *buf;
-
- desc_idx = priv->rx_curr_desc;
- desc = &priv->rx_desc_cpu[desc_idx];
-@@ -366,16 +367,14 @@ static int bcm_enet_receive_queue(struct
- }
-
- /* valid packet */
-- skb = priv->rx_skb[desc_idx];
-+ buf = priv->rx_buf[desc_idx];
- len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT;
- /* don't include FCS */
- len -= 4;
-
- if (len < copybreak) {
-- struct sk_buff *nskb;
--
-- nskb = napi_alloc_skb(&priv->napi, len);
-- if (!nskb) {
-+ skb = napi_alloc_skb(&priv->napi, len);
-+ if (unlikely(!skb)) {
- /* forget packet, just rearm desc */
- dev->stats.rx_dropped++;
- continue;
-@@ -383,14 +382,21 @@ static int bcm_enet_receive_queue(struct
-
- dma_sync_single_for_cpu(kdev, desc->address,
- len, DMA_FROM_DEVICE);
-- memcpy(nskb->data, skb->data, len);
-+ memcpy(skb->data, buf + priv->rx_buf_offset, len);
- dma_sync_single_for_device(kdev, desc->address,
- len, DMA_FROM_DEVICE);
-- skb = nskb;
- } else {
-- dma_unmap_single(&priv->pdev->dev, desc->address,
-- priv->rx_skb_size, DMA_FROM_DEVICE);
-- priv->rx_skb[desc_idx] = NULL;
-+ dma_unmap_single(kdev, desc->address,
-+ priv->rx_buf_size, DMA_FROM_DEVICE);
-+ priv->rx_buf[desc_idx] = NULL;
-+
-+ skb = build_skb(buf, priv->rx_frag_size);
-+ if (unlikely(!skb)) {
-+ skb_free_frag(buf);
-+ dev->stats.rx_dropped++;
-+ continue;
-+ }
-+ skb_reserve(skb, priv->rx_buf_offset);
- }
-
- skb_put(skb, len);
-@@ -404,7 +410,7 @@ static int bcm_enet_receive_queue(struct
- netif_receive_skb_list(&rx_list);
-
- if (processed || !priv->rx_desc_count) {
-- bcm_enet_refill_rx(dev);
-+ bcm_enet_refill_rx(dev, true);
-
- /* kick rx dma */
- enet_dmac_writel(priv, priv->dma_chan_en_mask,
-@@ -861,22 +867,22 @@ static void bcm_enet_adjust_link(struct
- priv->pause_tx ? "tx" : "off");
- }
-
--static void bcm_enet_free_rx_skb_ring(struct device *kdev, struct bcm_enet_priv *priv)
-+static void bcm_enet_free_rx_buf_ring(struct device *kdev, struct bcm_enet_priv *priv)
- {
- int i;
-
- for (i = 0; i < priv->rx_ring_size; i++) {
- struct bcm_enet_desc *desc;
-
-- if (!priv->rx_skb[i])
-+ if (!priv->rx_buf[i])
- continue;
-
- desc = &priv->rx_desc_cpu[i];
-- dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
-+ dma_unmap_single(kdev, desc->address, priv->rx_buf_size,
- DMA_FROM_DEVICE);
-- kfree_skb(priv->rx_skb[i]);
-+ skb_free_frag(priv->rx_buf[i]);
- }
-- kfree(priv->rx_skb);
-+ kfree(priv->rx_buf);
- }
-
- /*
-@@ -988,10 +994,10 @@ static int bcm_enet_open(struct net_devi
- priv->tx_curr_desc = 0;
- spin_lock_init(&priv->tx_lock);
-
-- /* init & fill rx ring with skbs */
-- priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *),
-+ /* init & fill rx ring with buffers */
-+ priv->rx_buf = kcalloc(priv->rx_ring_size, sizeof(void *),
- GFP_KERNEL);
-- if (!priv->rx_skb) {
-+ if (!priv->rx_buf) {
- ret = -ENOMEM;
- goto out_free_tx_skb;
- }
-@@ -1008,8 +1014,8 @@ static int bcm_enet_open(struct net_devi
- enet_dmac_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
- ENETDMAC_BUFALLOC, priv->rx_chan);
-
-- if (bcm_enet_refill_rx(dev)) {
-- dev_err(kdev, "cannot allocate rx skb queue\n");
-+ if (bcm_enet_refill_rx(dev, false)) {
-+ dev_err(kdev, "cannot allocate rx buffer queue\n");
- ret = -ENOMEM;
- goto out;
- }
-@@ -1103,7 +1109,7 @@ static int bcm_enet_open(struct net_devi
- return 0;
-
- out:
-- bcm_enet_free_rx_skb_ring(kdev, priv);
-+ bcm_enet_free_rx_buf_ring(kdev, priv);
-
- out_free_tx_skb:
- kfree(priv->tx_skb);
-@@ -1209,8 +1215,8 @@ static int bcm_enet_stop(struct net_devi
- /* force reclaim of all tx buffers */
- bcm_enet_tx_reclaim(dev, 1);
-
-- /* free the rx skb ring */
-- bcm_enet_free_rx_skb_ring(kdev, priv);
-+ /* free the rx buffer ring */
-+ bcm_enet_free_rx_buf_ring(kdev, priv);
-
- /* free remaining allocated memory */
- kfree(priv->tx_skb);
-@@ -1637,9 +1643,12 @@ static int bcm_enet_change_mtu(struct ne
- * align rx buffer size to dma burst len, account FCS since
- * it's appended
- */
-- priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN,
-+ priv->rx_buf_size = ALIGN(actual_mtu + ETH_FCS_LEN,
- priv->dma_maxburst * 4);
-
-+ priv->rx_frag_size = SKB_DATA_ALIGN(priv->rx_buf_offset + priv->rx_buf_size) +
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+
- dev->mtu = new_mtu;
- return 0;
- }
-@@ -1725,6 +1734,7 @@ static int bcm_enet_probe(struct platfor
-
- priv->enet_is_sw = false;
- priv->dma_maxburst = BCMENET_DMA_MAXBURST;
-+ priv->rx_buf_offset = NET_SKB_PAD;
-
- ret = bcm_enet_change_mtu(dev, dev->mtu);
- if (ret)
-@@ -2142,7 +2152,7 @@ static int bcm_enetsw_open(struct net_de
- priv->tx_skb = kcalloc(priv->tx_ring_size, sizeof(struct sk_buff *),
- GFP_KERNEL);
- if (!priv->tx_skb) {
-- dev_err(kdev, "cannot allocate rx skb queue\n");
-+ dev_err(kdev, "cannot allocate tx skb queue\n");
- ret = -ENOMEM;
- goto out_free_tx_ring;
- }
-@@ -2152,11 +2162,11 @@ static int bcm_enetsw_open(struct net_de
- priv->tx_curr_desc = 0;
- spin_lock_init(&priv->tx_lock);
-
-- /* init & fill rx ring with skbs */
-- priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *),
-+ /* init & fill rx ring with buffers */
-+ priv->rx_buf = kcalloc(priv->rx_ring_size, sizeof(void *),
- GFP_KERNEL);
-- if (!priv->rx_skb) {
-- dev_err(kdev, "cannot allocate rx skb queue\n");
-+ if (!priv->rx_buf) {
-+ dev_err(kdev, "cannot allocate rx buffer queue\n");
- ret = -ENOMEM;
- goto out_free_tx_skb;
- }
-@@ -2203,8 +2213,8 @@ static int bcm_enetsw_open(struct net_de
- enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
- ENETDMA_BUFALLOC_REG(priv->rx_chan));
-
-- if (bcm_enet_refill_rx(dev)) {
-- dev_err(kdev, "cannot allocate rx skb queue\n");
-+ if (bcm_enet_refill_rx(dev, false)) {
-+ dev_err(kdev, "cannot allocate rx buffer queue\n");
- ret = -ENOMEM;
- goto out;
- }
-@@ -2303,7 +2313,7 @@ static int bcm_enetsw_open(struct net_de
- return 0;
-
- out:
-- bcm_enet_free_rx_skb_ring(kdev, priv);
-+ bcm_enet_free_rx_buf_ring(kdev, priv);
-
- out_free_tx_skb:
- kfree(priv->tx_skb);
-@@ -2353,8 +2363,8 @@ static int bcm_enetsw_stop(struct net_de
- /* force reclaim of all tx buffers */
- bcm_enet_tx_reclaim(dev, 1);
-
-- /* free the rx skb ring */
-- bcm_enet_free_rx_skb_ring(kdev, priv);
-+ /* free the rx buffer ring */
-+ bcm_enet_free_rx_buf_ring(kdev, priv);
-
- /* free remaining allocated memory */
- kfree(priv->tx_skb);
-@@ -2655,6 +2665,7 @@ static int bcm_enetsw_probe(struct platf
- priv->rx_ring_size = BCMENET_DEF_RX_DESC;
- priv->tx_ring_size = BCMENET_DEF_TX_DESC;
- priv->dma_maxburst = BCMENETSW_DMA_MAXBURST;
-+ priv->rx_buf_offset = NET_SKB_PAD + NET_IP_ALIGN;
-
- pd = dev_get_platdata(&pdev->dev);
- if (pd) {
---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
-+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
-@@ -230,11 +230,17 @@ struct bcm_enet_priv {
- /* next dirty rx descriptor to refill */
- int rx_dirty_desc;
-
-- /* size of allocated rx skbs */
-- unsigned int rx_skb_size;
-+ /* size of allocated rx buffers */
-+ unsigned int rx_buf_size;
-
-- /* list of skb given to hw for rx */
-- struct sk_buff **rx_skb;
-+ /* allocated rx buffer offset */
-+ unsigned int rx_buf_offset;
-+
-+ /* size of allocated rx frag */
-+ unsigned int rx_frag_size;
-+
-+ /* list of buffer given to hw for rx */
-+ void **rx_buf;
-
- /* used when rx skb allocation failed, so we defer rx queue
- * refill */