On Sun, Apr 13, 2025 at 10:12:48PM -0400, Waiman Long <longman@xxxxxxxxxx> wrote:
2) memory.low is set to a non-zero value but the cgroup has no task inI think you want to distinguish "no tasks" vs "no usage" in this
it so that it has an effective low value of 0. Again it may have a
non-zero low event count if memory reclaim happens. This is probably
not a result expected by the users and it is really doubtful that
users will check an empty cgroup with no task in it and expecting
some non-zero event counts.
paragraph.
--- a/mm/vmscan.cAs I think more about this -- the idea expressed by the diff makes
+++ b/mm/vmscan.c
@@ -5963,6 +5963,10 @@ static void shrink_node_memcgs(pg_data_t *pgdat, struct scan_control *sc)
mem_cgroup_calculate_protection(target_memcg, memcg);
+ /* Skip memcg with no usage */
+ if (!mem_cgroup_usage(memcg, false))
+ continue;
+
if (mem_cgroup_below_min(target_memcg, memcg)) {
sense. But is it really a change?
For non-root memcgs, they'll be skipped because 0 >= 0 (in
mem_cgroup_below_min()) and root memcg would hardly be skipped.
--- a/tools/testing/selftests/cgroup/test_memcontrol.cPlease note the subtlety in my suggestion -- I want the test with
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -380,10 +380,10 @@ static bool reclaim_until(const char *memcg, long goal);
*
* Then it checks actual memory usages and expects that:
* A/B memory.current ~= 50M
- * A/B/C memory.current ~= 29M
- * A/B/D memory.current ~= 21M
- * A/B/E memory.current ~= 0
- * A/B/F memory.current = 0
+ * A/B/C memory.current ~= 29M [memory.events:low > 0]
+ * A/B/D memory.current ~= 21M [memory.events:low > 0]
+ * A/B/E memory.current ~= 0 [memory.events:low == 0 if !memory_recursiveprot, > 0 otherwise]
memory_recursiveprot _not_ to check events count at all. Because:
a) it forces single interpretation of low events wrt effective
low limit
b) effective low limit should still be 0 in E in this testcase
(there should be no unclaimed protection of C and D).