It's still a very new addition to upstream, so hasn't been on my radar as much. But I can it to the PR as well. Hopefully it too can be merged upstream.
See my comment here:
The reporting of NSS CPU load is very basic and nothing like what's provided in the kernel stack for SoC CPU. The NSS driver just reads from current, average, max registers set by the firmware. The firmware decides when, and how often to update those metrics.
Does "firmware" mean something like nss-firmware-ipq6018, nss-firmware-ipq8074 or qca-nss-drv` ? It sounds like we need to modify the related params in firmware if we want realtime update.
nss-firmware-* = Firmware. The binary blobs (/lib/firmware/qca-nss*) that are loaded onto the NSS cores on boot.
qca-nss-drv = Driver. The thing talking to the firmware.
There's no "params" to modify. It's a read-only operation. The moment you cat /sys/kernel/debug/qca-nss-drv/stats/cpu_load_ubi, is when the driver asks the firmware for stats.
This is the entire code for it.
/*
* nss_freq_stats.c
* NSS Frequency statistics APIs.
*/
#include "nss_stats.h"
#include "nss_tx_rx_common.h"
/*
* At any point, this object has the latest data about CPU utilization.
*/
extern struct nss_freq_cpu_usage nss_freq_cpu_status;
/*
* Spinlock to protect the global data structure nss_freq_cpu_status
*/
extern spinlock_t nss_freq_cpu_usage_lock;
/*
* nss_freq_stats_read()
* Read frequency stats and display CPU information.
*/
static ssize_t nss_freq_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
/*
* max output lines = Should change in case of number of lines below.
*/
uint32_t max_output_lines = (2 + 3) + 5;
size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
size_t size_wr = 0;
ssize_t bytes_read = 0;
uint32_t avg, max, min;
char *lbuf = kzalloc(size_al, GFP_KERNEL);
if (unlikely(!lbuf)) {
nss_warning("Could not allocate memory for local statistics buffer");
return 0;
}
size_wr = scnprintf(lbuf, size_al, "CPU Utilization:\n");
spin_lock_bh(&nss_freq_cpu_usage_lock);
avg = nss_freq_cpu_status.used;
max = nss_freq_cpu_status.max;
min = nss_freq_cpu_status.min;
spin_unlock_bh(&nss_freq_cpu_usage_lock);
size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Note: Averaged over 1 second\n\n");
size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Core 0:\n");
size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Min\tAvg\tMax\n");
size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, " %u%%\t %u%%\t %u%%\n\n", min, avg, max);
bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
kfree(lbuf);
return bytes_read;
}
/*
* nss_freq_stats_ops
*/
NSS_STATS_DECLARE_FILE_OPERATIONS(freq)
/*
* nss_freq_dentry_create()
*/
void nss_freq_stats_dentry_create(void)
{
nss_stats_create_dentry("cpu_load_ubi", &nss_freq_stats_ops);
}
@qosmio Hi, is there some simple/easy way how to build that NSS repo of yours just without wifi offloading? Or maybe a way how to turn it off? Would like to know for sure if those dynamic vlans are broken bc of that or no...
For anyone curious about cpu_load_ubi, did some experimenting today. It turns out the reason people see min,max,avg being a mostly static value is due NSS frequency scaling.
➤ cat /proc/sys/dev/nss/clock/auto_scale
0
When set to 0, the NSS core is fixed to it's highest setting (1.7ghz). As a result, the cores don't CPU load usage stats.
BTW, I please DO NOT enable it. I had it disabled for performance reasons. Even Qualcomm disables frequency scaling in their mac80211 package. Simply posting my findings for those curious.
So yeah when I switched off those two configuration toggles and then moved both 207 patches from ath11k and subsys under nss folder into their default subfolders respectively the dynamic vlans works.
So it has something to do with rest of the patches thus offloading.
Too bad we can't just toggle the nss_offload on flashed device, that would probably said a lot more.
@ zxlhhyccc was asking if the output he obtained from his Redmi AX6 is valid/invalid -- he provide steps and logs which I personally think it's valid/working. (his English is quite poor, I'd say...)
if that looks the same to you, then the "list of working Model" can have "Redmi AX6" added with a "Y"
So now I found out that I have problems with VLAN filtering in general, does anyone else here also uses nss build with utilization of VLAN filtering on the bridge?
Setup:
Device: AX3600
Using VLANs on the wan (wan.# - wana: main table, wan.# - wanb: default table).
Enabled VLAN filtering with multiple vlans on the br-lan where is one trunk port and two access ports.
Firewall rule which marks packets with destination IP1.
Route rule which points marked packets to the default table.
PC1 connected to the router trough the trunk port.
PC2 connected to the router trough the access port.
Both are members of the same vlan.
Observed behavior:
When PC1 initiate connection to the IP1 packets are successfully routed trough the default routing table.
When PC2 initiate connection to the IP1 packets are routed trough the main routing table.
My best guess is maybe some race condition between vlan tagging, firewall marking/routing? Given the fact that it works when router does not have to tag the packets?