Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
tbblgm119
lede
提交
b93293ef
L
lede
项目概览
tbblgm119
/
lede
与 Fork 源项目一致
从无法访问的项目Fork
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
lede
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b93293ef
编写于
7月 03, 2020
作者:
C
coolsnowwolf
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ipq40xx: essedma time-balanced scheduling for nat
上级
96652f8f
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
636 addition
and
1 deletion
+636
-1
target/linux/ipq40xx/Makefile
target/linux/ipq40xx/Makefile
+3
-1
target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network
...ux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network
+7
-0
target/linux/ipq40xx/base-files/etc/init.d/adjust_network
target/linux/ipq40xx/base-files/etc/init.d/adjust_network
+19
-0
target/linux/ipq40xx/base-files/lib/adjust_network.sh
target/linux/ipq40xx/base-files/lib/adjust_network.sh
+89
-0
target/linux/ipq40xx/patches-4.19/715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch
...ssedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch
+205
-0
target/linux/ipq40xx/patches-4.19/716-essedma-reduce-write-reg.patch
...x/ipq40xx/patches-4.19/716-essedma-reduce-write-reg.patch
+54
-0
target/linux/ipq40xx/patches-5.4/715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch
...ssedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch
+205
-0
target/linux/ipq40xx/patches-5.4/716-essedma-reduce-write-reg.patch
...ux/ipq40xx/patches-5.4/716-essedma-reduce-write-reg.patch
+54
-0
未找到文件。
target/linux/ipq40xx/Makefile
浏览文件 @
b93293ef
...
...
@@ -18,6 +18,8 @@ DEFAULT_PACKAGES += \
kmod-usb-dwc3-qcom
\
kmod-leds-gpio kmod-gpio-button-hotplug swconfig
\
kmod-ath10k-ct wpad-openssl
\
kmod-usb3 kmod-usb-dwc3 ath10k-firmware-qca4019-ct ethtool
kmod-usb3 kmod-usb-dwc3 ath10k-firmware-qca4019-ct
\
automount autosamba luci-app-ipsec-vpnd luci-app-unblockmusic luci-app-cpufreq luci-app-zerotier luci-app-xlnetacc
\
htop fdisk e2fsprogs ethtool
$(eval
$(call
BuildTarget))
target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network
0 → 100644
浏览文件 @
b93293ef
#!/bin/sh
[
-f
/lib/adjust_network.sh
]
&&
{
.
/lib/adjust_network.sh
adjust_eth_queue
}
target/linux/ipq40xx/base-files/etc/init.d/adjust_network
0 → 100755
浏览文件 @
b93293ef
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org
START
=
11
STOP
=
98
adjust_smp_affinity
()
{
test
-f
/lib/adjust_network.sh
&&
{
.
/lib/adjust_network.sh
adjust_eth_queue
adjust_edma_smp_affinity
adjust_radio_smp_affinity
}
}
boot
()
{
adjust_smp_affinity
}
target/linux/ipq40xx/base-files/lib/adjust_network.sh
0 → 100644
浏览文件 @
b93293ef
#!/bin/sh
# this scripts is used for adjust cpu's choice of interrupts.
#
################################################
# Adjust smp_affinity of edma
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# Remark:
# execute only once on start-up.
################################################
adjust_edma_smp_affinity
()
{
grep
-q
edma_eth_ /proc/interrupts
||
return
0
local
nr
=
`
cat
/proc/cpuinfo |
grep
processor |
wc
-l
`
local
cpu
=
0
local
tx_irq_num
for
tx_num
in
`
seq
0 1 15
`
;
do
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
for
rx_num
in
`
seq
0 1 7
`
;
do
cpu
=
`
printf
"%x"
$((
1
<<
((
rx_num/2
)%
nr
))
)
`
rx_irq_num
=
`
grep
-m1
edma_eth_rx
$rx_num
/proc/interrupts |
cut
-d
':'
-f
1 |
tail
-n1
|
tr
-d
' '
`
[
-n
"
$rx_irq_num
"
]
&&
echo
$cpu
>
/proc/irq/
$rx_irq_num
/smp_affinity
done
}
################################################
# Adjust smp_affinity of ath10k for 2G and 5G
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# Remark:
# execute only once on start-up.
################################################
adjust_radio_smp_affinity
()
{
local
irqs
=
"
`
grep
-E
'ath10k'
/proc/interrupts |
cut
-d
':'
-f
1 |
tr
-d
' '
`
"
local
nr
=
`
cat
/proc/cpuinfo |
grep
processor |
wc
-l
`
local
idx
=
2
for
irq
in
$irqs
;
do
cpu
=
`
printf
"%x"
$((
1
<<
((
idx
)%
nr
))
)
`
echo
$cpu
>
/proc/irq/
$irq
/smp_affinity
idx
=
$((
idx+1
))
done
}
################################################
# Adjust queue of eth
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# Remark:
# Each network reboot needs to be executed.
################################################
adjust_eth_queue
()
{
local
nr
=
`
cat
/proc/cpuinfo |
grep
processor |
wc
-l
`
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
which ethtool
>
/dev/null 2>&1
&&
ethtool
-K
$eth
gro off
done
echo
1024
>
/proc/sys/net/core/rps_sock_flow_entries
}
target/linux/ipq40xx/patches-4.19/715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch
0 → 100644
浏览文件 @
b93293ef
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c
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];
bool edma_stp_rstp;
u16 edma_ath_eth_type;
-/* edma_skb_priority_offset()
- * get edma skb priority
- */
-static unsigned int edma_skb_priority_offset(struct sk_buff *skb)
-{
- return (skb->priority >> 2) & 1;
-}
-
/* edma_alloc_tx_ring()
* Allocate Tx descriptors ring
*/
@@ -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
*/
-static inline int edma_tx_queue_get(struct edma_adapter *adapter,
+static inline int edma_tx_queue_get(struct edma_common_info *edma_cinfo, struct edma_adapter *adapter,
struct sk_buff *skb, int txq_id)
{
/* skb->priority is used as an index to skb priority table
* and based on packet priority, correspong queue is assigned.
+ * 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] + (smp_processor_id() % edma_cinfo->num_txq_per_core_netdev);
}
/* edma_tx_update_hw_idx()
@@ -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 = ((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);
@@ -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);
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
- for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + 4); j++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++) {
+ for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + edma_cinfo->num_txq_per_core); j++)
free_irq(edma_cinfo->tx_irq[j], &edma_cinfo->edma_percpu_info[i]);
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 015e5f5..abb0bd5 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.h
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.h
@@ -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 */
+ u32 num_txq_per_core_netdev; /* Tx queues per core per netdev */
u16 tx_ring_count; /* Tx ring count */
u16 rx_ring_count; /* Rx ring*/
u16 rx_head_buffer_len; /* rx buffer length */
@@ -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 */
u32 phy_mdio_addr; /* PHY device address on MII interface */
u32 poll_required; /* check if link polling is required */
- u32 tx_start_offset[CONFIG_NR_CPUS]; /* tx queue start */
+ u32 tx_start_offset[EDMA_CPU_CORES_SUPPORTED]; /* tx queue start */
u32 default_vlan_tag; /* vlan tag */
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 d53c63b..2d4770c 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
@@ -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;
-
- if (CONFIG_NR_CPUS != EDMA_CPU_CORES_SUPPORTED) {
- dev_err(&pdev->dev, "Invalid CPU Cores\n");
- return -EINVAL;
- }
+ int netdev_group = 2;
if ((num_rxq != 4) && (num_rxq != 8)) {
dev_err(&pdev->dev, "Invalid RX queue, edma probe failed\n");
@@ -747,7 +743,7 @@
static int edma_axi_probe(struct platform_device *pdev)
/* Initialize the netdev array before allocation
* to avoid double free
*/
- for (i = 0 ; i < edma_cinfo->num_gmac ; i++)
+ for (i = 0 ; i < EDMA_MAX_PORTID_SUPPORTED; i++)
edma_netdev[i] = NULL;
for (i = 0 ; i < edma_cinfo->num_gmac ; i++) {
@@ -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;
- edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / 4);
+ edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / num_online_cpus());
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
edma_cinfo->tx_ring_count = EDMA_TX_RING_SIZE;
+ if (edma_cinfo->num_txq_per_core == 0)
+ edma_cinfo->num_txq_per_core = 1;
/* Update num rx queues based on module parameter */
edma_cinfo->num_rx_queues = num_rxq;
@@ -939,6 +938,13 @@
static int edma_axi_probe(struct platform_device *pdev)
idx_mac++;
}
+ if (edma_cinfo->num_gmac == 1) {
+ netdev_group = 1;
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
+ }
+ if (edma_cinfo->num_txq_per_core_netdev == 0)
+ edma_cinfo->num_txq_per_core_netdev = 1;
+
/* Populate the adapter structure register the netdevice */
for (i = 0; i < edma_cinfo->num_gmac; i++) {
int k, m;
@@ -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;
- for (j = 0; j < CONFIG_NR_CPUS; j++) {
- m = i % 2;
- adapter[i]->tx_start_offset[j] =
- ((j << EDMA_TX_CPU_START_SHIFT) + (m << 1));
+ for (j = 0; j < num_online_cpus() && j < EDMA_CPU_CORES_SUPPORTED; j++) {
+ m = i % netdev_group;
+ adapter[i]->tx_start_offset[j] = j * edma_cinfo->num_txq_per_core + m * edma_cinfo->num_txq_per_core_netdev;
/* Share the queues with available net-devices.
* For instance , with 5 net-devices
* eth0/eth2/eth4 will share q0,q1,q4,q5,q8,q9,q12,q13
* and eth1/eth3 will get the remaining.
*/
for (k = adapter[i]->tx_start_offset[j]; k <
- (adapter[i]->tx_start_offset[j] + 2); k++) {
+ (adapter[i]->tx_start_offset[j] + edma_cinfo->num_txq_per_core_netdev); k++) {
if (edma_fill_netdev(edma_cinfo, k, i, j)) {
pr_err("Netdev overflow Error\n");
goto err_register;
@@ -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_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);
+ tx_start[i] = i * edma_cinfo->num_txq_per_core;
+
edma_cinfo->edma_percpu_info[i].napi.state = 0;
netif_napi_add(edma_netdev[0],
@@ -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;
- j < tx_start[i] + 4; j++) {
+ j < tx_start[i] + edma_cinfo->num_txq_per_core; j++) {
sprintf(&edma_tx_irq[j][0], "edma_eth_tx%d", j);
err = request_irq(edma_cinfo->tx_irq[j],
edma_interrupt,
@@ -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);
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);
- 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);
edma_irq_disable(edma_cinfo);
target/linux/ipq40xx/patches-4.19/716-essedma-reduce-write-reg.patch
0 → 100644
浏览文件 @
b93293ef
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);
target/linux/ipq40xx/patches-5.4/715-essedma-refine-txq-to-be-adaptive-of-cpus-and-netdev.patch
0 → 100644
浏览文件 @
b93293ef
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c
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];
bool edma_stp_rstp;
u16 edma_ath_eth_type;
-/* edma_skb_priority_offset()
- * get edma skb priority
- */
-static unsigned int edma_skb_priority_offset(struct sk_buff *skb)
-{
- return (skb->priority >> 2) & 1;
-}
-
/* edma_alloc_tx_ring()
* Allocate Tx descriptors ring
*/
@@ -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
*/
-static inline int edma_tx_queue_get(struct edma_adapter *adapter,
+static inline int edma_tx_queue_get(struct edma_common_info *edma_cinfo, struct edma_adapter *adapter,
struct sk_buff *skb, int txq_id)
{
/* skb->priority is used as an index to skb priority table
* and based on packet priority, correspong queue is assigned.
+ * 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] + (smp_processor_id() % edma_cinfo->num_txq_per_core_netdev);
}
/* edma_tx_update_hw_idx()
@@ -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 = ((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);
@@ -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);
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
- for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + 4); j++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++) {
+ for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + edma_cinfo->num_txq_per_core); j++)
free_irq(edma_cinfo->tx_irq[j], &edma_cinfo->edma_percpu_info[i]);
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 015e5f5..abb0bd5 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.h
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.h
@@ -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 */
+ u32 num_txq_per_core_netdev; /* Tx queues per core per netdev */
u16 tx_ring_count; /* Tx ring count */
u16 rx_ring_count; /* Rx ring*/
u16 rx_head_buffer_len; /* rx buffer length */
@@ -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 */
u32 phy_mdio_addr; /* PHY device address on MII interface */
u32 poll_required; /* check if link polling is required */
- u32 tx_start_offset[CONFIG_NR_CPUS]; /* tx queue start */
+ u32 tx_start_offset[EDMA_CPU_CORES_SUPPORTED]; /* tx queue start */
u32 default_vlan_tag; /* vlan tag */
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 d53c63b..2d4770c 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
@@ -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;
-
- if (CONFIG_NR_CPUS != EDMA_CPU_CORES_SUPPORTED) {
- dev_err(&pdev->dev, "Invalid CPU Cores\n");
- return -EINVAL;
- }
+ int netdev_group = 2;
if ((num_rxq != 4) && (num_rxq != 8)) {
dev_err(&pdev->dev, "Invalid RX queue, edma probe failed\n");
@@ -747,7 +743,7 @@
static int edma_axi_probe(struct platform_device *pdev)
/* Initialize the netdev array before allocation
* to avoid double free
*/
- for (i = 0 ; i < edma_cinfo->num_gmac ; i++)
+ for (i = 0 ; i < EDMA_MAX_PORTID_SUPPORTED; i++)
edma_netdev[i] = NULL;
for (i = 0 ; i < edma_cinfo->num_gmac ; i++) {
@@ -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;
- edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / 4);
+ edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / num_online_cpus());
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
edma_cinfo->tx_ring_count = EDMA_TX_RING_SIZE;
+ if (edma_cinfo->num_txq_per_core == 0)
+ edma_cinfo->num_txq_per_core = 1;
/* Update num rx queues based on module parameter */
edma_cinfo->num_rx_queues = num_rxq;
@@ -939,6 +938,13 @@
static int edma_axi_probe(struct platform_device *pdev)
idx_mac++;
}
+ if (edma_cinfo->num_gmac == 1) {
+ netdev_group = 1;
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
+ }
+ if (edma_cinfo->num_txq_per_core_netdev == 0)
+ edma_cinfo->num_txq_per_core_netdev = 1;
+
/* Populate the adapter structure register the netdevice */
for (i = 0; i < edma_cinfo->num_gmac; i++) {
int k, m;
@@ -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;
- for (j = 0; j < CONFIG_NR_CPUS; j++) {
- m = i % 2;
- adapter[i]->tx_start_offset[j] =
- ((j << EDMA_TX_CPU_START_SHIFT) + (m << 1));
+ for (j = 0; j < num_online_cpus() && j < EDMA_CPU_CORES_SUPPORTED; j++) {
+ m = i % netdev_group;
+ adapter[i]->tx_start_offset[j] = j * edma_cinfo->num_txq_per_core + m * edma_cinfo->num_txq_per_core_netdev;
/* Share the queues with available net-devices.
* For instance , with 5 net-devices
* eth0/eth2/eth4 will share q0,q1,q4,q5,q8,q9,q12,q13
* and eth1/eth3 will get the remaining.
*/
for (k = adapter[i]->tx_start_offset[j]; k <
- (adapter[i]->tx_start_offset[j] + 2); k++) {
+ (adapter[i]->tx_start_offset[j] + edma_cinfo->num_txq_per_core_netdev); k++) {
if (edma_fill_netdev(edma_cinfo, k, i, j)) {
pr_err("Netdev overflow Error\n");
goto err_register;
@@ -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_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);
+ tx_start[i] = i * edma_cinfo->num_txq_per_core;
+
edma_cinfo->edma_percpu_info[i].napi.state = 0;
netif_napi_add(edma_netdev[0],
@@ -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;
- j < tx_start[i] + 4; j++) {
+ j < tx_start[i] + edma_cinfo->num_txq_per_core; j++) {
sprintf(&edma_tx_irq[j][0], "edma_eth_tx%d", j);
err = request_irq(edma_cinfo->tx_irq[j],
edma_interrupt,
@@ -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);
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);
- 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);
edma_irq_disable(edma_cinfo);
target/linux/ipq40xx/patches-5.4/716-essedma-reduce-write-reg.patch
0 → 100644
浏览文件 @
b93293ef
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);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录