Skip to content
Snippets Groups Projects
Commit acce25b7 authored by Felix Fietkau's avatar Felix Fietkau
Browse files

netifd: improve packet steering on ipq40xx (and possibly others)

Some platforms a single ethernet device for all ports with multiple rx rings
and NAPI threading enabled. In this case, the steering script was limiting
performance by keeping all NAPI threads assigned to the same CPU.
Fix this by assigning each rx queue and the corresponding NAPI task separately.
Additionally, if the number of rx queues is at least as big as the number of
CPUs, skip weight based assignment and distribute the load across all CPUs
directly.

Fixes: https://github.com/openwrt/openwrt/issues/17611


Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 693c1ea8
No related branches found
No related tags found
No related merge requests found
......@@ -65,8 +65,9 @@ function cpu_mask(cpu)
return sprintf("%x", mask);
}
function set_netdev_cpu(dev, cpu) {
let queues = glob(`/sys/class/net/${dev}/queues/rx-*/rps_cpus`);
function set_netdev_cpu(dev, cpu, rx_queue) {
rx_queue ??= "rx-*";
let queues = glob(`/sys/class/net/${dev}/queues/${rx_queue}/rps_cpus`);
let val = cpu_mask(cpu);
if (disable)
val = 0;
......@@ -76,7 +77,7 @@ function set_netdev_cpu(dev, cpu) {
if (!do_nothing)
writefile(queue, `${val}`);
}
queues = glob(`/sys/class/net/${dev}/queues/rx-*/rps_flow_cnt`);
queues = glob(`/sys/class/net/${dev}/queues/${rx_queue}/rps_flow_cnt`);
for (let queue in queues) {
if (debug || do_nothing)
warn(`echo ${local_flows} > ${queue}\n`);
......@@ -160,6 +161,9 @@ for (let dev in netdevs) {
netdev: [],
phy: [],
tasks: [],
rx_tasks: [],
rx_queues: map(glob(`/sys/class/net/${dev}/queues/rx-*/rps_cpus`),
(v) => basename(dirname(v))),
};
}
......@@ -187,11 +191,51 @@ for (let path in glob("/proc/*/exe")) {
continue;
push(dev.tasks, pid);
let napi_match = match(name, /napi\/([^-]*)-(\d+)/);
if (napi_match && napi_match[2] > 0)
push(dev.rx_tasks, pid);
break;
}
}
function assign_dev_queues_cpu(dev) {
let num = length(dev.rx_queues);
if (num < length(dev.rx_tasks))
num = length(dev.rx_tasks);
for (let i = 0; i < num; i++) {
let cpu;
let task = dev.rx_tasks[i];
if (num >= length(cpus))
cpu = i % length(cpus);
else if (task)
cpu = get_next_cpu(napi_weight);
else
cpu = -1;
set_task_cpu(task, cpu);
let rxq = dev.rx_queues[i];
if (!rxq)
continue;
if (num >= length(cpus))
cpu = (i + 1) % length(cpus);
else if (all_cpus)
cpu = -1;
else
cpu = get_next_cpu(napi_weight, cpu);
for (let netdev in dev.netdev)
set_netdev_cpu(netdev, cpu, rxq);
}
}
function assign_dev_cpu(dev) {
if (length(dev.rx_queues) > 1 &&
length(dev.rx_tasks) > 1)
return assign_dev_queues_cpu(dev);
if (length(dev.tasks) > 0) {
let cpu = dev.napi_cpu = get_next_cpu(napi_weight);
for (let task in dev.tasks)
......@@ -204,7 +248,6 @@ function assign_dev_cpu(dev) {
cpu = -1;
else
cpu = get_next_cpu(rx_weight, dev.napi_cpu);
dev.rx_cpu = cpu;
for (let netdev in dev.netdev)
set_netdev_cpu(netdev, cpu);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment