diff --git a/.gitignore b/.gitignore index 255d405..6f0d462 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.swp /tuna-0.11.tar.bz2 /tuna-0.11.1.tar.bz2 /tuna-0.12.tar.xz @@ -8,3 +9,4 @@ /tuna-0.16.tar.xz /tuna-0.17.tar.xz /tuna-0.18.tar.xz +/tuna-0.19.tar.xz diff --git a/sources b/sources index cd14d9b..fd3d2cc 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (tuna-0.18.tar.xz) = f05774a030f6b41a262fbe28fba2516763bddfdd1bd4ae1ed925cf3852397231af94571b857952466e87f73a33c4111afb53009faa8ed0fde12db4be1788ada7 +SHA512 (tuna-0.19.tar.xz) = 046ae4d24700916b05fcaa5c93a5beb9d09473edbad176d50ce218db52594273eaa32a9e3546ff47265973956920276e81a9476c9e32bb1fb6e0be0da1fe4f64 diff --git a/tuna-Adapt-show_threads-cgroup-output-to-terminal-si.patch b/tuna-Adapt-show_threads-cgroup-output-to-terminal-si.patch deleted file mode 100644 index 530c1c4..0000000 --- a/tuna-Adapt-show_threads-cgroup-output-to-terminal-si.patch +++ /dev/null @@ -1,148 +0,0 @@ -From b04ce6fa8b183f6a930fbff240eff44efe801f91 Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Mon, 14 Nov 2022 14:55:08 -0500 -Subject: [PATCH] tuna: Adapt show_threads cgroup output to terminal size - -Passing the --cgroup flag to the show_threads command currently displays -long cgroup strings on the thread output and decreases readability. - -Adapt the show_threads output to account for output string and terminal -size, and format output accordingly to improve readability. Add ---spaced flag to show_threads to print cgroups with spacing in -between thread outputs. - -Signed-off-by: Leah Leshchinsky - ---- -target branch: main - -Signed-off-by: John Kacur - -diff --git a/docs/tuna.8 b/docs/tuna.8 -index f50a8c2a0a16..242389455f83 100644 ---- a/docs/tuna.8 -+++ b/docs/tuna.8 -@@ -188,6 +188,7 @@ optional arguments: - Operation will affect children threads - -G, --cgroups Display the processes with the type of cgroups they - are in -+ -z, --spaced Display spaced view for cgroups - - .TP - \fBtuna show_irqs\fR -diff --git a/tuna-cmd.py b/tuna-cmd.py -index 8be35f7fb4c4..630c8bc60deb 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -114,6 +114,7 @@ def gen_parser(): - "sockets": dict(dest='cpu_list', default=[], metavar='CPU-SOCKET-LIST', type=socketstring_to_list, help="CPU-SOCKET-LIST affected by commands"), - "show_sockets": dict(action='store_true', help='Show network sockets in use by threads'), - "cgroups": dict(action='store_true', dest='cgroups', help='Display the processes with the type of cgroups they are in'), -+ "spaced": dict(action='store_false', dest='compact', help='Display spaced view for cgroups'), - "affect_children": dict(action='store_true', help="Operation will affect children threads"), - "nohz_full": dict(action='store_true', help="CPUs in nohz_full kernel command line will be affected by operations"), - "no_uthreads": dict(action='store_false', dest='uthreads', help="Operations will not affect user threads"), -@@ -215,6 +216,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('-z', '--spaced', **MODS['spaced']) - - - show_irqs_group = show_irqs.add_mutually_exclusive_group(required=False) -@@ -335,7 +337,7 @@ def format_affinity(affinity): - return ",".join(str(hex(a)) for a in procfs.hexbitmask(affinity, get_nr_cpus())) - - def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, -- sock_inode_re, cgroups): -+ sock_inode_re, cgroups, columns=None, compact=True): - global irqs - try: - affinity = format_affinity(os.sched_getaffinity(pid)) -@@ -372,10 +374,20 @@ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, - nonvoluntary_ctxt_switches) - - # Indent affected children -- print(" %-5d " % pid if affect_children else " %-5d" % pid, end=' ') -- print("%6s %5d %8s%s %15s %s" % (sched, rtprio, affinity, -- ctxt_switch_info, cmd, users), end=' ') -- print(" %9s" % cgout if cgroups else "") -+ s1 = " %-5d " % pid if affect_children else " %-5d" % pid -+ print(s1, end=' ') -+ s2 = "%6s %5d %8s%s %15s %s" % (sched, rtprio, affinity, -+ ctxt_switch_info, cmd, users) -+ print(s2, end=' ') -+ -+ if cgroups: -+ length = int(columns) - len(s1 + " ") - len(s2 + " ") -+ if len(" %9s" % cgout) <= length: -+ print("%s" % cgout) -+ else: -+ print("\n %s" % cgout + ("" if compact else "\n")) -+ else: -+ print() - - if sock_inodes: - ps_show_sockets(pid, ps, sock_inodes, sock_inode_re, -@@ -384,12 +396,12 @@ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, - for tid in list(ps[pid]["threads"].keys()): - ps_show_thread(tid, False, ps[pid]["threads"], - has_ctxt_switch_info, -- sock_inodes, sock_inode_re, cgroups) -+ sock_inodes, sock_inode_re, cgroups, columns, compact) - - - 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): -+ has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups, compact): - - ps_list = [] - for pid in list(ps.keys()): -@@ -426,9 +438,15 @@ def ps_show(ps, affect_children, thread_list, cpu_list, - - ps_list.sort() - -+ -+ # Width of terminal in columns -+ columns = None -+ if cgroups: -+ _, columns = os.popen('stty size', 'r').read().split() -+ - for pid in ps_list: - ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, -- sock_inodes, sock_inode_re, cgroups) -+ sock_inodes, sock_inode_re, cgroups, columns, compact) - - - def load_socktype(socktype, inodes): -@@ -449,7 +467,7 @@ def load_sockets(): - - - def do_ps(thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, -- affect_children, show_sockets, cgroups): -+ affect_children, show_sockets, cgroups, compact): - ps = procfs.pidstats() - if affect_children: - ps.reload_threads() -@@ -466,7 +484,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) -+ has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups, compact) - except IOError: - # 'tuna -P | head' for instance - pass -@@ -698,7 +716,7 @@ def main(): - - elif args.command in ['show_threads']: - 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.kthreads, args.affect_children, args.show_sockets if "show_sockets" in args else None, args.cgroups, args.compact) - - elif args.command in ['show_irqs']: - show_irqs(args.irq_list, args.cpu_list) --- -2.31.1 - diff --git a/tuna-Add-sockets-command-line-option.patch b/tuna-Add-sockets-command-line-option.patch deleted file mode 100644 index d6f829b..0000000 --- a/tuna-Add-sockets-command-line-option.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 87f6d9e29bab615b03b26210e3ead493fd08fe1f Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Thu, 8 Sep 2022 14:49:35 -0400 -Subject: [PATCH 3/6] tuna: Add --sockets command line option - -The getopt version of tuna implements the --sockets argument which is used -to specify a cpulist from the cpu sockets on a system. The --sockets -and --cpus arguments in the getopt version override each other, such -that 'tuna -S 0 -c 1,2' will cause a cpu_list of [1, 2]. - -In the argparse cli, add support for a --sockets argument used to specify a -cpulist and is mutually exclusive with the --cpus and --nohz_full arguments. - -Signed-off-by: Leah Leshchinsky -Signed-off-by: John Kacur - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index 554912057f03..9a3d3f32398b 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -112,7 +112,7 @@ def gen_parser(): - "threads": dict(dest='thread_list', default=[], metavar='THREAD-LIST', type=threadstring_to_list, help="THREAD-LIST affected by commands"), - "irqs": dict(dest='irq_list', default=[], metavar='IRQ-LIST', type=irqstring_to_list, help="IRQ-LIST affect by commands"), - "cpus": dict(dest='cpu_list', default=[], metavar='CPU-LIST', type=tuna.cpustring_to_list, help='CPU-LIST affected by commands'), -- "sockets": dict(default=[], nargs='+', type=int, help="CPU-SOCKET-LIST affected by commands"), -+ "sockets": dict(dest='cpu_list', default=[], metavar='CPU-SOCKET-LIST', type=socketstring_to_list, help="CPU-SOCKET-LIST affected by commands"), - "show_sockets": dict(action='store_true', help='Show network sockets in use by threads'), - "cgroups": dict(action='store_true', dest='cgroups', help='Display the processes with the type of cgroups they are in'), - "affect_children": dict(action='store_true', help="Operation will affect children threads"), -@@ -159,20 +159,24 @@ def gen_parser(): - - isolate_group = isolate.add_mutually_exclusive_group(required=True) - isolate_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ isolate_group.add_argument('-S', '--sockets', **MODS['sockets']) - isolate_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) - - include_group = include.add_mutually_exclusive_group(required=True) - include_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ include_group.add_argument('-S', '--sockets', **MODS['sockets']) - include_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) - - move_group = move.add_mutually_exclusive_group(required=True) - move_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ move_group.add_argument('-S', '--sockets', **MODS['sockets']) - move_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) - move.add_argument('-t', '--threads', **MODS['threads']) - move.add_argument('-q', '--irqs', **MODS['irqs']) - - spread_group = spread.add_mutually_exclusive_group(required=True) - spread_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ spread_group.add_argument('-S', '--sockets', **MODS['sockets']) - spread_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) - spread.add_argument('-t', '--threads', **MODS['threads']) - spread.add_argument('-q', '--irqs', **MODS['irqs']) -@@ -182,12 +186,18 @@ def gen_parser(): - priority.add_argument('-C', '--affect_children', **MODS['affect_children']) - - run.add_argument('run_command', **POS['run_command']) -- run.add_argument('-c', '--cpus', **MODS['cpus']) -+ run_group = run.add_mutually_exclusive_group(required=False) -+ run_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ run_group.add_argument('-S', '--sockets', **MODS['sockets']) -+ run_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) - run.add_argument('-p', '--priority', **MODS['priority']) - run.add_argument('-b', '--background', **MODS['background']) - - save.add_argument('filename', **POS['filename']) -- save.add_argument('-c', '--cpus', **MODS['cpus']) -+ save_group = save.add_mutually_exclusive_group(required=False) -+ save_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ save_group.add_argument('-S', '--sockets', **MODS['sockets']) -+ save_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) - save.add_argument('-t', '--threads', **MODS['threads']) - - apply.add_argument('profilename', **POS['profilename']) -@@ -195,6 +205,7 @@ def gen_parser(): - show_threads_group1 = show_threads.add_mutually_exclusive_group(required=False) - show_threads_group1.add_argument('-c', '--cpus', **MODS['cpus']) - show_threads_group1.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ show_threads_group1.add_argument('-S', '--sockets', **MODS['sockets']) - show_threads_group2 = show_threads.add_mutually_exclusive_group(required=False) - show_threads_group2.add_argument('-t', '--threads', **MODS['threads']) - show_threads_group2.add_argument('-q', '--irqs', **MODS['irqs']) -@@ -206,14 +217,21 @@ def gen_parser(): - show_threads.add_argument('-n', '--show_sockets', **MODS['show_sockets']) - show_threads.add_argument('-G', '--cgroups', **MODS['cgroups']) - -- show_irqs.add_argument('-c', '--cpus', **MODS['cpus']) -+ -+ show_irqs_group = show_irqs.add_mutually_exclusive_group(required=False) -+ show_irqs_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ show_irqs_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ show_irqs_group.add_argument('-S', '--sockets', **MODS['sockets']) - show_irqs.add_argument('-q', '--irqs', **MODS['irqs']) - - what_is.add_argument('thread_list', **POS['thread_list']) - - gui.add_argument('-d', '--disable_perf', **MODS['disable_perf']) - gui.add_argument('-R', '--refresh', **MODS['refresh']) -- gui.add_argument('-c', '--cpus', **MODS['cpus']) -+ gui_group = gui.add_mutually_exclusive_group(required=False) -+ gui_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ gui_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ gui_group.add_argument('-S', '--sockets', **MODS['sockets']) - gui.add_argument('-U', '--no_uthreads', **MODS['no_uthreads']) - gui.add_argument('-K', '--no_kthreads', **MODS['no_kthreads']) - -@@ -536,7 +554,6 @@ def irqstring_to_list(irqstr): - - irq_list = [] - irq_strings = list(set(irqstr.split(','))) -- print(irq_strings) - for s in irq_strings: - if s.isdigit(): - irq_list.append(int(s)) -@@ -546,6 +563,18 @@ def irqstring_to_list(irqstr): - irq_list += [int(i) for i in irq_list_str if i.isdigit()] - return irq_list - -+def socketstring_to_list(socketstr): -+ cpu_list = [] -+ socket_strings = list(set(socketstr.split(','))) -+ cpu_info = sysfs.cpus() -+ -+ for s in socket_strings: -+ if s not in cpu_info.sockets: -+ print("tuna: invalid socket %(socket)s sockets available: %(available)s" % -+ {"socket": s,"available": ",".join(list(cpu_info.sockets.keys()))}) -+ sys.exit(2) -+ cpu_list += [int(cpu.name[3:]) for cpu in cpu_info.sockets[s]] -+ return cpu_list - - def pick_op(argument): - if argument == "": --- -2.31.1 - diff --git a/tuna-Fix-matching-irqs-in-ps_show_thread.patch b/tuna-Fix-matching-irqs-in-ps_show_thread.patch deleted file mode 100644 index b218c88..0000000 --- a/tuna-Fix-matching-irqs-in-ps_show_thread.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 3f1fbb092f5ef07d04fef7ddec9e538f36d84450 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Fri, 2 Sep 2022 11:55:07 -0400 -Subject: [PATCH 5/6] tuna: Fix matching irqs in ps_show_thread - -To new format to match irqs is "irqs/" -We already test this when we call is_irq_thread(cmd): - -With this fix if you do - -tuna show_threads - -You will get nic information that was previously missed such as - - 986 FIFO 50 9 69286 2 irq/164-iwlwifi:default_que -ue iwlwifi:default_queue - -Signed-off-by: John Kacur - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index b13b25b8a801..80e27523acc6 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -351,17 +351,12 @@ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, - try: - if not irqs: - irqs = procfs.interrupts() -- if cmd[:4] == "IRQ-": -- users = irqs[tuna.irq_thread_number(cmd)]["users"] -- for u in users: -- if u in get_nics(): -- users[users.index(u)] = "%s(%s)" % ( -- u, ethtool.get_module(u)) -- users = ",".join(users) -- else: -- u = cmd[cmd.find('-') + 1:] -+ users = irqs[tuna.irq_thread_number(cmd)]["users"] -+ for u in users: - if u in get_nics(): -- users = ethtool.get_module(u) -+ users[users.index(u)] = "%s(%s)" % ( -+ u, ethtool.get_module(u)) -+ users = ",".join(users) - except: - users = "Not found in /proc/interrupts!" - --- -2.31.1 - diff --git a/tuna-Fix-show_threads-cgroups-run-without-a-term.patch b/tuna-Fix-show_threads-cgroups-run-without-a-term.patch deleted file mode 100644 index e8afb68..0000000 --- a/tuna-Fix-show_threads-cgroups-run-without-a-term.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 4ccef8c2996e59e7031e77d7f8e2b42b73036210 Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Wed, 23 Nov 2022 14:14:36 -0500 -Subject: [PATCH] tuna: Fix show_threads --cgroups run without a term - -When tuna show_threads --cgroups is run without a term, -provide a default column size of 80 to fix a traceback -that occurred when querying the terminal size. - -Signed-off-by: Leah Leshchinsky -- Edited the commit title -- Edited the description -Signed-off-by: John Kacur - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index 630c8bc..4e809dd 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -31,6 +31,7 @@ import procfs - from tuna import tuna, sysfs - import logging - import time -+import shutil - - def get_loglevel(level): - if level.isdigit() and int(level) in range(0,5): -@@ -440,9 +441,10 @@ def ps_show(ps, affect_children, thread_list, cpu_list, - - - # Width of terminal in columns -- columns = None -+ columns = 80 - if cgroups: -- _, columns = os.popen('stty size', 'r').read().split() -+ if os.isatty(sys.stdout.fileno()): -+ columns = shutil.get_terminal_size().columns - - for pid in ps_list: - ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, --- -2.38.1 - diff --git a/tuna-Move-get_policy_and_rtprio-call-to-parser-level.patch b/tuna-Move-get_policy_and_rtprio-call-to-parser-level.patch deleted file mode 100644 index 45c4fb6..0000000 --- a/tuna-Move-get_policy_and_rtprio-call-to-parser-level.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 9dd8c3e889fe632405561cc8476ed42659a99e2e Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Thu, 4 Aug 2022 09:39:11 -0400 -Subject: [PATCH 2/6] tuna: Move get_policy_and_rtprio call to parser level - -Due to the implementation of the parser for the priority action, -the valid policy and rtprio input can be checked at the parser level. - -Call get_policy_and_rtprio on `priority` and `run --priority` commands -at argparse level. - -Signed-off-by: Leah Leshchinsky -Signed-off-by: John Kacur - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index f49cce4d84d4..554912057f03 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -102,7 +102,7 @@ def gen_parser(): - "filename": dict(metavar='FILENAME', type=str, help="Save kthreads sched tunables to this file"), - "profilename": dict(type=str, help="Apply changes described in this file"), - "run_command": dict(metavar='COMMAND', type=str, help="fork a new process and run the \"COMMAND\""), -- "priority": dict(type=str, help="policy/priority help"), -+ "priority": dict(type=tuna.get_policy_and_rtprio, help="policy/priority help"), - } - - MODS = { -diff --git a/tuna/tuna.py b/tuna/tuna.py -index 8650f11c81c3..30a5a570c9d4 100755 ---- a/tuna/tuna.py -+++ b/tuna/tuna.py -@@ -558,11 +558,8 @@ def thread_set_priority(tid, policy, rtprio): - os.sched_setscheduler(tid, policy, param) - - def threads_set_priority(tids, parm, affect_children=False): -- try: -- (policy, rtprio) = get_policy_and_rtprio(parm) -- except ValueError: -- print("tuna: " + _("\"%s\" is an unsupported priority value!") % parm[0]) -- return -+ -+ (policy, rtprio) = parm - - for tid in tids: - try: --- -2.31.1 - diff --git a/tuna-Remove-threads-print-statement.patch b/tuna-Remove-threads-print-statement.patch deleted file mode 100644 index 297038e..0000000 --- a/tuna-Remove-threads-print-statement.patch +++ /dev/null @@ -1,24 +0,0 @@ -From b82d9037fe7f51e49a9b3c84b1ccb71fda1e1f61 Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Tue, 25 Oct 2022 16:19:25 -0400 -Subject: [PATCH 6/6] tuna: Remove threads print statement - -Remove unnecessary print statement from threadstring_to_list function - -Signed-off-by: Leah Leshchinsky - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index 80e27523acc6..c5bc65059da7 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -533,7 +533,6 @@ def threadstring_to_list(threadstr): - global ps - thread_list = [] - thread_strings = list(set(threadstr.split(','))) -- print(thread_strings) - for s in thread_strings: - if s.isdigit(): - thread_list.append(int(s)) --- -2.31.1 - diff --git a/tuna-Replace-python_ethtool-with-builtin-funtionalit.patch b/tuna-Replace-python_ethtool-with-builtin-funtionalit.patch deleted file mode 100644 index b8408f6..0000000 --- a/tuna-Replace-python_ethtool-with-builtin-funtionalit.patch +++ /dev/null @@ -1,97 +0,0 @@ -From f2a28b05264fa9557192b73a1b888756748930ac Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Tue, 27 Sep 2022 12:59:54 -0400 -Subject: [PATCH 4/6] tuna: Replace python_ethtool with builtin funtionality - -This patch replaces the dependency on python_ethtool with some -simplified functions to achieve the same result. - -Reviewed-by: Federico Pellegrin -- return 'tun' only if tun_flags exists -Signed-off-by: John Kacur - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index 9a3d3f32398b..b13b25b8a801 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -26,7 +26,7 @@ import fnmatch - import gettext - import locale - from functools import reduce --import ethtool -+import tuna.new_eth as ethtool - import tuna.tuna_sched as tuna_sched - import procfs - from tuna import tuna, sysfs -diff --git a/tuna/gui/irqview.py b/tuna/gui/irqview.py -index 35fc3fd0b0ca..5143d6dc0df5 100755 ---- a/tuna/gui/irqview.py -+++ b/tuna/gui/irqview.py -@@ -7,7 +7,7 @@ from gi.repository import Gtk - from gi.repository import GObject - import os - from functools import reduce --import ethtool -+import tuna.new_eth as ethtool - import tuna.tuna_sched as tuna_sched - - import gi -diff --git a/tuna/new_eth.py b/tuna/new_eth.py -new file mode 100755 -index 000000000000..98f9179d5695 ---- /dev/null -+++ b/tuna/new_eth.py -@@ -0,0 +1,37 @@ -+# Copyright (C) 2022 John Kacur -+""" A few functions similar to ethtool """ -+import os -+import socket -+ -+def get_active_devices(): -+ """ return a list of network devices """ -+ ret = [] -+ -+ for device in socket.if_nameindex(): -+ ret.append(device[1]) -+ -+ return ret -+ -+def get_module(intf): -+ """ return the kernel module for the given network interface """ -+ if intf == 'lo': -+ return "" -+ myp = f'/sys/class/net/{intf}/device/driver' -+ if os.path.exists(myp): -+ return os.path.basename(os.readlink(myp)) -+ if os.path.exists(f'/sys/class/net/{intf}/bridge'): -+ return 'bridge' -+ if os.path.exists(f'/sys/class/net/{intf}/tun_flags'): -+ return 'tun' -+ return "" -+ -+if __name__ == "__main__": -+ nics = get_active_devices() -+ print(f'nics = {nics}') -+ -+ for intf in nics: -+ driver = get_module(intf) -+ if driver: -+ print(f'{intf}, {driver}') -+ else: -+ print(f'{intf}') -diff --git a/tuna/tuna.py b/tuna/tuna.py -index 30a5a570c9d4..43adb84079e4 100755 ---- a/tuna/tuna.py -+++ b/tuna/tuna.py -@@ -9,7 +9,7 @@ import sys - import shlex - import fnmatch - import platform --import ethtool -+import tuna.new_eth as ethtool - import procfs - from procfs import utilist - from tuna import help --- -2.31.1 - diff --git a/tuna-Update-command-line-interface.patch b/tuna-Update-command-line-interface.patch deleted file mode 100644 index d86331e..0000000 --- a/tuna-Update-command-line-interface.patch +++ /dev/null @@ -1,733 +0,0 @@ -From eba1333c50f8a5eebb12b523c30faffac33681b3 Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Thu, 4 Aug 2022 09:39:10 -0400 -Subject: [PATCH 1/6] tuna: Update command-line interface - -The current command-line interface allows for chaining of multiple -actions, which results in ambiguous user input, a need for maintaining -variable states (thread-list, cpu-list, etc.) in the program, and a need -to type check input after parsing. The help menu can also be -overwhelming. - -Allow for the use of argparse rather than getopt to significantly -simplify the program. -Provide subcommands and clearer usage menus for the user, -introduce type checking at the parser level, and remove -ambiguity for user input. - -Signed-off-by: Leah Leshchinsky -Signed-off-by: John Kacur - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index bdaa70ffc156..f49cce4d84d4 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -14,8 +14,9 @@ - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - # General Public License for more details. - --""" tuna - Application Tuning GUI """ -+""" tuna - Application Tuning Program""" - -+import argparse - import os - import sys - import errno -@@ -37,7 +38,7 @@ def get_loglevel(level): - # logging built-in module levels: - # 0 - NOTSET - # 10 - DEBUG -- # 20 - INFO, -+ # 20 - INFO - # 30 - WARNING - # 40 - ERROR - return int(level) * 10 -@@ -85,70 +86,138 @@ except: - nr_cpus = None - ps = None - irqs = None --version = "0.18" -- -- --def usage(): -- print(_('Usage: tuna [OPTIONS]')) -- fmt = '\t%-40s %s' -- print(fmt % ('-h, --help', _('Give this help list'))) -- print(fmt % ('-a, --config_file_apply=profilename', -- _('Apply changes described in profile'))) -- print(fmt % ('-l, --config_file_list', -- _('List preloaded profiles'))) -- print(fmt % ('-g, --gui', _('Start the GUI'))) -- print(fmt % ('-G, --cgroup', -- _('Display the processes with the type of cgroups they are in'))) -- print(fmt % ('-c, --cpus=' + _('CPU-LIST'), _('%(cpulist)s affected by commands') % -- {"cpulist": _('CPU-LIST')})) -- print(fmt % ('-C, --affect_children', -- _('Operation will affect children threads'))) -- print(fmt % ('-d, --disable_perf', -- _('Explicitly disable usage of perf in GUI for process view'))) -- print(fmt % ('-D, --debug', _('Print DEBUG level logging details to console'))) -- print(fmt % ('-f, --filter', -- _('Display filter the selected entities'))) -- print(fmt % ('-i, --isolate', _('Move all allowed threads and IRQs away from %(cpulist)s') % -- {"cpulist": _('CPU-LIST')})) -- print(fmt % ('-I, --include', _('Allow all allowed threads and IRQs to run on %(cpulist)s') % -- {"cpulist": _('CPU-LIST')})) -- print(fmt % ('-K, --no_kthreads', -- _('Operations will not affect kernel threads'))) -- print(fmt % ('-L, --logging', -- _('Log application details to log file for given LOG-LEVEL'))) -- print(fmt % ('-m, --move', _('Move selected entities to %(cpulist)s') % -- {"cpulist": _('CPU-LIST')})) -- print(fmt % ('-N, --nohz_full', -- _('CPUs in nohz_full= kernel command line will be affected by operations'))) -+ -+class HelpMessageParser(argparse.ArgumentParser): -+ def error(self, message): -+ sys.stderr.write('error: %s\n' % message) -+ self.print_help() -+ sys.exit(2) -+ -+def gen_parser(): -+ -+ -+ POS = { -+ "cpu_list": dict(metavar='CPU-LIST', type=tuna.cpustring_to_list, help="CPU-LIST affected by commands"), -+ "thread_list": dict(metavar='THREAD-LIST', type=threadstring_to_list, help="THREAD-LIST affected by commands"), -+ "filename": dict(metavar='FILENAME', type=str, help="Save kthreads sched tunables to this file"), -+ "profilename": dict(type=str, help="Apply changes described in this file"), -+ "run_command": dict(metavar='COMMAND', type=str, help="fork a new process and run the \"COMMAND\""), -+ "priority": dict(type=str, help="policy/priority help"), -+ } -+ -+ MODS = { -+ "logging": dict(dest='loglevel', metavar='LOG-LEVEL', type=get_loglevel, help="Log application details to file for given LOG-LEVEL"), -+ "debug" : dict(action='store_true', dest='debug', help='Print DEBUG level logging details to console'), -+ "version": dict(action='version', version='0.18', help="show version"), -+ "threads": dict(dest='thread_list', default=[], metavar='THREAD-LIST', type=threadstring_to_list, help="THREAD-LIST affected by commands"), -+ "irqs": dict(dest='irq_list', default=[], metavar='IRQ-LIST', type=irqstring_to_list, help="IRQ-LIST affect by commands"), -+ "cpus": dict(dest='cpu_list', default=[], metavar='CPU-LIST', type=tuna.cpustring_to_list, help='CPU-LIST affected by commands'), -+ "sockets": dict(default=[], nargs='+', type=int, help="CPU-SOCKET-LIST affected by commands"), -+ "show_sockets": dict(action='store_true', help='Show network sockets in use by threads'), -+ "cgroups": dict(action='store_true', dest='cgroups', help='Display the processes with the type of cgroups they are in'), -+ "affect_children": dict(action='store_true', help="Operation will affect children threads"), -+ "nohz_full": dict(action='store_true', help="CPUs in nohz_full kernel command line will be affected by operations"), -+ "no_uthreads": dict(action='store_false', dest='uthreads', help="Operations will not affect user threads"), -+ "no_kthreads": dict(action='store_false', dest='kthreads', help="Operations will not affect kernel threads"), -+ "disable_perf": dict(action='store_true', help="Explicitly disable usage of perf in GUI for process view"), -+ "refresh": dict(default=2500, metavar='MSEC', type=int, help="Refresh the GUI every MSEC milliseconds"), -+ "priority": dict(default=(None, None), type=tuna.get_policy_and_rtprio, help="Set thread scheduler tunables: POLICY and RTPRIO"), -+ "background": dict(action='store_true', help="Run command as background task") -+ } -+ -+ parser = HelpMessageParser(description="tuna - Application Tuning Program") -+ -+ parser._positionals.title = "commands" -+ parser.add_argument('-v', '--version', **MODS['version']) -+ parser.add_argument('-L', '--logging', **MODS['logging']) -+ parser.add_argument('-D', '--debug', **MODS['debug']) -+ -+ subparser = parser.add_subparsers(dest='command') -+ -+ isolate = subparser.add_parser('isolate', description="Move all allowed threads and IRQs away from CPU-LIST", -+ help="Move all allowed threads and IRQs away from CPU-LIST") -+ include = subparser.add_parser('include', description="Allow all threads to run on CPU-LIST", -+ help="Allow all threads to run on CPU-LIST") -+ move = subparser.add_parser('move', description="Move selected entities to CPU-LIST", -+ help="Move selected entities to CPU-LIST") -+ spread = subparser.add_parser('spread', description="Move selected entities to CPU-LIST", -+ help="Spread selected entities over CPU-LIST") -+ priority = subparser.add_parser('priority', description="Set thread scheduler tunables: POLICY and RTPRIO", -+ help="Set thread scheduler tunables: POLICY and RTPRIO") -+ run = subparser.add_parser('run', description="Fork a new process and run the COMMAND", -+ help="Fork a new process and run the COMMAND") -+ save = subparser.add_parser('save', description="Save kthreads sched tunables to FILENAME", -+ help="Save kthreads sched tunables to FILENAME") -+ apply = subparser.add_parser('apply', description="Apply changes described in profile", -+ help="Apply changes described in profile") -+ show_threads = subparser.add_parser('show_threads', description='Show thread list', help='Show thread list') -+ show_irqs = subparser.add_parser('show_irqs', description='Show IRQ list', help='Show IRQ list') -+ show_configs = subparser.add_parser('show_configs', description='List preloaded profiles', help='List preloaded profiles') -+ -+ what_is = subparser.add_parser('what_is', description='Provides help about selected entities', help='Provides help about selected entities') -+ gui = subparser.add_parser('gui', description="Start the GUI", help="Start the GUI") -+ -+ isolate_group = isolate.add_mutually_exclusive_group(required=True) -+ isolate_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ isolate_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ -+ include_group = include.add_mutually_exclusive_group(required=True) -+ include_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ include_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ -+ move_group = move.add_mutually_exclusive_group(required=True) -+ move_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ move_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ move.add_argument('-t', '--threads', **MODS['threads']) -+ move.add_argument('-q', '--irqs', **MODS['irqs']) -+ -+ spread_group = spread.add_mutually_exclusive_group(required=True) -+ spread_group.add_argument('-c', '--cpus', **MODS['cpus']) -+ spread_group.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ spread.add_argument('-t', '--threads', **MODS['threads']) -+ spread.add_argument('-q', '--irqs', **MODS['irqs']) -+ -+ priority.add_argument('priority', **POS['priority']) -+ priority.add_argument('-t', '--threads', **MODS['threads'], required=True) -+ priority.add_argument('-C', '--affect_children', **MODS['affect_children']) -+ -+ run.add_argument('run_command', **POS['run_command']) -+ run.add_argument('-c', '--cpus', **MODS['cpus']) -+ run.add_argument('-p', '--priority', **MODS['priority']) -+ run.add_argument('-b', '--background', **MODS['background']) -+ -+ save.add_argument('filename', **POS['filename']) -+ save.add_argument('-c', '--cpus', **MODS['cpus']) -+ save.add_argument('-t', '--threads', **MODS['threads']) -+ -+ apply.add_argument('profilename', **POS['profilename']) -+ -+ show_threads_group1 = show_threads.add_mutually_exclusive_group(required=False) -+ show_threads_group1.add_argument('-c', '--cpus', **MODS['cpus']) -+ show_threads_group1.add_argument('-N', '--nohz_full', **MODS['nohz_full']) -+ show_threads_group2 = show_threads.add_mutually_exclusive_group(required=False) -+ show_threads_group2.add_argument('-t', '--threads', **MODS['threads']) -+ show_threads_group2.add_argument('-q', '--irqs', **MODS['irqs']) -+ show_threads.add_argument('-U', '--no_uthreads', **MODS['no_uthreads']) -+ show_threads.add_argument('-K', '--no_kthreads', **MODS['no_kthreads']) -+ show_threads.add_argument('-C', '--affect_children', **MODS['affect_children']) -+ - if have_inet_diag: -- print(fmt % ('-n, --show_sockets', -- _('Show network sockets in use by threads'))) -- print(fmt % ('-p, --priority=[' + -- _('POLICY') + ':]' + -- _('RTPRIO'), _('Set thread scheduler tunables: %(policy)s and %(rtprio)s') % -- {"policy": _('POLICY'), "rtprio": _('RTPRIO')})) -- print(fmt % ('-P, --show_threads', _('Show thread list'))) -- print(fmt % ('-Q, --show_irqs', _('Show IRQ list'))) -- print(fmt % ('-q, --irqs=' + _('IRQ-LIST'), _('%(irqlist)s affected by commands') % -- {"irqlist": _('IRQ-LIST')})) -- print(fmt % ('-r, --run=' + _('COMMAND'), _('fork a new process and run the %(command)s') % -- {"command": _('COMMAND')})) -- print(fmt % ('-R, --refresh=' + _('MSEC'), _('Refresh the GUI every MSEC milliseconds'))) -- print(fmt % ('-s, --save=' + _('FILENAME'), _('Save kthreads sched tunables to %(filename)s') % -- {"filename": _('FILENAME')})) -- print(fmt % ('-S, --sockets=' + -- _('CPU-SOCKET-LIST'), _('%(cpusocketlist)s affected by commands') % -- {"cpusocketlist": _('CPU-SOCKET-LIST')})) -- print(fmt % ('-t, --threads=' + -- _('THREAD-LIST'), _('%(threadlist)s affected by commands') % -- {"threadlist": _('THREAD-LIST')})) -- print(fmt % ('-U, --no_uthreads', -- _('Operations will not affect user threads'))) -- print(fmt % ('-v, --version', _('Show version'))) -- print(fmt % ('-W, --what_is', -- _('Provides help about selected entities'))) -- print(fmt % ('-x, --spread', _('Spread selected entities over %(cpulist)s') % -- {"cpulist": _('CPU-LIST')})) -+ show_threads.add_argument('-n', '--show_sockets', **MODS['show_sockets']) -+ show_threads.add_argument('-G', '--cgroups', **MODS['cgroups']) -+ -+ show_irqs.add_argument('-c', '--cpus', **MODS['cpus']) -+ show_irqs.add_argument('-q', '--irqs', **MODS['irqs']) -+ -+ what_is.add_argument('thread_list', **POS['thread_list']) -+ -+ gui.add_argument('-d', '--disable_perf', **MODS['disable_perf']) -+ gui.add_argument('-R', '--refresh', **MODS['refresh']) -+ gui.add_argument('-c', '--cpus', **MODS['cpus']) -+ gui.add_argument('-U', '--no_uthreads', **MODS['no_uthreads']) -+ gui.add_argument('-K', '--no_kthreads', **MODS['no_kthreads']) -+ -+ return parser - - - def get_nr_cpus(): -@@ -447,39 +516,34 @@ def do_list_op(op, current_list, op_list): - return list(set(current_list) - set(op_list)) - return list(set(op_list)) - -- --def thread_mapper(s): -+def threadstring_to_list(threadstr): - global ps -- try: -- return [int(s), ] -- except: -- pass -- -- ps = procfs.pidstats() -- -- try: -- return ps.find_by_regex(re.compile(fnmatch.translate(s))) -- except: -- return ps.find_by_name(s) -- -+ thread_list = [] -+ thread_strings = list(set(threadstr.split(','))) -+ print(thread_strings) -+ for s in thread_strings: -+ if s.isdigit(): -+ thread_list.append(int(s)) -+ else: -+ ps = procfs.pidstats() -+ try: -+ thread_list += ps.find_by_regex(re.compile(fnmatch.translate(s))) -+ except: -+ thread_list += ps.find_by_name(s) -+ return thread_list - --def irq_mapper(s): -- global irqs -- try: -- return [int(s), ] -- except: -- pass -- if not irqs: -- irqs = procfs.interrupts() -+def irqstring_to_list(irqstr): - -- irq_list_str = irqs.find_by_user_regex(re.compile(fnmatch.translate(s))) - irq_list = [] -- for i in irq_list_str: -- try: -- irq_list.append(int(i)) -- except: -- pass -- -+ irq_strings = list(set(irqstr.split(','))) -+ print(irq_strings) -+ for s in irq_strings: -+ if s.isdigit(): -+ irq_list.append(int(s)) -+ else: -+ # find_by_user_regex returns a list of strings corresponding to irq number -+ irq_list_str = procfs.interrupts().find_by_user_regex(re.compile(fnmatch.translate(s))) -+ irq_list += [int(i) for i in irq_list_str if i.isdigit()] - return irq_list - - -@@ -531,298 +595,123 @@ def list_config(): - print(value) - sys.exit(1) - -+def nohz_full_to_cpu(): -+ -+ try: -+ return tuna.nohz_full_list() -+ except: -+ print("tuna: --nohz_full " + -+ _(" needs nohz_full=cpulist on the kernel command line")) -+ sys.exit(2) - - def main(): - global ps - - i18n_init() -- try: -- short = "a:c:dDCfgGhiIKlmNp:PQq:r:R:s:S:t:UvWxL:" -- long = ["cpus=", "affect_children", "filter", "gui", "help", -- "isolate", "include", "no_kthreads", "move", "nohz_full", -- "show_sockets", "priority=", "show_threads", -- "show_irqs", "irqs=", -- "save=", "sockets=", "threads=", "no_uthreads", -- "version", "what_is", "spread", "cgroup", "config_file_apply=", -- "config_file_list", "run=", "refresh=", "disable_perf", "logging=", "debug"] -- if have_inet_diag: -- short += "n" -- long.append("show_sockets") -- opts, args = getopt.getopt(sys.argv[1:], short, long) -- except getopt.GetoptError as err: -- usage() -- print(str(err)) -- sys.exit(2) -+ parser = gen_parser() -+ # Set all necessary defaults for gui subparser if no arguments provided -+ args = parser.parse_args() if len(sys.argv) > 1 else parser.parse_args(['gui']) -+ -+ if args.debug: -+ my_logger = setup_logging("my_logger") -+ my_logger.addHandler(add_handler("DEBUG", tofile=False)) -+ my_logger.info("Debug option set") -+ -+ if args.loglevel: -+ if not args.debug: -+ my_logger = setup_logging("my_logger") -+ try: -+ my_logger.addHandler(add_handler(args.loglevel, tofile=True)) -+ my_logger.info("Logging option set at log level {}".format(args.loglevel)) - -- run_gui = not opts -- kthreads = True -- uthreads = True -- cgroups = False -- cpu_list = None -- debug = False -- irq_list = None -- irq_list_str = None -- log = False -- rtprio = None -- policy = None -- thread_list = [] -- thread_list_str = None -- filter = False -- affect_children = False -- show_sockets = False -- p_waiting_action = False -- gui_refresh = 2500 -- disable_perf = False -- -- for o, a in opts: -- if o in ("-h", "--help"): -- usage() -- return -- if o in ("-D", "--debug"): -- if debug: -- my_logger.warning("Debugging already set") -- continue -- debug = True -- if not log: -- my_logger = setup_logging("my_logger") -- my_logger.addHandler(add_handler("DEBUG", tofile=False)) -- my_logger.info("Debug option set") -- if o in ("-L", "--logging"): -- if log: -- my_logger.warning("Logging already set") -- continue -- log = True -- loglevel = get_loglevel(a) -- if not debug: -- my_logger = setup_logging("my_logger") -- try: -- my_logger.addHandler(add_handler(loglevel, tofile=True)) -- except ValueError as e: -- print(e, "tuna: --logging requires valid logging level\n") -- print("Valid log levels: NOTSET, DEBUG, INFO, WARNING, ERROR") -- print("Log levels may be specified numerically (0-4)") -- my_logger.info("Logging option set") -- if o in ("-a", "--config_file_apply"): -- apply_config(a) -- elif o in ("-l", "--config_file_list"): -- list_config() -- elif o in ("-c", "--cpus"): -- (op, a) = pick_op(a) -- try: -- op_list = tuna.cpustring_to_list(a) -- except ValueError: -- usage() -- return -- cpu_list = do_list_op(op, cpu_list, op_list) -- elif o in ("-N", "--nohz_full"): -- try: -- cpu_list = tuna.nohz_full_list() -- except: -- print("tuna: --nohz_full " + -- _(" needs nohz_full=cpulist on the kernel command line")) -- sys.exit(2) -- elif o in ("-C", "--affect_children"): -- affect_children = True -- elif o in ("-G", "--cgroup"): -- cgroups = True -- elif o in ("-t", "--threads"): -- # The -t - will reset thread list -- if a == '-': -- thread_list = [] -- thread_list_str = '' -- else: -- (op, a) = pick_op(a) -- op_list = reduce(lambda i, j: i + j, -- list(map(thread_mapper, a.split(",")))) -- op_list = list(set(op_list)) -- thread_list = do_list_op(op, thread_list, op_list) -- # Check if a process name was specified and no -- # threads was found, which would result in an empty -- # thread list, i.e. we would print all the threads -- # in the system when we should print nothing. -- if not op_list and isinstance(a, type('')): -- thread_list_str = do_list_op(op, thread_list_str, -- a.split(",")) -- if not op: -- irq_list = None -- elif o in ("-f", "--filter"): -- filter = True -- elif o in ("-g", "--gui"): -- run_gui = True -- elif o in ("-R", "--refresh"): -- run_gui = True -- (op, a) = pick_op(a) -- try: -- gui_refresh=int(a) -- except Exception as err: -- print("tuna: --refresh %s" % err) -- sys.exit(2) -- elif o in ("-d", "--disable_perf"): -- run_gui = True -- disable_perf = True -- elif o in ("-i", "--isolate"): -- if not cpu_list: -- print("tuna: --isolate " + _("requires a cpu list!")) -- sys.exit(2) -- tuna.isolate_cpus(cpu_list, get_nr_cpus()) -- elif o in ("-I", "--include"): -- if not cpu_list: -- print("tuna: --include " + _("requires a cpu list!")) -- sys.exit(2) -- tuna.include_cpus(cpu_list, get_nr_cpus()) -- elif o in ("-p", "--priority"): -- # Save policy and rtprio for future Actions (e.g. --run). -- try: -- (policy, rtprio) = tuna.get_policy_and_rtprio(a) -- except ValueError: -- print("tuna: " + _("\"%s\" is an unsupported priority value!") % a) -- sys.exit(2) -- if not thread_list: -- # For backward compatibility -- p_waiting_action = True -- else: -- try: -- tuna.threads_set_priority(thread_list, a, affect_children) -- except OSError as err: -- print("tuna: %s" % err) -- sys.exit(2) -- elif o in ("-P", "--show_threads"): -- # If the user specified process names that weren't -- # resolved to pids, don't show all threads. -- if not thread_list and not irq_list: -- if thread_list_str or irq_list_str: -- continue -- do_ps(thread_list, cpu_list, irq_list, uthreads, -- kthreads, affect_children, show_sockets, cgroups) -- elif o in ("-Q", "--show_irqs"): -- # If the user specified IRQ names that weren't -- # resolved to IRQs, don't show all IRQs. -- if not irq_list and irq_list_str: -- continue -- show_irqs(irq_list, cpu_list) -- elif o in ("-n", "--show_sockets"): -- show_sockets = True -- elif o in ("-m", "--move", "-x", "--spread"): -- spread = o in ("-x", "--spread") -- if not cpu_list: -- print("tuna: %s " % ("--spread" if spread else "--move") + _("requires a cpu list!")) -- sys.exit(2) -- if not (thread_list or irq_list): -- print("tuna: %s " % ("--spread" if spread else "--move") + _("requires a list of threads/irqs!")) -- sys.exit(2) -- -- if thread_list: -- tuna.move_threads_to_cpu(cpu_list, thread_list, spread=spread) -- -- if irq_list: -- tuna.move_irqs_to_cpu(cpu_list, irq_list, spread=spread) -- elif o in ("-s", "--save"): -- save(cpu_list, thread_list, a) -- elif o in ("-S", "--sockets"): -- (op, a) = pick_op(a) -- sockets = list(a.split(',')) -- -- if not cpu_list: -- cpu_list = [] -- -- cpu_info = sysfs.cpus() -- op_list = [] -- for socket in sockets: -- if socket not in cpu_info.sockets: -- print("tuna: %s" % -- (_("invalid socket %(socket)s sockets available: %(available)s") % -- {"socket": socket, -- "available": ",".join(list(cpu_info.sockets.keys()))})) -- sys.exit(2) -- op_list += [int(cpu.name[3:]) -- for cpu in cpu_info.sockets[socket]] -- cpu_list = do_list_op(op, cpu_list, op_list) -- elif o in ("-K", "--no_kthreads"): -- kthreads = False -- elif o in ("-q", "--irqs"): -- (op, a) = pick_op(a) -- op_list = reduce(lambda i, j: i + j, -- list(map(irq_mapper, list(set(a.split(",")))))) -- irq_list = do_list_op(op, irq_list, op_list) -- # See comment above about thread_list_str -- if not op_list and isinstance(a, type('')): -- irq_list_str = do_list_op(op, irq_list_str, a.split(",")) -- if not op: -- thread_list = [] -- if not ps: -- ps = procfs.pidstats() -- if tuna.has_threaded_irqs(ps): -- for irq in irq_list: -- irq_re = tuna.threaded_irq_re(irq) -- irq_threads = ps.find_by_regex(irq_re) -- if irq_threads: -- # Change the affinity of the thread too -- # as we can't rely on changing the irq -- # affinity changing the affinity of the -- # thread or vice versa. We need to change -- # both. -- thread_list += irq_threads -- -- elif o in ("-U", "--no_uthreads"): -- uthreads = False -- elif o in ("-v", "--version"): -- print(version) -- elif o in ("-W", "--what_is"): -- if not thread_list: -- print("tuna: --what_is " + _("requires a thread list!")) -- sys.exit(2) -- for tid in thread_list: -- thread_help(tid) -- elif o in ("-r", "--run"): -- # If -p is set, it will be consumed. So, no backward compatible -- # error handling action must be taken. -- p_waiting_action = False -- -- # pick_op() before run the command: to remove the prefix -- # + or - from command line. -- (op, a) = pick_op(a) -- -- # In order to include the new process, it must run -- # the command first, and then get the list of pids, -- tuna.run_command(a, policy, rtprio, cpu_list) -- -- op_list = reduce(lambda i, j: i + j, -- list(map(thread_mapper, a.split(",")))) -- op_list = list(set(op_list)) -- thread_list = do_list_op(op, thread_list, op_list) -- -- # Check if a process name was specified and no -- # threads was found, which would result in an empty -- # thread list, i.e. we would print all the threads -- # in the system when we should print nothing. -- if not op_list and isinstance(a, type('')): -- thread_list_str = do_list_op(op, thread_list_str, a.split(",")) -- if not op: -- irq_list = None -- -- # For backward compatibility: when -p used to be only an Action, it -- # used to exit(2) if no action was taken (i.e. if no threads_list -- # was set). -- if p_waiting_action: -- print(("tuna: -p ") + _("requires a thread list!")) -- sys.exit(2) -+ except ValueError as e: -+ print(e, "tuna: --logging requires valid logging level\n") -+ print("Valid log levels: NOTSET, DEBUG, INFO, WARNING, ERROR") -+ print("Log levels may be specified numerically (0-4)\n") -+ -+ if 'irq_list' in vars(args): -+ ps = procfs.pidstats() -+ if tuna.has_threaded_irqs(ps): -+ for irq in args.irq_list: -+ irq_re = tuna.threaded_irq_re(irq) -+ irq_threads = ps.find_by_regex(irq_re) -+ if irq_threads: -+ # Change the affinity of the thread too -+ # as we can't rely on changing the irq -+ # affinity changing the affinity of the -+ # thread or vice versa. We need to change -+ # both. -+ if 'thread_list' in vars(args): -+ args.thread_list += irq_threads -+ -+ if 'nohz_full' in vars(args) and args.nohz_full: -+ args.cpu_list = nohz_full_to_cpu() -+ -+ if args.command in ['apply', 'a']: -+ apply_config(args.profilename) -+ -+ elif args.command in ['include', 'I']: -+ tuna.include_cpus(args.cpu_list, get_nr_cpus()) -+ -+ elif args.command in ['isolate', 'i']: -+ tuna.isolate_cpus(args.cpu_list, get_nr_cpus()) -+ -+ elif args.command in ['run', 'r']: -+ -+ tuna.run_command(args.run_command, args.priority[0], args.priority[1], args.cpu_list, args.background) -+ -+ elif args.command in ['priority', 'p']: -+ -+ try: -+ tuna.threads_set_priority(args.thread_list, args.priority, args.affect_children) -+ except OSError as err: -+ print("tuna: %s" % err) -+ sys.exit(2) -+ -+ elif args.command in ['show_configs']: -+ list_config() -+ -+ elif args.command in ['show_threads']: -+ 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) -+ -+ elif args.command in ['show_irqs']: -+ show_irqs(args.irq_list, args.cpu_list) -+ -+ elif args.command in ['move', 'm', 'spread', 'x']: -+ spread = args.command in ['spread', 'x'] -+ -+ if not (args.thread_list or args.irq_list): -+ parser.error("tuna: %s " % (args.command) + _("requires a thread/irq list!\n")) -+ -+ if args.thread_list: -+ tuna.move_threads_to_cpu(args.cpu_list, args.thread_list, spread=spread) -+ -+ if args.irq_list: -+ tuna.move_irqs_to_cpu(args.cpu_list, args.irq_list, spread=spread) -+ -+ elif args.command in ['s', 'save']: -+ save(args.cpu_list, args.thread_list, args.filename) -+ -+ elif args.command in ['W', 'what_is']: -+ for tid in args.thread_list: -+ thread_help(tid) - -- if run_gui: -+ elif args.command in ['g', 'gui']: - try: - from tuna import tuna_gui - except ImportError: - # gui packages not installed - print(_('tuna: packages needed for the GUI missing.')) - print(_(' Make sure xauth, pygtk2-libglade are installed.')) -- usage() -+ parser.print_help() - return - except RuntimeError: - print("tuna: machine needs to be authorized via xhost or ssh -X?") - return - - try: -- cpus_filtered = filter if cpu_list else [] -- app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered, gui_refresh, disable_perf) -+ app = tuna_gui.main_gui(args.kthreads, args.uthreads, args.cpu_list, args.refresh, args.disable_perf) - app.run() - except KeyboardInterrupt: - pass -diff --git a/tuna/tuna.py b/tuna/tuna.py -index 31707c9cb69c..8650f11c81c3 100755 ---- a/tuna/tuna.py -+++ b/tuna/tuna.py -@@ -618,7 +618,7 @@ def get_kthread_sched_tunings(proc=None): - - return kthreads - --def run_command(cmd, policy, rtprio, cpu_list): -+def run_command(cmd, policy, rtprio, cpu_list, background): - newpid = os.fork() - if newpid == 0: - cmd_list = shlex.split(cmd) -@@ -642,7 +642,8 @@ def run_command(cmd, policy, rtprio, cpu_list): - print("tuna: %s" % err) - sys.exit(2) - else: -- os.waitpid(newpid, 0) -+ if not background: -+ os.waitpid(newpid, 0) - - def generate_rtgroups(filename, kthreads, nr_cpus): - f = open(filename, "w") --- -2.31.1 - diff --git a/tuna-Update-manpages-for-argparse-CLI-changes.patch b/tuna-Update-manpages-for-argparse-CLI-changes.patch deleted file mode 100644 index 88275aa..0000000 --- a/tuna-Update-manpages-for-argparse-CLI-changes.patch +++ /dev/null @@ -1,372 +0,0 @@ -From 0681906e75e1c8166126bbfc2f3055e7507bfcb5 Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Mon, 31 Oct 2022 13:04:28 -0400 -Subject: [PATCH 2/2] tuna: Update manpages for argparse CLI changes - -Due to the introduction of a new commandline interface, -update the tuna manpages. - -Update with new command line options. - -Signed-off-by: Leah Leshchinsky -- Slightly edited the description -- Changed "seperated" to "separated" -- Changed the "explains" to "describes" (not part of Leah's patch) -Signed-off-by: John Kacur - -diff --git a/docs/tuna.8 b/docs/tuna.8 -index 3a065562b00e..f50a8c2a0a16 100644 ---- a/docs/tuna.8 -+++ b/docs/tuna.8 -@@ -9,100 +9,261 @@ This manual page explains the \fBtuna\fR program. The program can be used to cha - .PP - \fBtuna\fP can change scheduling policy, scheduler priority and processor affinity for processes and process threads. \fBtuna\fR can also change the processor affinity for interrupts. - When \fBtuna\fR is invoked without any options it starts up in its graphical interface mode. This manual page explains only the command\-line options for \fBtuna\fR --.SH "OPTIONS" --\fBtuna\fR has both \fIaction\fR options and \fImodifier\fR options. Modifier options must be specified on the command\-line before the actions they are intended to modify. Any modifier option applies to following actions on the same command-line until it is over-ridden. --.IP \fIActions\fR -+.SH "GLOBAL OPTIONS" - .TP - \fB\-h\fR, \fB\-\-help\fR - Print a list of options. \fBtuna\fR will exit after this action, ignoring the remainder of the command-line. - .TP --\fB\-g\fR, \fB\-\-gui\fR --Start the GUI. Actions that follow this on the command-line will be processed without waiting for the GUI to complete. -+\fB\-v\fR, \fB\-\-version\fR -+Show version - .TP --\fB\-a\fR, \fB\-\-config_file_apply=profilename\fR --Apply changes described in profile -+\fB\-L\fR, \fB\-\-logging\fR=\fILOG-LEVEL\fR -+Log application details to file for given LOG-LEVEL - .TP --\fB\-l\fR, \fB\-\-config_file_list\fR --List preloaded profiles -+\fB\-D\fR, \fB\-\-debug\fR -+Print DEBUG level logging details to console -+.SH "COMMANDS" - .TP --\fB\-i\fR, \fB\-\-isolate\fR --Move all allowed threads and IRQs away from CPU\-LIST. Requires \fB\-c\fR or \fB-S\fR. -+\fBtuna isolate\fR -+usage: tuna-cmd.py isolate [-h] (-c CPU-LIST | -S CPU-SOCKET-LIST | -N) -+ -+Move all allowed threads and IRQs away from CPU\-LIST. Requires \fB\-c\fR, \fB-S\fR, or \fB-N\fR. -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations - .TP --\fB\-I\fR, \fB\-\-include\fR --Allow all allowed threads and IRQs to run on CPU\-LIST. Requires \fB\-c\fR or \fB-S\fR. -+\fBtuna include\fR -+usage: tuna-cmd.py include [-h] (-c CPU-LIST | -S CPU-SOCKET-LIST | -N) -+ -+Allow all allowed threads and IRQs to run on CPU\-LIST. Requires \fB\-c\fR, \fB-S\fR, or \fB-N\fR. -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations - .TP --\fB\-m\fR, \fB\-\-move\fR --Move selected entities to CPU\-LIST. Requires \fB\-c\fR and either \fB-t\fR or \fB-q\fR. -+\fBtuna move\fR -+usage: tuna-cmd.py move [-h] (-c CPU-LIST | -S CPU-SOCKET-LIST | -N) -+ [-t THREAD-LIST] [-q IRQ-LIST] -+ -+Move selected entities to CPU\-LIST. Requires \fB\-c\fR, \fB-S\fR, or \fB-N\fR and \fB-t\fR or \fB-q\fR. -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations -+ -t THREAD-LIST, --threads THREAD-LIST -+ THREAD-LIST affected by commands -+ -q IRQ-LIST, --irqs IRQ-LIST -+ IRQ-LIST affect by commands - .TP --\fB\-p\fR, \fB\-\-priority\fR=\fI[POLICY:]\fRRTPRIO --Set thread scheduler tunables: POLICY and RTPRIO. POLICY is one of OTHER, FIFO, RR, or BATCH. If \fB\-t\fR is not set, \fB\-p\fR will act as a Modifier saving the sched tunables for future Actions, for example \fB\-r\fR. -+\fBtuna spread\fR -+usage: tuna-cmd.py spread [-h] (-c CPU-LIST | -S CPU-SOCKET-LIST | -N) -+ [-t THREAD-LIST] [-q IRQ-LIST] -+ -+Spread selected entities over CPU-LIST. The specified threads and IRQs are each assigned to one cpu in CPU-LIST. Requires \fB\-c\fR, \fB-S\fR, or \fB-N\fR and \fB-t\fR or \fB-q\fR. -+ -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations -+ -t THREAD-LIST, --threads THREAD-LIST -+ THREAD-LIST affected by commands -+ -q IRQ-LIST, --irqs IRQ-LIST -+ IRQ-LIST affect by commands - .TP --\fB\-P\fR, \fB\-\-show_threads\fR --Show thread list. -+ -+\fBtuna priority\fR -+usage: tuna-cmd.py priority [-h] -t THREAD-LIST [-C] POLICY:RTPRIO -+ -+Set thread scheduler tunables: POLICY and RTPRIO. POLICY is one of OTHER, FIFO, RR, or BATCH. Provide POLICY, RTPRIO, or POLICY:RTPRIO separated by ":". If only POLICY is set, the RT priority will default to 1 if the policy is RT, and 0 otherwise. If only RTPRIO is specified, policy will not be changed. -+ -+positional arguments: -+ POLICY:RTPRIO Set thread scheduler tunables: POLICY and RTPRIO -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -t THREAD-LIST, --threads THREAD-LIST -+ THREAD-LIST affected by commands -+ -C, --affect_children -+ Operation will affect children threads - .TP --\fB\-Q\fR, \fB\-\-show_irqs\fR --Show IRQ list. -+\fBtuna run\fR -+usage: tuna-cmd.py run [-h] [-c CPU-LIST | -S CPU-SOCKET-LIST | -N] -+ [-p PRIORITY] [-b] -+ COMMAND -+ -+Run the COMMAND. The entire command line must be provided inside "quotes". Modifiers \fB-c\fR, \fB-S\fR and \fB-p\fR can be used to set the affinity and scheduler tunables of the given COMMAND. -+ -+positional arguments: -+ COMMAND fork a new process and run the "COMMAND" -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations -+ -p PRIORITY, --priority PRIORITY -+ Set thread scheduler tunables: POLICY and RTPRIO -+ -b, --background Run command as background task -+ - .TP --\fB\-r\fR, \fB\-\-run\fR=\fI"COMMAND"\fR --Run the COMMAND. If arguments are passed, the entire command line must be provided inside "quotes". Modifiers \fB-c\fR and \fB-p\fR can be used to set the affinity and scheduler tunables of the given COMMAND. The arg[0] (i.e. the command) will be set in THREAD\-LIST. Likewise the \fB-t\fR, the COMMAND accepts the prefix \fB+\fR and \fB-\fR as wildcards in order to be appended or removed from THREAD\-LIST, respectively. -+\fBtuna save\fR -+usage: tuna-cmd.py save [-h] [-c CPU-LIST | -S CPU-SOCKET-LIST | -N] -+ [-t THREAD-LIST] -+ FILENAME -+ -+Save kthreads sched tunables to FILENAME -+ -+positional arguments: -+ FILENAME Save kthreads sched tunables to this file -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations -+ -t THREAD-LIST, --threads THREAD-LIST -+ THREAD-LIST affected by commands - .TP --\fB\-R\fR, \fB\-\-refresh\fR=\fIMSEC\fR --Refresh the GUI every MSEC milliseconds -+\fBtuna apply\fR -+usage: tuna-cmd.py apply [-h] profilename -+ -+Apply changes described in profile -+ -+positional arguments: -+ profilename Apply changes described in this file -+ -+optional arguments: -+ -h, --help show this help message and exit -+ - .TP --\fB\-s\fR, \fB\-\-save\fR=\fIFILENAME\fR --Save kthreads sched tunables to FILENAME. -+\fBtuna show_threads\fR -+usage: tuna-cmd.py show_threads [-h] [-c CPU-LIST | -N | -S CPU-SOCKET-LIST] -+ [-t THREAD-LIST | -q IRQ-LIST] [-U] [-K] [-C] -+ [-G] -+ -+Show thread list -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -t THREAD-LIST, --threads THREAD-LIST -+ THREAD-LIST affected by commands -+ -q IRQ-LIST, --irqs IRQ-LIST -+ IRQ-LIST affect by commands -+ -U, --no_uthreads Operations will not affect user threads -+ -K, --no_kthreads Operations will not affect kernel threads -+ -C, --affect_children -+ Operation will affect children threads -+ -G, --cgroups Display the processes with the type of cgroups they -+ are in -+ - .TP --\fB\-v\fR, \fB\-\-version\fR --Show version -+\fBtuna show_irqs\fR -+usage: tuna-cmd.py show_irqs [-h] [-c CPU-LIST | -N | -S CPU-SOCKET-LIST] -+ [-q IRQ-LIST] -+ -+Show IRQ list -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -q IRQ-LIST, --irqs IRQ-LIST -+ IRQ-LIST affect by commands -+ - .TP --\fB\-W\fR, \fB\-\-what_is\fR --Provides help about selected entities. Requires \fB-t\fR. -+\fBtuna show_configs\fR -+usage: tuna-cmd.py show_configs [-h] -+ -+List preloaded profiles -+ -+optional arguments: -+ -h, --help show this help message and exit -+ - .TP --\fB\-x\fR, \fB\-\-spread\fR --Spread selected entities over CPU\-LIST. Requires at least one of \fB-t\fR or \fB-q\fR. The specified threads and IRQs are each assigned to one cpu in CPU\-LIST. -+\fB tuna what_is\fR -+usage: tuna-cmd.py what_is [-h] THREAD-LIST -+ -+Provides help about selected entities -+ -+positional arguments: -+ THREAD-LIST THREAD-LIST affected by commands -+ -+optional arguments: -+ -h, --help show this help message and exit -+.TP -+\fB tuna gui\fR -+usage: tuna-cmd.py gui [-h] [-d] [-R MSEC] -+ [-c CPU-LIST | -N | -S CPU-SOCKET-LIST] [-U] [-K] -+ -+Start the GUI -+ -+optional arguments: -+ -h, --help show this help message and exit -+ -d, --disable_perf Explicitly disable usage of perf in GUI for process -+ view -+ -R MSEC, --refresh MSEC -+ Refresh the GUI every MSEC milliseconds -+ -c CPU-LIST, --cpus CPU-LIST -+ CPU-LIST affected by commands -+ -N, --nohz_full CPUs in nohz_full kernel command line will be affected -+ by operations -+ -S CPU-SOCKET-LIST, --sockets CPU-SOCKET-LIST -+ CPU-SOCKET-LIST affected by commands -+ -U, --no_uthreads Operations will not affect user threads -+ -K, --no_kthreads Operations will not affect kernel threads - .IP \fIModifiers\fR - .TP - \fB\-c\fR, \fB\-\-cpus\fR=\fICPU\-LIST\fR --CPU\-LIST affected by commands. Requires a CPU number or a comma-separated list of CPU numbers. --.TP --\fB\-C\fR, \fB\-\-affect_children\fR --Operation will affect children threads. --.TP --\fB\-d\fR, \fB\-\-disable_perf\fR --Explicitly disable usage of perf in GUI for process view --.TP --\fB\-D\fR, \fB\-\-debug\fR --Print DEBUG level logging details to console. --.TP --\fB\-f\fR, \fB\-\-filter\fR --Disable display of selected CPUs in \fB--gui\fR. Requires \fB-c\R. --.TP --\fB\-G\fR, \fB\-\-cgroup\fR --Display the processes with the type of cgroups they are in. Requires \fB-P\R. --.TP --\fB\-K\fR, \fB\-\-no_kthreads\fR --Operations will not affect kernel threads. --.TP --\fB\-L\fR, \fB\-\-logging\fR=\fILOG\-LEVEL\fR --Log application details to log file for given LOG-LEVEL --.TP --\fB\-N\fR, \fB\-\-nohz_full\fR --CPUs in nohz_full= kernel command line parameter will be affected by operations --.TP --\fB\-q\fR, \fB\-\-irqs\fR=\fIIRQ\-LIST\fR --IRQ\-LIST affected by commands. Requires an IRQ number or a comma-separated list of IRQ numbers. -+CPU\-LIST affected by commands. Requires a CPU number, a range, or a comma-separated list of CPU numbers. - .TP - \fB\-S\fR, \fB\-\-sockets\fR=\fICPU\-SOCKET\-LIST\fR - CPU\-SOCKET\-LIST affected by commands. Requires a socket number or a comma-separated list of socket numbers. - .TP - \fB\-t\fR, \fB\-\-threads\fR=\fITHREAD\-LIST\fR --THREAD\-LIST affected by commands. Requires a thread number or thread name, or a comma-separated list of thread numbers and/or names. Thread names may contain wildcards. Be sure to quote or escape any wildcard specifications. If only \fB-\fR is passed as argument, the THREAD\-LIST will be cleared. -+THREAD\-LIST affected by commands. Requires a thread number or thread name, or a comma-separated list of thread numbers and/or names. Thread names may contain wildcards. Be sure to quote or escape any wildcard specifications. - .TP --\fB\-U\fR, \fB\-\-no_uthreads\fR --Operations will not affect user threads. - .SH USAGE EXAMPLES - If for instance the Ethernet NICs have multiple queues for both receive and transmit, each with its own IRQ, the Ethernet IRQs can be associated with a CPU socket: - .TP --.B tuna -S 2 -i -q 'eth*' -x -+.B tuna isolate -S 2 -+.TP -+.B tuna spread -q 'eth*' -S 2 - - Move everything off the CPUs in socket 2, then spread the IRQs for the Ethernet devices across those same CPUs. -diff --git a/tuna-cmd.py b/tuna-cmd.py -index 4ac01f4f4522..8be35f7fb4c4 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -101,7 +101,7 @@ def gen_parser(): - "filename": dict(metavar='FILENAME', type=str, help="Save kthreads sched tunables to this file"), - "profilename": dict(type=str, help="Apply changes described in this file"), - "run_command": dict(metavar='COMMAND', type=str, help="fork a new process and run the \"COMMAND\""), -- "priority": dict(type=tuna.get_policy_and_rtprio, help="policy/priority help"), -+ "priority": dict(type=tuna.get_policy_and_rtprio, metavar="POLICY:RTPRIO", help="Set thread scheduler tunables: POLICY and RTPRIO"), - } - - MODS = { -@@ -120,7 +120,7 @@ def gen_parser(): - "no_kthreads": dict(action='store_false', dest='kthreads', help="Operations will not affect kernel threads"), - "disable_perf": dict(action='store_true', help="Explicitly disable usage of perf in GUI for process view"), - "refresh": dict(default=2500, metavar='MSEC', type=int, help="Refresh the GUI every MSEC milliseconds"), -- "priority": dict(default=(None, None), type=tuna.get_policy_and_rtprio, help="Set thread scheduler tunables: POLICY and RTPRIO"), -+ "priority": dict(default=(None, None), metavar="POLICY:RTPRIO", type=tuna.get_policy_and_rtprio, help="Set thread scheduler tunables: POLICY and RTPRIO"), - "background": dict(action='store_true', help="Run command as background task") - } - --- -2.31.1 - diff --git a/tuna-remove-import-and-fix-help-message.patch b/tuna-remove-import-and-fix-help-message.patch deleted file mode 100644 index 0bd2812..0000000 --- a/tuna-remove-import-and-fix-help-message.patch +++ /dev/null @@ -1,33 +0,0 @@ -From bef2c2009ed5151cf7ae4bf258a908c9f577ca7d Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Wed, 2 Nov 2022 11:16:48 -0400 -Subject: [PATCH 1/2] tuna: remove import and fix help message - -Remove getopt import and fix help message for 'spread' command. - -Signed-off-by: Leah Leshchinsky - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index 44d9faaf15fb..4ac01f4f4522 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -21,7 +21,6 @@ import os - import sys - import errno - import re --import getopt - import fnmatch - import gettext - import locale -@@ -140,7 +139,7 @@ def gen_parser(): - help="Allow all threads to run on CPU-LIST") - move = subparser.add_parser('move', description="Move selected entities to CPU-LIST", - help="Move selected entities to CPU-LIST") -- spread = subparser.add_parser('spread', description="Move selected entities to CPU-LIST", -+ spread = subparser.add_parser('spread', description="Spread selected entities to CPU-LIST", - help="Spread selected entities over CPU-LIST") - priority = subparser.add_parser('priority', description="Set thread scheduler tunables: POLICY and RTPRIO", - help="Set thread scheduler tunables: POLICY and RTPRIO") --- -2.31.1 - diff --git a/tuna-tuna-cmd.py-use-fstrings.patch b/tuna-tuna-cmd.py-use-fstrings.patch deleted file mode 100644 index e9ba212..0000000 --- a/tuna-tuna-cmd.py-use-fstrings.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 1e2f6a3b64bce4ea335e97b1ab31ada3e082a6bc Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Tue, 1 Nov 2022 13:24:00 -0400 -Subject: [PATCH 2/4] tuna: tuna-cmd.py use fstrings - -Add fstrings where possible to improve readabilty - -Due to the discussion regarding dropping the language feature, gettext -shorthand _() have been removed. - -Signed-off-by: Leah Leshchinsky -Signed-off-by: John Kacur - -diff --git a/tuna-cmd.py b/tuna-cmd.py -index c5bc65059da7..44d9faaf15fb 100755 ---- a/tuna-cmd.py -+++ b/tuna-cmd.py -@@ -89,7 +89,7 @@ irqs = None - - class HelpMessageParser(argparse.ArgumentParser): - def error(self, message): -- sys.stderr.write('error: %s\n' % message) -+ sys.stderr.write(f'error: {message}\n') - self.print_help() - sys.exit(2) - -@@ -263,13 +263,16 @@ def thread_help(tid): - ps = procfs.pidstats() - - if tid not in ps: -- print("tuna: " + _("thread %d doesn't exists!") % tid) -+ print(f"tuna: thread {tid} doesn't exist!") - return - - pinfo = ps[tid] - cmdline = procfs.process_cmdline(pinfo) - help, title = tuna.kthread_help_plain_text(tid, cmdline) -- print("%s\n\n%s" % (title, _(help))) -+ print(title, "\n\n") -+ if help.isspace(): -+ help = "No help description available." -+ print(help) - - - def save(cpu_list, thread_list, filename): -@@ -295,7 +298,7 @@ def ps_show_header(has_ctxt_switch_info, cgroups=False): - - def ps_show_sockets(pid, ps, inodes, inode_re, indent=0): - header_printed = False -- dirname = "/proc/%s/fd" % pid -+ dirname = f"/proc/{pid}/fd" - try: - filenames = os.listdir(dirname) - except: # Process died -@@ -688,7 +691,7 @@ def main(): - try: - tuna.threads_set_priority(args.thread_list, args.priority, args.affect_children) - except OSError as err: -- print("tuna: %s" % err) -+ print(f"tuna: {err}") - sys.exit(2) - - elif args.command in ['show_configs']: -@@ -705,7 +708,7 @@ def main(): - spread = args.command in ['spread', 'x'] - - if not (args.thread_list or args.irq_list): -- parser.error("tuna: %s " % (args.command) + _("requires a thread/irq list!\n")) -+ parser.error(f"tuna: {args.command} requires a thread/irq list!\n") - - if args.thread_list: - tuna.move_threads_to_cpu(args.cpu_list, args.thread_list, spread=spread) --- -2.31.1 - diff --git a/tuna-tuna.py-use-fstrings.patch b/tuna-tuna.py-use-fstrings.patch deleted file mode 100644 index 02277c9..0000000 --- a/tuna-tuna.py-use-fstrings.patch +++ /dev/null @@ -1,94 +0,0 @@ -From efcc75a317b63227a8630ca17e9bcf153a6cc03e Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Mon, 31 Oct 2022 13:11:31 -0400 -Subject: [PATCH 3/4] tuna: tuna.py use fstrings - -Add fstrings where possible to improve readabilty - -Signed-off-by: Leah Leshchinsky -Signed-off-by: John Kacur - -diff --git a/tuna/tuna.py b/tuna/tuna.py -index 43adb84079e4..e527facb151c 100755 ---- a/tuna/tuna.py -+++ b/tuna/tuna.py -@@ -58,7 +58,7 @@ def iskthread(pid): - # in this function, so that they know that the thread vanished and - # can act accordingly, removing entries from tree views, etc - try: -- f = open("/proc/%d/smaps" % pid) -+ f = open(f"/proc/{pid}/smaps") - except IOError: - # Thread has vanished - return True -@@ -88,7 +88,7 @@ def is_irq_thread(cmd): - return cmd[:4] in ("IRQ-", "irq/") - - def threaded_irq_re(irq): -- return re.compile("(irq/%s-.+|IRQ-%s)" % (irq, irq)) -+ return re.compile(f"(irq/{irq}-.+|IRQ-{irq})") - - # FIXME: Move to python-linux-procfs - def has_threaded_irqs(ps): -@@ -96,10 +96,10 @@ def has_threaded_irqs(ps): - return len(ps.find_by_regex(irq_re)) > 0 - - def set_irq_affinity_filename(filename, bitmasklist): -- pathname = "/proc/irq/%s" % filename -+ pathname = f"/proc/irq/{filename}" - f = open(pathname, "w") - text = ",".join(["%x" % a for a in bitmasklist]) -- f.write("%s\n" % text) -+ f.write(f"{text}\n") - try: - f.close() - except IOError: -@@ -225,7 +225,7 @@ def move_threads_to_cpu(cpus, pid_list, set_affinity_warning=None, spread=False) - if pid not in ps: - continue - -- threads = procfs.pidstats("/proc/%d/task" % pid) -+ threads = procfs.pidstats(f"/proc/{pid}/task") - for tid in list(threads.keys()): - try: - curr_affinity = os.sched_getaffinity(tid) -@@ -320,11 +320,11 @@ def affinity_remove_cpus(affinity, cpus, nr_cpus): - # Should be moved to python_linux_procfs.interrupts, shared with interrupts.parse_affinity, etc. - def parse_irq_affinity_filename(filename, nr_cpus): - try: -- f = open("/proc/irq/%s" % filename) -+ f = open(f"/proc/irq/{filename}") - except IOError as err: - if procfs.is_s390(): - print("This operation is not supported on s390", file=sys.stderr) -- print("tuna: %s" % err, file=sys.stderr) -+ print(f"tuna: {err}", file=sys.stderr) - sys.exit(2) - - line = f.readline() -@@ -624,19 +624,19 @@ def run_command(cmd, policy, rtprio, cpu_list, background): - try: - thread_set_priority(pid, policy, rtprio) - except (SystemError, OSError) as err: -- print("tuna: %s" % err) -+ print(f"tuna: {err}") - sys.exit(2) - if cpu_list: - try: - os.sched_setaffinity(pid, cpu_list) - except (SystemError, OSError) as err: -- print("tuna: %s" % err) -+ print(f"tuna: {err}") - sys.exit(2) - - try: - os.execvp(cmd_list[0], cmd_list) - except (SystemError, OSError) as err: -- print("tuna: %s" % err) -+ print(f"tuna: {err}") - sys.exit(2) - else: - if not background: --- -2.31.1 - diff --git a/tuna-tuna_gui.py-use-fstrings.patch b/tuna-tuna_gui.py-use-fstrings.patch deleted file mode 100644 index 9e4663e..0000000 --- a/tuna-tuna_gui.py-use-fstrings.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 67c5a4dc31f7dd8a6204a1a636fcec4e8f17a86b Mon Sep 17 00:00:00 2001 -From: Leah Leshchinsky -Date: Fri, 28 Oct 2022 12:52:46 -0400 -Subject: [PATCH 1/4] tuna: tuna_gui.py use fstrings - -Add fstrings where possible to improve readabilty - -Signed-off-by: Leah Leshchinsky -Signed-off-by: John Kacur - -diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py -index f1f2caacbcba..459f90303ed5 100755 ---- a/tuna/tuna_gui.py -+++ b/tuna/tuna_gui.py -@@ -33,7 +33,7 @@ class main_gui: - if self.check_root(): - sys.exit(1) - for dir in tuna_glade_dirs: -- tuna_glade = "%s/tuna_gui.glade" % dir -+ tuna_glade = f"{dir}/tuna_gui.glade" - if os.access(tuna_glade, os.F_OK): - break - self.wtree = Gtk.Builder() --- -2.31.1 - diff --git a/tuna.spec b/tuna.spec index 7e44416..849aa69 100644 --- a/tuna.spec +++ b/tuna.spec @@ -1,6 +1,6 @@ Name: tuna -Version: 0.18 -Release: 12%{?dist} +Version: 0.19 +Release: 1%{?dist} License: GPLv2 Summary: Application tuning GUI & command line utility URL: https://git.kernel.org/pub/scm/utils/tuna/tuna.git @@ -13,19 +13,6 @@ Requires: python3-linux-procfs >= 0.6 # Requires: python-inet_diag # Patches -Patch1: tuna-Update-command-line-interface.patch -Patch2: tuna-Move-get_policy_and_rtprio-call-to-parser-level.patch -Patch3: tuna-Add-sockets-command-line-option.patch -Patch4: tuna-Replace-python_ethtool-with-builtin-funtionalit.patch -Patch5: tuna-Fix-matching-irqs-in-ps_show_thread.patch -Patch6: tuna-Remove-threads-print-statement.patch -Patch7: tuna-tuna_gui.py-use-fstrings.patch -Patch8: tuna-tuna-cmd.py-use-fstrings.patch -Patch9: tuna-tuna.py-use-fstrings.patch -Patch10: tuna-remove-import-and-fix-help-message.patch -Patch11: tuna-Update-manpages-for-argparse-CLI-changes.patch -Patch12: tuna-Adapt-show_threads-cgroup-output-to-terminal-si.patch -Patch13: tuna-Fix-show_threads-cgroups-run-without-a-term.patch %description Provides interface for changing scheduler and IRQ tunables, at whole CPU and at @@ -79,6 +66,10 @@ done %{_datadir}/polkit-1/actions/org.tuna.policy %changelog +* Thu Nov 02 2023 John Kacur - 0.19-1 +- Update to latest upstream version, tuna-0.19 +Resolves: RHEL-7862 + * Wed Nov 23 2022 Leah Leshchinsky - 0.18-12 - Fix show_threads --cgroups run without term Resolves: rhbz#2121517