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;
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`);
netdev: [],
phy: [],
tasks: [],
+ rx_tasks: [],
+ rx_queues: map(glob(`/sys/class/net/${dev}/queues/rx-*/rps_cpus`),
+ (v) => basename(dirname(v))),
};
}
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)
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);
}