From 9c87378caae19f536d22b6c46e2364749e3ea3ff Mon Sep 17 00:00:00 2001 From: AmadeusGhost <42570690+AmadeusGhost@users.noreply.github.com> Date: Thu, 27 Feb 2020 10:59:55 +0800 Subject: [PATCH] ipq40xx: essedma Time-balanced scheduling add script to adjust cpu affinity essedma Time-balanced scheduling: TX: CPU: |3 | |2 | |1 | |0 | TX-Q: |15-14-13-12| |11-10-09-08| |07-06-05-04| |03-02-01-00| ___________| | | | ______________________| | | | _________________________________| | | | TX-P: |15-11-07-03| |14-10-06-02| |13-09-05-01| |12-08-04-00| TX-S: |---+--+--+-| |+-----+--+-| |+--+-----+-| |+--+--+----| | | | | RX: | | | | CPU: |3 | | 2 | | 1 | | 0 | RX-Q: |07-06 | |05-04 | |03-02 | |01-00 | Signed-off-by: Chen Minqiang --- .../base-files/etc/init.d/adjust_network | 1 + .../ipq40xx/base-files/lib/adjust_network.sh | 7 +- ...essedma-fixup-ethernet-driver-rx-bug.patch | 144 ------------------ ...ssedma-add-fix-for-memory-allocation.patch | 14 +- ...q-to-be-adaptive-of-cpus-and-netdev.patch} | 64 +++----- .../716-essedma-reduce-write-reg.patch | 54 +++++++ 6 files changed, 89 insertions(+), 195 deletions(-) delete mode 100644 target/linux/ipq40xx/patches-4.14/713-0001-essedma-fixup-ethernet-driver-rx-bug.patch rename target/linux/ipq40xx/patches-4.14/{713-0002-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch => 715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch} (80%) create mode 100644 target/linux/ipq40xx/patches-4.14/716-essedma-reduce-write-reg.patch diff --git a/target/linux/ipq40xx/base-files/etc/init.d/adjust_network b/target/linux/ipq40xx/base-files/etc/init.d/adjust_network index 788b833ff4..02af81983e 100755 --- a/target/linux/ipq40xx/base-files/etc/init.d/adjust_network +++ b/target/linux/ipq40xx/base-files/etc/init.d/adjust_network @@ -8,6 +8,7 @@ adjust_smp_affinity() { test -f /lib/adjust_network.sh && { . /lib/adjust_network.sh + adjust_eth_queue adjust_edma_smp_affinity adjust_radio_smp_affinity } diff --git a/target/linux/ipq40xx/base-files/lib/adjust_network.sh b/target/linux/ipq40xx/base-files/lib/adjust_network.sh index 95ffedc04f..99423022c5 100644 --- a/target/linux/ipq40xx/base-files/lib/adjust_network.sh +++ b/target/linux/ipq40xx/base-files/lib/adjust_network.sh @@ -20,7 +20,7 @@ adjust_edma_smp_affinity() { local tx_irq_num for tx_num in `seq 0 1 15` ; do - cpu=`printf "%x" $((1<<((tx_num/4+3)%nr)))` + cpu=`printf "%x" $((1<<((tx_num/4+0)%nr)))` tx_irq_num=`grep -m1 edma_eth_tx$tx_num /proc/interrupts | cut -d ':' -f 1 | tail -n1 | tr -d ' '` [ -n "$tx_irq_num" ] && echo $cpu > /proc/irq/$tx_irq_num/smp_affinity done @@ -68,14 +68,17 @@ adjust_radio_smp_affinity() { ################################################ adjust_eth_queue() { local nr=`cat /proc/cpuinfo | grep processor | wc -l` - local cpu=`printf "%x" $(((1< $exps echo 256 > `dirname $exps`/rps_flow_cnt done diff --git a/target/linux/ipq40xx/patches-4.14/713-0001-essedma-fixup-ethernet-driver-rx-bug.patch b/target/linux/ipq40xx/patches-4.14/713-0001-essedma-fixup-ethernet-driver-rx-bug.patch deleted file mode 100644 index 75267b688d..0000000000 --- a/target/linux/ipq40xx/patches-4.14/713-0001-essedma-fixup-ethernet-driver-rx-bug.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 0bcfbe3c613d6ed8044404bc1cc3c29ff961d89c Mon Sep 17 00:00:00 2001 -From: Chen Minqiang -Date: Thu, 15 Mar 2018 04:59:57 +0800 -Subject: [PATCH 1/2] essedma: fixup ethernet driver rx bug - - - modify the error rx ring full conditions - - in rare cases, out of memory allocation failure causes the receive queues stop - we use the timer to re-alloc rx rings under these circumstances - -Signed-off-by: Chen Minqiang ---- - drivers/net/ethernet/qualcomm/essedma/edma.c | 51 ++++++++++++++++++++++-- - drivers/net/ethernet/qualcomm/essedma/edma.h | 3 ++ - drivers/net/ethernet/qualcomm/essedma/edma_axi.c | 8 ++++ - 3 files changed, 58 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c -index fecc0ba..3f1da93 100644 ---- a/drivers/net/ethernet/qualcomm/essedma/edma.c -+++ b/drivers/net/ethernet/qualcomm/essedma/edma.c -@@ -530,6 +530,47 @@ static int edma_rx_complete_paged(struct sk_buff *skb, u16 num_rfds, u16 length, - return sw_next_to_clean; - } - -+static int edma_rfd_desc_unused(struct edma_rfd_desc_ring *erdr) -+{ -+ if (erdr->sw_next_to_clean > erdr->sw_next_to_fill) -+ return erdr->sw_next_to_clean - erdr->sw_next_to_fill - 1; -+ return erdr->count + erdr->sw_next_to_clean - erdr->sw_next_to_fill - 1; -+} -+ -+void edma_rx_realloc(unsigned long data) -+{ -+ struct edma_per_cpu_queues_info *edma_percpu_info = (struct edma_per_cpu_queues_info *)data; -+ struct edma_common_info *edma_cinfo = edma_percpu_info->edma_cinfo; -+ s32 status = edma_percpu_info->rx_realloc_status; -+ -+ while (status) { -+ int queue_id; -+ int ret_count; -+ struct edma_rfd_desc_ring *erdr; -+ -+ queue_id = ffs(status) - 1; -+ erdr = edma_cinfo->rfd_ring[queue_id]; -+ ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, edma_rfd_desc_unused(erdr), queue_id); -+ if (ret_count == 0) { -+ edma_percpu_info->rx_realloc_status &= ~(1 << queue_id); -+ } -+ status &= ~(1 << queue_id); -+ } -+ -+ if (edma_percpu_info->rx_realloc_status) { -+ mod_timer(&edma_percpu_info->rx_realloc_timer, jiffies + HZ); -+ } -+} -+ -+static inline void edma_realloc_timer_start(struct napi_struct *napi, int queue_id) -+{ -+ struct edma_per_cpu_queues_info *edma_percpu_info = container_of(napi, -+ struct edma_per_cpu_queues_info, napi); -+ -+ edma_percpu_info->rx_realloc_status |= (1 << queue_id); -+ mod_timer(&edma_percpu_info->rx_realloc_timer, jiffies + 5 * HZ); /* restart alloc in 5 secs */ -+} -+ - /* - * edma_rx_complete() - * Main api called from the poll function to process rx packets. -@@ -754,10 +795,12 @@ static void edma_rx_complete(struct edma_common_info *edma_cinfo, - erdr->sw_next_to_clean = sw_next_to_clean; - - /* Refill here in case refill threshold wasn't reached */ -- if (likely(cleaned_count)) { -- ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); -- if (ret_count) -+ if (edma_rfd_desc_unused(erdr)) { -+ ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, edma_rfd_desc_unused(erdr), queue_id); -+ if (ret_count) { - dev_dbg(&pdev->dev, "Not all buffers was reallocated"); -+ edma_realloc_timer_start(napi, queue_id); -+ } - edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), - erdr->sw_next_to_clean); - } -@@ -1801,7 +1844,7 @@ int edma_configure(struct edma_common_info *edma_cinfo) - /* Allocate the RX buffer */ - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - struct edma_rfd_desc_ring *ring = edma_cinfo->rfd_ring[j]; -- ret_count = edma_alloc_rx_buf(edma_cinfo, ring, ring->count, j); -+ ret_count = edma_alloc_rx_buf(edma_cinfo, ring, edma_rfd_desc_unused(ring), j); - if (ret_count) { - dev_dbg(&edma_cinfo->pdev->dev, "not all rx buffers allocated\n"); - } -diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.h b/drivers/net/ethernet/qualcomm/essedma/edma.h -index 5d6dc73..29c8379 100644 ---- a/drivers/net/ethernet/qualcomm/essedma/edma.h -+++ b/drivers/net/ethernet/qualcomm/essedma/edma.h -@@ -304,6 +304,8 @@ struct edma_per_cpu_queues_info { - u32 tx_start; /* tx queue start */ - u32 rx_start; /* rx queue start */ - struct edma_common_info *edma_cinfo; /* edma common info */ -+ u32 rx_realloc_status; -+ struct timer_list rx_realloc_timer; - }; - - /* edma specific common info */ -@@ -448,6 +450,7 @@ void edma_change_tx_coalesce(int usecs); - void edma_change_rx_coalesce(int usecs); - void edma_get_tx_rx_coalesce(u32 *reg_val); - void edma_clear_irq_status(void); -+void edma_rx_realloc(unsigned long data); - void ess_set_port_status_speed(struct edma_common_info *edma_cinfo, - struct phy_device *phydev, uint8_t port_id); - #endif /* _EDMA_H_ */ -diff --git a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c -index 81fc1e1..d9f8b52 100644 ---- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c -+++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c -@@ -1131,6 +1131,11 @@ static int edma_axi_probe(struct platform_device *pdev) - edma_cinfo->edma_percpu_info[i].rx_status = 0; - edma_cinfo->edma_percpu_info[i].edma_cinfo = edma_cinfo; - -+ edma_cinfo->edma_percpu_info[i].rx_realloc_status = 0; -+ init_timer(&edma_cinfo->edma_percpu_info[i].rx_realloc_timer); -+ edma_cinfo->edma_percpu_info[i].rx_realloc_timer.function = edma_rx_realloc; -+ edma_cinfo->edma_percpu_info[i].rx_realloc_timer.data = (unsigned long)&edma_cinfo->edma_percpu_info[i]; -+ - /* Request irq per core */ - for (j = edma_cinfo->edma_percpu_info[i].tx_start; - j < tx_start[i] + 4; j++) { -@@ -1259,7 +1264,10 @@ err_configure: - err_rmap_add_fail: - edma_free_irqs(adapter[0]); - for (i = 0; i < CONFIG_NR_CPUS; i++) -+ { - napi_disable(&edma_cinfo->edma_percpu_info[i].napi); -+ del_timer_sync(&edma_cinfo->edma_percpu_info[i].rx_realloc_timer); -+ } - err_reset: - err_unregister_sysctl_tbl: - err_rmap_alloc_fail: --- -2.7.4 - diff --git a/target/linux/ipq40xx/patches-4.14/714-essedma-add-fix-for-memory-allocation.patch b/target/linux/ipq40xx/patches-4.14/714-essedma-add-fix-for-memory-allocation.patch index 6c696caf4b..5b9fcf780c 100644 --- a/target/linux/ipq40xx/patches-4.14/714-essedma-add-fix-for-memory-allocation.patch +++ b/target/linux/ipq40xx/patches-4.14/714-essedma-add-fix-for-memory-allocation.patch @@ -115,14 +115,12 @@ Reviewed-by: Grant Grundler } /* At this point skb should go to stack */ -@@ -756,13 +769,17 @@ static u16 edma_rx_complete(struct edma_common_info *edma_cinfo, +@@ -756,11 +769,17 @@ static void edma_rx_complete(struct edma /* Refill here in case refill threshold wasn't reached */ - if (edma_rfd_desc_unused(erdr)) { - ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, edma_rfd_desc_unused(erdr), queue_id); -- if (ret_count) { + if (likely(cleaned_count)) { + ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); +- if (ret_count) - dev_dbg(&pdev->dev, "Not all buffers was reallocated"); -- edma_realloc_timer_start(napi, queue_id); -- } + erdr->pending_fill = ret_count; + if (ret_count) { + if (net_ratelimit()) @@ -137,7 +135,7 @@ Reviewed-by: Grant Grundler } /* edma_delete_rfs_filter() -@@ -2064,6 +2081,7 @@ int edma_poll(struct napi_struct *napi, +@@ -2064,6 +2083,7 @@ int edma_poll(struct napi_struct *napi, u32 shadow_rx_status, shadow_tx_status; int queue_id; int i, work_done = 0; @@ -145,7 +143,7 @@ Reviewed-by: Grant Grundler /* Store the Rx/Tx status by ANDing it with * appropriate CPU RX?TX mask -@@ -2097,13 +2115,19 @@ int edma_poll(struct napi_struct *napi, +@@ -2097,13 +2117,19 @@ int edma_poll(struct napi_struct *napi, */ while (edma_percpu_info->rx_status) { queue_id = ffs(edma_percpu_info->rx_status) - 1; diff --git a/target/linux/ipq40xx/patches-4.14/713-0002-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch b/target/linux/ipq40xx/patches-4.14/715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch similarity index 80% rename from target/linux/ipq40xx/patches-4.14/713-0002-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch rename to target/linux/ipq40xx/patches-4.14/715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch index 6c6ef84abc..d8d09c1425 100644 --- a/target/linux/ipq40xx/patches-4.14/713-0002-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch +++ b/target/linux/ipq40xx/patches-4.14/715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch @@ -1,20 +1,5 @@ -From 7be0cb35513b07bf74d93d052d57b12e2c654b43 Mon Sep 17 00:00:00 2001 -From: Chen Minqiang -Date: Thu, 15 Mar 2018 05:04:37 +0800 -Subject: [PATCH 2/2] essedma: refine txq to be adaptive of cpus and netdev - - - use 4 queue for each cpu if only 1 netdev - - use all 16 txqueue if only 1 netdev - -Signed-off-by: Chen Minqiang ---- - drivers/net/ethernet/qualcomm/essedma/edma.c | 22 +++++-------- - drivers/net/ethernet/qualcomm/essedma/edma.h | 5 +-- - drivers/net/ethernet/qualcomm/essedma/edma_axi.c | 40 ++++++++++++++---------- - 3 files changed, 35 insertions(+), 32 deletions(-) - diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c -index 3f1da93..05f9ce9 100644 +index 724f355..7a16236 100644 --- a/drivers/net/ethernet/qualcomm/essedma/edma.c +++ b/drivers/net/ethernet/qualcomm/essedma/edma.c @@ -22,14 +22,6 @@ extern struct net_device *edma_netdev[EDMA_MAX_PORTID_SUPPORTED]; @@ -32,7 +17,7 @@ index 3f1da93..05f9ce9 100644 /* edma_alloc_tx_ring() * Allocate Tx descriptors ring */ -@@ -1042,13 +1034,14 @@ static inline u16 edma_tpd_available(struct edma_common_info *edma_cinfo, +@@ -1014,13 +1006,14 @@ static inline u16 edma_tpd_available(struct edma_common_info *edma_cinfo, /* edma_tx_queue_get() * Get the starting number of the queue */ @@ -45,23 +30,23 @@ index 3f1da93..05f9ce9 100644 + * FIXME we just simple use jiffies for time base balance */ - return adapter->tx_start_offset[txq_id] + edma_skb_priority_offset(skb); -+ return adapter->tx_start_offset[txq_id] + (jiffies % edma_cinfo->num_txq_per_core_netdev); ++ return adapter->tx_start_offset[txq_id] + (smp_processor_id() % edma_cinfo->num_txq_per_core_netdev); } /* edma_tx_update_hw_idx() -@@ -1417,8 +1410,9 @@ netdev_tx_t edma_xmit(struct sk_buff *skb, +@@ -1389,8 +1382,9 @@ netdev_tx_t edma_xmit(struct sk_buff *skb, } /* this will be one of the 4 TX queues exposed to linux kernel */ - txq_id = skb_get_queue_mapping(skb); - queue_id = edma_tx_queue_get(adapter, skb, txq_id); + /* XXX what if num_online_cpus() > EDMA_CPU_CORES_SUPPORTED */ -+ txq_id = smp_processor_id() % EDMA_CPU_CORES_SUPPORTED; ++ txq_id = ((jiffies >> 5) % (EDMA_CPU_CORES_SUPPORTED - 1) + smp_processor_id() + 1) % EDMA_CPU_CORES_SUPPORTED; + queue_id = edma_tx_queue_get(edma_cinfo, adapter, skb, txq_id); etdr = edma_cinfo->tpd_ring[queue_id]; nq = netdev_get_tx_queue(net_dev, txq_id); -@@ -1899,8 +1893,8 @@ void edma_free_irqs(struct edma_adapter *adapter) +@@ -1871,8 +1865,8 @@ void edma_free_irqs(struct edma_adapter *adapter) int i, j; int k = ((edma_cinfo->num_rx_queues == 4) ? 1 : 2); @@ -73,10 +58,10 @@ index 3f1da93..05f9ce9 100644 for (j = edma_cinfo->edma_percpu_info[i].rx_start; j < (edma_cinfo->edma_percpu_info[i].rx_start + k); j++) diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.h b/drivers/net/ethernet/qualcomm/essedma/edma.h -index 29c8379..2ba43e0 100644 +index 015e5f5..abb0bd5 100644 --- a/drivers/net/ethernet/qualcomm/essedma/edma.h +++ b/drivers/net/ethernet/qualcomm/essedma/edma.h -@@ -325,6 +325,7 @@ struct edma_common_info { +@@ -324,6 +324,7 @@ struct edma_common_info { u32 from_cpu; /* from CPU TPD field */ u32 num_rxq_per_core; /* Rx queues per core */ u32 num_txq_per_core; /* Tx queues per core */ @@ -84,14 +69,14 @@ index 29c8379..2ba43e0 100644 u16 tx_ring_count; /* Tx ring count */ u16 rx_ring_count; /* Rx ring*/ u16 rx_head_buffer_len; /* rx buffer length */ -@@ -332,7 +333,7 @@ struct edma_common_info { +@@ -331,7 +332,7 @@ struct edma_common_info { u32 page_mode; /* Jumbo frame supported flag */ u32 fraglist_mode; /* fraglist supported flag */ struct edma_hw hw; /* edma hw specific structure */ - struct edma_per_cpu_queues_info edma_percpu_info[CONFIG_NR_CPUS]; /* per cpu information */ + struct edma_per_cpu_queues_info edma_percpu_info[EDMA_CPU_CORES_SUPPORTED]; /* per cpu information */ spinlock_t stats_lock; /* protect edma stats area for updation */ - + struct timer_list edma_stats_timer; bool is_single_phy; @@ -401,7 +402,7 @@ struct edma_adapter { u32 link_state; /* phy link state */ @@ -103,10 +88,10 @@ index 29c8379..2ba43e0 100644 u32 dp_bitmap; uint8_t phy_id[MII_BUS_ID_SIZE + 3]; diff --git a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c -index d9f8b52..5824680 100644 +index d53c63b..2d4770c 100644 --- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c +++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c -@@ -721,11 +721,7 @@ static int edma_axi_probe(struct platform_device *pdev) +@@ -719,11 +719,7 @@ static int edma_axi_probe(struct platform_device *pdev) int i, j, k, err = 0; int portid_bmp; int idx = 0, idx_mac = 0; @@ -119,7 +104,7 @@ index d9f8b52..5824680 100644 if ((num_rxq != 4) && (num_rxq != 8)) { dev_err(&pdev->dev, "Invalid RX queue, edma probe failed\n"); -@@ -749,7 +745,7 @@ static int edma_axi_probe(struct platform_device *pdev) +@@ -747,7 +743,7 @@ static int edma_axi_probe(struct platform_device *pdev) /* Initialize the netdev array before allocation * to avoid double free */ @@ -128,7 +113,7 @@ index d9f8b52..5824680 100644 edma_netdev[i] = NULL; for (i = 0 ; i < edma_cinfo->num_gmac ; i++) { -@@ -770,8 +766,11 @@ static int edma_axi_probe(struct platform_device *pdev) +@@ -768,8 +764,11 @@ static int edma_axi_probe(struct platform_device *pdev) /* Fill ring details */ edma_cinfo->num_tx_queues = EDMA_MAX_TRANSMIT_QUEUE; @@ -141,7 +126,7 @@ index d9f8b52..5824680 100644 /* Update num rx queues based on module parameter */ edma_cinfo->num_rx_queues = num_rxq; -@@ -941,6 +940,13 @@ static int edma_axi_probe(struct platform_device *pdev) +@@ -939,6 +938,13 @@ static int edma_axi_probe(struct platform_device *pdev) idx_mac++; } @@ -155,7 +140,7 @@ index d9f8b52..5824680 100644 /* Populate the adapter structure register the netdevice */ for (i = 0; i < edma_cinfo->num_gmac; i++) { int k, m; -@@ -948,17 +954,16 @@ static int edma_axi_probe(struct platform_device *pdev) +@@ -946,17 +952,16 @@ static int edma_axi_probe(struct platform_device *pdev) adapter[i] = netdev_priv(edma_netdev[i]); adapter[i]->netdev = edma_netdev[i]; adapter[i]->pdev = pdev; @@ -177,12 +162,12 @@ index d9f8b52..5824680 100644 if (edma_fill_netdev(edma_cinfo, k, i, j)) { pr_err("Netdev overflow Error\n"); goto err_register; -@@ -1111,9 +1116,12 @@ static int edma_axi_probe(struct platform_device *pdev) +@@ -1109,9 +1114,12 @@ static int edma_axi_probe(struct platform_device *pdev) /* populate per_core_info, do a napi_Add, request 16 TX irqs, * 8 RX irqs, do a napi enable */ - for (i = 0; i < CONFIG_NR_CPUS; i++) { -+ for (i = 0; i < num_online_cpus() && i < EDMA_MAX_TRANSMIT_QUEUE; i++) { ++ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++) { u8 rx_start; + tx_mask[i] = (0xFFFF >> (16 - edma_cinfo->num_txq_per_core)) << (i * edma_cinfo->num_txq_per_core); @@ -191,7 +176,7 @@ index d9f8b52..5824680 100644 edma_cinfo->edma_percpu_info[i].napi.state = 0; netif_napi_add(edma_netdev[0], -@@ -1138,7 +1146,7 @@ static int edma_axi_probe(struct platform_device *pdev) +@@ -1131,7 +1139,7 @@ static int edma_axi_probe(struct platform_device *pdev) /* Request irq per core */ for (j = edma_cinfo->edma_percpu_info[i].tx_start; @@ -200,16 +185,16 @@ index d9f8b52..5824680 100644 sprintf(&edma_tx_irq[j][0], "edma_eth_tx%d", j); err = request_irq(edma_cinfo->tx_irq[j], edma_interrupt, -@@ -1263,7 +1271,7 @@ err_configure: +@@ -1253,7 +1261,7 @@ static int edma_axi_probe(struct platform_device *pdev) #endif err_rmap_add_fail: edma_free_irqs(adapter[0]); - for (i = 0; i < CONFIG_NR_CPUS; i++) + for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++) - { napi_disable(&edma_cinfo->edma_percpu_info[i].napi); - del_timer_sync(&edma_cinfo->edma_percpu_info[i].rx_realloc_timer); -@@ -1314,7 +1322,7 @@ static int edma_axi_remove(struct platform_device *pdev) + err_reset: + err_unregister_sysctl_tbl: +@@ -1301,7 +1309,7 @@ static int edma_axi_remove(struct platform_device *pdev) unregister_netdev(edma_netdev[i]); edma_stop_rx_tx(hw); @@ -218,6 +203,3 @@ index d9f8b52..5824680 100644 napi_disable(&edma_cinfo->edma_percpu_info[i].napi); edma_irq_disable(edma_cinfo); --- -2.7.4 - diff --git a/target/linux/ipq40xx/patches-4.14/716-essedma-reduce-write-reg.patch b/target/linux/ipq40xx/patches-4.14/716-essedma-reduce-write-reg.patch new file mode 100644 index 0000000000..58b87467d6 --- /dev/null +++ b/target/linux/ipq40xx/patches-4.14/716-essedma-reduce-write-reg.patch @@ -0,0 +1,54 @@ +diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c +index fc274c8..e9d12a4 100644 +--- a/drivers/net/ethernet/qualcomm/essedma/edma.c ++++ b/drivers/net/ethernet/qualcomm/essedma/edma.c +@@ -2075,15 +2075,13 @@ int edma_poll(struct napi_struct *napi, int budget) + int i, work_done = 0; + u16 rx_pending_fill; + +- /* Store the Rx/Tx status by ANDing it with +- * appropriate CPU RX?TX mask ++ /* Store the Tx status by ANDing it with ++ * appropriate CPU TX mask + */ +- edma_read_reg(EDMA_REG_RX_ISR, ®_data); +- edma_percpu_info->rx_status |= reg_data & edma_percpu_info->rx_mask; +- shadow_rx_status = edma_percpu_info->rx_status; + edma_read_reg(EDMA_REG_TX_ISR, ®_data); + edma_percpu_info->tx_status |= reg_data & edma_percpu_info->tx_mask; + shadow_tx_status = edma_percpu_info->tx_status; ++ edma_write_reg(EDMA_REG_TX_ISR, shadow_tx_status); + + /* Every core will have a start, which will be computed + * in probe and stored in edma_percpu_info->tx_start variable. +@@ -2098,6 +2096,14 @@ int edma_poll(struct napi_struct *napi, int budget) + edma_percpu_info->tx_status &= ~(1 << queue_id); + } + ++ /* Store the Rx status by ANDing it with ++ * appropriate CPU RX mask ++ */ ++ edma_read_reg(EDMA_REG_RX_ISR, ®_data); ++ edma_percpu_info->rx_status |= reg_data & edma_percpu_info->rx_mask; ++ shadow_rx_status = edma_percpu_info->rx_status; ++ edma_write_reg(EDMA_REG_RX_ISR, shadow_rx_status); ++ + /* Every core will have a start, which will be computed + * in probe and stored in edma_percpu_info->tx_start variable. + * We will shift the status bit by tx_start to obtain +@@ -2122,15 +2128,6 @@ int edma_poll(struct napi_struct *napi, int budget) + } + } + +- /* Clear the status register, to avoid the interrupts to +- * reoccur.This clearing of interrupt status register is +- * done here as writing to status register only takes place +- * once the producer/consumer index has been updated to +- * reflect that the packet transmission/reception went fine. +- */ +- edma_write_reg(EDMA_REG_RX_ISR, shadow_rx_status); +- edma_write_reg(EDMA_REG_TX_ISR, shadow_tx_status); +- + /* If budget not fully consumed, exit the polling mode */ + if (likely(work_done < budget)) { + napi_complete(napi);