summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2008-11-27 18:25:38 -0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2008-11-27 18:25:38 -0200
commitd244016828ccea2956b0befca89a9f5fb5382e89 (patch)
tree0e6b6fb4b93b12b46f80227c2dee6f67df3d967d
parent426c601013d0537079a406b6748af6b7435d42f5 (diff)
downloadtuna-d244016828ccea2956b0befca89a9f5fb5382e89.tar.gz
cmdline: Implement --irqs/-q to select IRQs by number or name
Examples: thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 182 FIFO 85 0xff 2 0 IRQ-9 acpi 7178 FIFO 85 0xff 21973 0 IRQ-2293 eth0(tg3) thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 556 FIFO 85 0xff 4 0 IRQ-1 i8042 566 FIFO 85 0xff 2 0 IRQ-8 rtc0 686 FIFO 85 0xff 50 0 IRQ-14 libata thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 686 FIFO 85 0xff 50 0 IRQ-14 libata 7178 FIFO 85 0xff 22587 0 IRQ-2293 eth0(tg3) thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 686 FIFO 85 0,2,4,6 50 0 IRQ-14 libata 7178 FIFO 85 0,2,4,6 22592 0 IRQ-2293 eth0(tg3) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rwxr-xr-xtuna-cmd.py68
-rwxr-xr-xtuna/tuna.py47
2 files changed, 97 insertions, 18 deletions
diff --git a/tuna-cmd.py b/tuna-cmd.py
index 1fdcac2..4c6a5df 100755
--- a/tuna-cmd.py
+++ b/tuna-cmd.py
@@ -3,6 +3,7 @@
# -*- coding: utf-8 -*-
# tuna - Application Tuning GUI
# Copyright (C) 2008 Red Hat Inc.
+# Arnaldo Carvalho de Melo <acme@redhat.com>
#
# This application is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -41,6 +42,7 @@ def usage():
-m, --move move selected entities to CPU-LIST
-p, --priority=[POLICY]:RTPRIO set thread scheduler POLICY and RTPRIO
-P, --show_threads show thread list
+ -q, --irqs=IRQ-LIST IRQ-LIST affected by commands
-s, --save=FILENAME save kthreads sched tunables to FILENAME
-S, --sockets=CPU-SOCKET-LIST CPU-SOCKET-LIST affected by commands
-t, --threads=THREAD-LIST THREAD-LIST affected by commands
@@ -132,9 +134,22 @@ def ps_show_thread(pid, affect_children, ps, cpuinfo, irqs, nics, has_ctxt_switc
has_ctxt_switch_info)
-def ps_show(ps, affect_children, cpuinfo, irqs, threads, cpus,
+def ps_show(ps, affect_children, cpuinfo, irqs, threads, cpus, irq_list,
show_uthreads, show_kthreads, has_ctxt_switch_info):
+ if irq_list:
+ irq_list_numbers = []
+ for i in irq_list:
+ try:
+ irq = int(i)
+ except:
+ irq = irqs.find_by_user(i)
+ if not irq:
+ continue
+ irq = int(irq)
+
+ irq_list_numbers.append(irq)
+
ps_list = []
for pid in ps.keys():
if threads and pid not in threads:
@@ -144,6 +159,15 @@ def ps_show(ps, affect_children, cpuinfo, irqs, threads, cpus,
continue
if not show_kthreads and iskth:
continue
+ if irq_list_numbers:
+ if not tuna.is_hardirq_handler(ps, pid):
+ continue
+ try:
+ irq = int(ps[pid]["stat"]["comm"][4:])
+ if irq not in irq_list_numbers:
+ continue
+ except:
+ pass
try:
affinity = schedutils.get_affinity(pid)
except SystemError: # (3, 'No such process')
@@ -159,7 +183,8 @@ def ps_show(ps, affect_children, cpuinfo, irqs, threads, cpus,
for pid in ps_list:
ps_show_thread(pid, affect_children, ps, cpuinfo, irqs, nics, has_ctxt_switch_info)
-def do_ps(threads, cpus, show_uthreads, show_kthreads, affect_children):
+def do_ps(threads, cpus, irq_list, show_uthreads,
+ show_kthreads, affect_children):
ps = procfs.pidstats()
if affect_children:
ps.reload_threads()
@@ -169,7 +194,8 @@ def do_ps(threads, cpus, show_uthreads, show_kthreads, affect_children):
try:
ps_show_header(has_ctxt_switch_info)
ps_show(ps, affect_children, cpuinfo, irqs, threads, cpus,
- show_uthreads, show_kthreads, has_ctxt_switch_info)
+ irq_list, show_uthreads, show_kthreads,
+ has_ctxt_switch_info)
except IOError:
# 'tuna -P | head' for instance
pass
@@ -177,12 +203,13 @@ def do_ps(threads, cpus, show_uthreads, show_kthreads, affect_children):
def main():
try:
opts, args = getopt.getopt(sys.argv[1:],
- "c:CfghiIKmp:Ps:S:t:UvWx",
+ "c:CfghiIKmp:Pq:s:S:t:UvWx",
("cpus=", "affect_children",
"filter", "gui", "help",
"isolate", "include",
"no_kthreads",
- "move", "priority=", "show_threads",
+ "move", "priority=",
+ "show_threads", "irqs=",
"save=", "sockets=", "threads=",
"no_uthreads", "version", "what_is",
"spread"))
@@ -195,6 +222,7 @@ def main():
kthreads = True
uthreads = True
cpus = None
+ irq_list = None
threads = None
filter = False
affect_children = False
@@ -226,15 +254,25 @@ def main():
elif o in ("-p", "--priority"):
tuna.threads_set_priority(threads, a, affect_children)
elif o in ("-P", "--show_threads"):
- do_ps(threads, cpus, uthreads, kthreads, affect_children)
- elif o in ("-m", "--move"):
+ do_ps(threads, cpus, irq_list, uthreads, kthreads,
+ affect_children)
+ elif o in ("-m", "--move", "-x", "--spread"):
if not cpus:
print "tuna: --move requires a cpu list!"
sys.exit(2)
- if not threads:
- print "tuna: --move requires a thread list!"
+ if not (threads or irq_list):
+ print "tuna: --move requires a list or threads/irqs!"
sys.exit(2)
- tuna.move_threads_to_cpu(cpus, threads)
+
+ spread = o in ("-x", "--spread")
+
+ if threads:
+ tuna.move_threads_to_cpu(cpus, threads,
+ spread = spread)
+
+ if irq_list:
+ tuna.move_irqs_to_cpu(cpus, irq_list,
+ spread = spread)
elif o in ("-s", "--save"):
save(cpus, threads, a)
elif o in ("-S", "--sockets"):
@@ -252,6 +290,8 @@ def main():
cpus.sort()
elif o in ("-K", "--no_kthreads"):
kthreads = False
+ elif o in ("-q", "--irqs"):
+ irq_list = a.split(",")
elif o in ("-U", "--no_uthreads"):
uthreads = False
elif o in ("-v", "--version"):
@@ -262,14 +302,6 @@ def main():
sys.exit(2)
for tid in threads:
thread_help(tid)
- elif o in ("-x", "--spread"):
- if not cpus:
- print "tuna: --spread requires a cpu list!"
- sys.exit(2)
- if not threads:
- print "tuna: --spread requires a thread list!"
- sys.exit(2)
- tuna.move_threads_to_cpu(cpus, threads, spread = True)
if run_gui:
try:
diff --git a/tuna/tuna.py b/tuna/tuna.py
index 5468012..0d2c8ce 100755
--- a/tuna/tuna.py
+++ b/tuna/tuna.py
@@ -216,6 +216,53 @@ def move_threads_to_cpu(cpus, pid_list, set_affinity_warning = None,
continue
return changed
+def move_irqs_to_cpu(cpus, irq_list, spread = False):
+ changed = 0
+ unprocessed = []
+
+ cpu_idx = 0
+ nr_cpus = len(cpus)
+ new_affinity = cpus
+ last_cpu = max(cpus) + 1
+ irqs = None
+ ps = procfs.pidstats()
+ for i in irq_list:
+ try:
+ irq = int(i)
+ except:
+ if not irqs:
+ irqs = procfs.interrupts()
+ irq = irqs.find_by_user(i)
+ if not irq:
+ unprocessed.append(i)
+ continue
+ try:
+ irq = int(irq)
+ except:
+ unprocessed.append(i)
+ continue
+
+ if spread:
+ new_affinity = [cpus[cpu_idx]]
+ cpu_idx += 1
+ if cpu_idx == nr_cpus:
+ cpu_idx = 0
+
+ bitmasklist = procfs.hexbitmask(new_affinity, last_cpu)
+ set_irq_affinity(irq, bitmasklist)
+ changed += 1
+ pid = ps.find_by_name("IRQ-%d" % irq)
+ if pid:
+ pid = int(pid[0])
+ try:
+ schedutils.set_affinity(pid, new_affinity)
+ except SystemError: # (3, 'No such process')
+ unprocessed.append(i)
+ changed -= 1
+ continue
+
+ return (changed, unprocessed)
+
def affinity_remove_cpus(affinity, cpus, nr_cpus):
# If the cpu being isolated was the only one in the current affinity
affinity = list(set(affinity) - set(cpus))