[PATCH 30/36] tuna: Add --cpuset filter option to show_threads command
John Kacur <[email protected]> Fri, 10 Jul 2026 10:15:08 -0400
| Newsgroups | org.kernel.vger.linux-rt-users |
|---|---|
| Message-ID | <[email protected]> |
Add a --cpuset option to the show_threads command to filter and display only processes that belong to a specific cpuset. This makes it easy to monitor which processes are running in a particular cpuset without manually inspecting cgroup paths. The filter works by parsing the cgroup path from /proc/[pid]/cgroup and extracting the cpuset name. Processes are only displayed if they match the requested cpuset name. Usage: tuna show_threads --cpuset <name> Show processes in cpuset tuna show_threads --cpuset "" Show processes in root cgroup The option can be combined with other filters: tuna show_threads --cpuset tuna0 -t <pattern> Filter by cpuset and thread tuna show_threads --cpuset tuna0 -G Show with cgroup info tuna show_threads --cpuset tuna0 -c 0-3 Filter by cpuset and CPUs This completes the third integration feature for cpusets (Enhancement #5c), providing a convenient way to verify which processes are in a cpuset after using 'tuna move --cpuset' or 'tuna isolate --cpuset'. Assisted-by: Claude:claude-sonnet-4-5 Signed-off-by: John Kacur <[email protected]> --- tuna-cmd.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tuna-cmd.py b/tuna-cmd.py index ce34aee8e909..c2208e268c97 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -247,6 +247,7 @@ def gen_parser(): if have_inet_diag: show_threads.add_argument('-n', '--show_sockets', **MODS['show_sockets']) show_threads.add_argument('-G', '--cgroups', **MODS['cgroups']) + show_threads.add_argument('--cpuset', type=str, metavar='CPUSET-NAME', help='Show only threads in the specified cpuset') show_threads.add_argument('-z', '--spaced', **MODS['spaced']) @@ -469,7 +470,7 @@ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, def ps_show(ps, affect_children, thread_list, cpu_list, irq_list_numbers, show_uthreads, show_kthreads, - has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups, compact, match_requested, irqs): + has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups, compact, match_requested, irqs, cpuset_filter=None): ps_list = [] for pid in list(ps.keys()): @@ -502,6 +503,22 @@ def ps_show(ps, affect_children, thread_list, cpu_list, raise e if cpu_list and not set(cpu_list).intersection(set(affinity)): continue + # Filter by cpuset if requested + if cpuset_filter: + # Extract cpuset name from cgroup path + # Format: "0::/cpuset_name" or "0::/" for root + cgroup_path = ps[pid]["cgroups"] + if cgroup_path.startswith("0::"): + cgroup_path = cgroup_path[3:] # Remove "0::" prefix + # Remove leading slash to get cpuset name + if cgroup_path.startswith("/"): + cgroup_path = cgroup_path[1:] + # Get the first component (cpuset name) + # For nested cpusets like "parent/child", this gets "parent" + cpuset_name = cgroup_path.split('/')[0] if cgroup_path else "" + # Check if process is in the requested cpuset + if cpuset_name != cpuset_filter: + continue if match_requested and thread_list and pid in thread_list: ps_list.append(pid) elif not match_requested: @@ -540,7 +557,7 @@ def load_sockets(): def do_ps(thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, - affect_children, show_sockets, cgroups, compact, match_requested): + affect_children, show_sockets, cgroups, compact, match_requested, cpuset_filter=None): ps = procfs.pidstats() if affect_children: ps.reload_threads() @@ -559,7 +576,7 @@ def do_ps(thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, ps_show_header(has_ctxt_switch_info, cgroups) ps_show(ps, affect_children, thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, - has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups, compact, match_requested, irqs) + has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups, compact, match_requested, irqs, cpuset_filter) except IOError: # 'tuna -P | head' for instance pass @@ -1712,7 +1729,7 @@ def main(): if has_content: do_ps(args.thread_list, args.cpu_list, args.irq_list, args.uthreads, - args.kthreads, args.affect_children, args.show_sockets if "show_sockets" in args else None, args.cgroups, args.compact, match_requested) + args.kthreads, args.affect_children, args.show_sockets if "show_sockets" in args else None, args.cgroups, args.compact, match_requested, args.cpuset if "cpuset" in args else None) elif args.command in ['show_irqs']: # Skip display if pattern matched nothing (warning already shown) -- 2.54.0