summaryrefslogtreecommitdiff
path: root/tools/lib/python
diff options
context:
space:
mode:
authorKonstantin Khorenko <khorenko@virtuozzo.com>2026-10-12 20:59:06 +0200
committerTejun Heo <tj@kernel.org>2026-10-12 11:59:58 -1000
commiteb69e955de7bdea6aa932fc4cce413ca439a4a5d (patch)
treebc99eb40b55bc17ad9819787a146f92ddc7059f3 /tools/lib/python
parent216a983640bce942e25c62e9d2f901dfba888cca (diff)
downloadlinux-next-eb69e955de7bdea6aa932fc4cce413ca439a4a5d.tar.gz
linux-next-eb69e955de7bdea6aa932fc4cce413ca439a4a5d.zip
selftests: cgroup: make test_memcg_sock check flushed sock stats
test_memcg_sock compares memory.current with the "sock " entry of memory.stat. memory.current changes at charge time, "sock " only when the memcg stats are flushed: by a memory.stat read once enough updates are pending (MEMCG_CHARGE_BATCH per online CPU), or by a periodic, deferrable worker. Nothing in the test makes sure a flush happens: - tcp_client() takes 16 readings right after connect(). If no flush lands among them, "sock " reads 0, and the test either passes on 0 == 0 without checking anything or, once memory.current shows the first charge, cannot pass any more and fails: not ok 11 test_memcg_sock - The final check waits 3 seconds for "sock " to drop to 0, counting on the deferrable worker, which can run later than that on an idle machine. Make the test cause the flushes instead of waiting for them. Every page of socket or anonymous memory that comes and goes in the cgroup counts towards the flush threshold, and MEMCG_FLUSH_BYTES (twice the vmstat error test_kmem allows for) is enough to cross it. After that much, either another flush has reset the count or the next memory.stat read flushes. - tcp_client() sets a small receive buffer before it connects. Only the server's socket is charged to the test cgroup, and with a large receive window its data moves straight on to the client; with few CPUs the client then drains it between reads and "sock " stays near 0. A small window keeps the data queued in the server's socket. - tcp_client() then keeps reading, comparing after every read, until "sock " is nonzero and matches memory.current, for up to four times MEMCG_FLUSH_BYTES. A comparison can still miss after a flush: one that came midway leaves "sock " behind, and memory.current also holds the per-CPU charge stock. The budget leaves room for several flushes. - After the server has exited, the test allocates and frees MEMCG_FLUSH_BYTES of anonymous memory in the cgroup and reads "sock ", for up to three rounds until it reads 0. The socket memory is uncharged before the first round, so any flush that has gone through all CPUs since sees "sock " at 0. A flush still running in parallel can reset the count before it reaches the CPU that did the uncharge, and the read then misses the uncharge. That flush only has to finish its walk over the CPUs for the next read to see it, and each round gives it the time of another allocation. Three rounds are a margin for a flusher that gets rescheduled midway, not a guarantee: nothing bounds how long it can be held up. MEMCG_CHARGE_BATCH goes to cgroup_util.h, and test_kmem's MAX_VMSTAT_ERROR uses it too. Assisted-by: LLM Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'tools/lib/python')
0 files changed, 0 insertions, 0 deletions