From 34d8a7f63fe6cb7b760e80f9a01d3614bcfc8115 Mon Sep 17 00:00:00 2001 From: Oskari Lemmela Date: Mon, 21 Aug 2023 08:41:37 +0300 Subject: [PATCH] ipq806x: 5.15: revert upstream commit to fix #11676 Commit d5a05e69ac6e4 ("net: stmmac: Use hrtimer for TX coalescing") causes high CPU usage due to hrtimer raw spin locks. Fixes: #11676 Signed-off-by: Oskari Lemmela [ renumber and rename revert patch ] Signed-off-by: Christian Marangi --- ...stmmac-Use-hrtimer-for-TX-coalescing.patch | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 target/linux/ipq806x/patches-5.15/700-Revert-net-stmmac-Use-hrtimer-for-TX-coalescing.patch diff --git a/target/linux/ipq806x/patches-5.15/700-Revert-net-stmmac-Use-hrtimer-for-TX-coalescing.patch b/target/linux/ipq806x/patches-5.15/700-Revert-net-stmmac-Use-hrtimer-for-TX-coalescing.patch new file mode 100644 index 00000000000..11360c92a66 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/700-Revert-net-stmmac-Use-hrtimer-for-TX-coalescing.patch @@ -0,0 +1,155 @@ +From 0db3e9ac75b107d2158b227426f58df9bb00529f Mon Sep 17 00:00:00 2001 +From: Oskari Lemmela +Date: Sun, 20 Aug 2023 15:25:09 +0300 +Subject: [PATCH] Revert "net: stmmac: Use hrtimer for TX coalescing" + +This reverts commit d5a05e69ac6e4c431c380ced2b534c91f7bc3280. + +hrtimer uses raw_spin_lock which causes high CPU usage. +ipq806x platform's TCP transmit speed dropped from 950 Mbps to 250 Mbps +due to high ksoftirq. + +Signed-off-by: Oskari Lemmela +--- + drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 +-- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +++++++------------ + 2 files changed, 10 insertions(+), 18 deletions(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h +@@ -13,7 +13,6 @@ + #define DRV_MODULE_VERSION "Jan_2016" + + #include +-#include + #include + #include + #include +@@ -59,7 +58,7 @@ struct stmmac_tx_info { + struct stmmac_tx_queue { + u32 tx_count_frames; + int tbs; +- struct hrtimer txtimer; ++ struct timer_list txtimer; + u32 queue_index; + struct stmmac_priv *priv_data; + struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp; +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -142,7 +142,7 @@ static void stmmac_init_fs(struct net_de + static void stmmac_exit_fs(struct net_device *dev); + #endif + +-#define STMMAC_COAL_TIMER(x) (ns_to_ktime((x) * NSEC_PER_USEC)) ++#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) + + int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled) + { +@@ -2725,9 +2725,7 @@ static int stmmac_tx_clean(struct stmmac + + /* We still have pending packets, let's call for a new scheduling */ + if (tx_q->dirty_tx != tx_q->cur_tx) +- hrtimer_start(&tx_q->txtimer, +- STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), +- HRTIMER_MODE_REL); ++ mod_timer(&tx_q->txtimer, STMMAC_COAL_TIMER(priv->tx_coal_timer[queue])); + + __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue)); + +@@ -3019,9 +3017,7 @@ static void stmmac_tx_timer_arm(struct s + { + struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; + +- hrtimer_start(&tx_q->txtimer, +- STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), +- HRTIMER_MODE_REL); ++ mod_timer(&tx_q->txtimer, STMMAC_COAL_TIMER(priv->tx_coal_timer[queue])); + } + + /** +@@ -3030,9 +3026,9 @@ static void stmmac_tx_timer_arm(struct s + * Description: + * This is the timer handler to directly invoke the stmmac_tx_clean. + */ +-static enum hrtimer_restart stmmac_tx_timer(struct hrtimer *t) ++static void stmmac_tx_timer(struct timer_list *t) + { +- struct stmmac_tx_queue *tx_q = container_of(t, struct stmmac_tx_queue, txtimer); ++ struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer); + struct stmmac_priv *priv = tx_q->priv_data; + struct stmmac_channel *ch; + struct napi_struct *napi; +@@ -3048,8 +3044,6 @@ static enum hrtimer_restart stmmac_tx_ti + spin_unlock_irqrestore(&ch->lock, flags); + __napi_schedule(napi); + } +- +- return HRTIMER_NORESTART; + } + + /** +@@ -3072,8 +3066,7 @@ static void stmmac_init_coalesce(struct + priv->tx_coal_frames[chan] = STMMAC_TX_FRAMES; + priv->tx_coal_timer[chan] = STMMAC_COAL_TX_TIMER; + +- hrtimer_init(&tx_q->txtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); +- tx_q->txtimer.function = stmmac_tx_timer; ++ timer_setup(&tx_q->txtimer, stmmac_tx_timer, 0); + } + + for (chan = 0; chan < rx_channel_count; chan++) +@@ -3902,7 +3895,7 @@ irq_error: + phylink_stop(priv->phylink); + + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) +- hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); ++ del_timer_sync(&priv->dma_conf.tx_queue[chan].txtimer); + + stmmac_hw_teardown(dev); + init_error: +@@ -3958,7 +3951,7 @@ static int stmmac_release(struct net_dev + stmmac_disable_all_queues(priv); + + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) +- hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); ++ del_timer_sync(&priv->dma_conf.tx_queue[chan].txtimer); + + netif_tx_disable(dev); + +@@ -6655,7 +6648,7 @@ void stmmac_xdp_release(struct net_devic + stmmac_disable_all_queues(priv); + + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) +- hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); ++ del_timer_sync(&priv->dma_conf.tx_queue[chan].txtimer); + + /* Free the IRQ lines */ + stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0); +@@ -6750,8 +6743,7 @@ int stmmac_xdp_open(struct net_device *d + stmmac_set_tx_tail_ptr(priv, priv->ioaddr, + tx_q->tx_tail_addr, chan); + +- hrtimer_init(&tx_q->txtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); +- tx_q->txtimer.function = stmmac_tx_timer; ++ timer_setup(&tx_q->txtimer, stmmac_tx_timer, 0); + } + + /* Enable the MAC Rx/Tx */ +@@ -6774,7 +6766,7 @@ int stmmac_xdp_open(struct net_device *d + + irq_error: + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) +- hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); ++ del_timer_sync(&priv->dma_conf.tx_queue[chan].txtimer); + + stmmac_hw_teardown(dev); + init_error: +@@ -7495,7 +7487,7 @@ int stmmac_suspend(struct device *dev) + stmmac_disable_all_queues(priv); + + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) +- hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); ++ del_timer_sync(&priv->dma_conf.tx_queue[chan].txtimer); + + if (priv->eee_enabled) { + priv->tx_path_in_lpi_mode = false;