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 <ptpt52@gmail.com>
This commit is contained in:
AmadeusGhost 2020-02-27 10:59:55 +08:00
parent 77fc8875ed
commit 9c87378caa
6 changed files with 89 additions and 195 deletions

View File

@ -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
}

View File

@ -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<<nr)-1))`
local idx=0
for epath in /sys/class/net/eth[0-9]*; do
test -e $epath || break
echo $epath | grep -q "\." && continue
eth=`basename $epath`
idx=0
for exps in /sys/class/net/$eth/queues/rx-[0-9]*/rps_cpus; do
test -e $exps || break
cpu=`printf "%x" $((1<<((idx+1)%nr)))`
idx=$((idx+1))
echo $cpu > $exps
echo 256 > `dirname $exps`/rps_flow_cnt
done

View File

@ -1,144 +0,0 @@
From 0bcfbe3c613d6ed8044404bc1cc3c29ff961d89c Mon Sep 17 00:00:00 2001
From: Chen Minqiang <ptpt52@gmail.com>
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 <ptpt52@gmail.com>
---
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

View File

@ -115,14 +115,12 @@ Reviewed-by: Grant Grundler <grundler@chromium.org>
}
/* 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 <grundler@chromium.org>
}
/* 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 <grundler@chromium.org>
/* 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;

View File

@ -1,20 +1,5 @@
From 7be0cb35513b07bf74d93d052d57b12e2c654b43 Mon Sep 17 00:00:00 2001
From: Chen Minqiang <ptpt52@gmail.com>
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 <ptpt52@gmail.com>
---
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

View File

@ -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, &reg_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, &reg_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, &reg_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);