From 7ae115f28a184052f7ca5c77ab2574ed54675bff Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Fri, 3 Jan 2025 12:39:27 -0800 Subject: [PATCH] kernfs,memcg: limit runtime of test The max_scan parameter of dump_page_cache_pages_pinning_cgroups() only allows limiting the number of matching pages which are printed. For systems or vmcores where there are (a) many pages, and (b) no matching pages, this means that all pages (or nearly all) are scanned before the function can terminate. This isn't really a problem for the corelens module: users must run it manually (not as part of any report). If it runs too long, they may interrupt it with Ctrl-C. But for CI testing, the function runs too long in some cases. So, introduce a max_scan parameter that limits the number of pages considered. The test limits the scan count to a million, which seems more than enough. The max_scan parameter is not exposed to the corelens module, but it can be at a later date if a need arises. Signed-off-by: Stephen Brennan --- drgn_tools/kernfs_memcg.py | 16 +++++++++++----- tests/test_kernfs_memcg.py | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drgn_tools/kernfs_memcg.py b/drgn_tools/kernfs_memcg.py index bbaf6ae..eca7092 100644 --- a/drgn_tools/kernfs_memcg.py +++ b/drgn_tools/kernfs_memcg.py @@ -185,15 +185,19 @@ def get_num_mem_cgroups(prog: Program) -> None: # that have memcg ref but if max_pages is specified # then we bail out after getting those many pages # or after scanning all pages , whichever happens first. -def dump_page_cache_pages_pinning_cgroups(prog: Program, max_pages: int = 0): +def dump_page_cache_pages_pinning_cgroups( + prog: Program, max_pages: int = 0, max_scan: int = 0 +): """ Dump page-cache pages that have reference to a mem-cgroup. - The ouput also contains information such as the cgroup that is pinned, its flags - (to indicate current state of cgroup) and file cached by this page. - :params: max_pages: specify how many pages to find. By default first 10000 such - pages are listed. Use 0 to list all such pages. + The ouput also contains information such as the cgroup that is pinned, its + flags (to indicate current state of cgroup) and file cached by this page. + :param max_pages: specify how many pages to find. Use 0 (the default) to + list all such pages. + :param max_scan: how many pages to scan, regardless of whether any such + pages are found. Use 0 (the default) to scan all pages. """ mem_cgroup_root = prog["cgroup_subsys"][_MEMORY_CGRP_ID].root total_count = 0 @@ -201,6 +205,8 @@ def dump_page_cache_pages_pinning_cgroups(prog: Program, max_pages: int = 0): fault_count = 0 for page in for_each_page(prog): total_count = total_count + 1 + if max_scan and total_count > max_scan: + break try: # Ignore slab pages if PageSlab(page): diff --git a/tests/test_kernfs_memcg.py b/tests/test_kernfs_memcg.py index d4924f9..013f46e 100644 --- a/tests/test_kernfs_memcg.py +++ b/tests/test_kernfs_memcg.py @@ -6,7 +6,7 @@ def test_dump_page_cache_pages_pinning_cgroups(prog: drgn.Program) -> None: - kernfs_memcg.dump_page_cache_pages_pinning_cgroups(prog, 10) + kernfs_memcg.dump_page_cache_pages_pinning_cgroups(prog, 10, 1000000) def test_dump_memcgroup_hierarchy(prog: drgn.Program) -> None: