summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2008-08-07 13:08:58 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2008-08-07 13:08:58 -0300
commit797eb2f4a8d07b660ef3fbd59470d2459e2d526b (patch)
tree1d8f246612ed83abe13bb94949a364f08fb26c19
parentfc9170d2859e209fce7fd6ed86c3d0bf7b14a4c0 (diff)
downloadtuna-797eb2f4a8d07b660ef3fbd59470d2459e2d526b.tar.gz
tuna: Implement saving current kthread sched policy and rtprio as an rtctl file
It obeys --threads and --cpus filters, so its possible to: [root@doppio tuna]# ps ax | grep sirq-net- 7 ? S< 0:00 [sirq-net-tx/0] 8 ? S< 0:17 [sirq-net-rx/0] 20 ? S< 0:00 [sirq-net-tx/1] 21 ? S< 0:21 [sirq-net-rx/1] 3372 pts/1 R+ 0:00 grep sirq-net- [root@doppio tuna]# ./tuna-cmd.py --threads=7,8,20,21 --save /tmp/sirq [root@doppio tuna]# cat /tmp/sirq Generated by tuna # # Use it with rtctl: # # rtctl --file /tmp/sirq reset # # Please use 'man rtctl' for more operations # # Associate processes into named groups with default priority and # scheduling policy. # # Format is: <groupname>:<sched>:<prio>:<regex> # # groupname must start at beginning of line. # sched must be one of: 'f' (fifo) # 'b' (batch) # 'r' (round-robin) # 'o' (other) # '*' (leave alone) # regex is an awk regex # # The regex is matched against process names as printed by "ps -eo cmd". kthreads:*:1:\[.*\]$ sirq-net-rx:f:80:\[(sirq|softirq)-net-rx\/.*\]$ sirq-net-tx:f:80:\[(sirq|softirq)-net-tx\/.*\]$ [root@doppio tuna]# Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rwxr-xr-xtuna-cmd.py23
-rwxr-xr-xtuna/tuna.py78
2 files changed, 99 insertions, 2 deletions
diff --git a/tuna-cmd.py b/tuna-cmd.py
index 64a328d..7d5b296 100755
--- a/tuna-cmd.py
+++ b/tuna-cmd.py
@@ -16,6 +16,12 @@
import getopt, procfs, sys
from tuna import tuna
+try:
+ from sets import Set as set
+except:
+ # OK, we're modern, having sets as first class citizens
+ pass
+
# FIXME: ETOOMANYGLOBALS, we need a class!
nr_cpus = None
@@ -33,6 +39,7 @@ def usage():
-K, --no_kthreads Operations will not affect kernel threads
-m, --move move selected entities to CPU-LIST
-p, --priority=[POLICY]:RTPRIO set thread scheduler POLICY and RTPRIO
+ -s, --save=FILENAME save kthreads sched tunables to FILENAME
-t, --threads=THREAD-LIST THREAD-LIST affected by commands
-U, --no_uthreads Operations will not affect user threads
-W, --what_is Provides help about selected entities'''
@@ -58,15 +65,25 @@ def thread_help(tid):
help, title = tuna.kthread_help_plain_text(tid, cmdline)
print "%s\n\n%s" % (title, help)
+def save(cpus, threads, filename):
+ kthreads = tuna.get_kthread_sched_tunings()
+ for name in kthreads.keys():
+ kt = kthreads[name]
+ if (cpus and not set(kt.affinity).intersection(set(cpus))) or \
+ (threads and kt.pid not in threads) :
+ del kthreads[name]
+ tuna.generate_rtgroups(filename, kthreads)
+
def main():
try:
opts, args = getopt.getopt(sys.argv[1:],
- "c:CfghiIKmp:t:UW",
+ "c:CfghiIKmp:s:t:UW",
("cpus=", "affect_children",
"filter", "gui", "help",
"isolate", "include",
"no_kthreads",
- "move", "priority", "threads=",
+ "move", "priority",
+ "save=", "threads=",
"no_uthreads", "what_is"))
except getopt.GetoptError, err:
usage()
@@ -116,6 +133,8 @@ def main():
print "tuna: --move requires a thread list!"
sys.exit(2)
tuna.move_threads_to_cpu(cpus, threads)
+ elif o in ("-s", "--save"):
+ save(cpus, threads, a)
elif o in ("-K", "--no_kthreads"):
kthreads = False
elif o in ("-U", "--no_uthreads"):
diff --git a/tuna/tuna.py b/tuna/tuna.py
index 12a8048..f7d4885 100755
--- a/tuna/tuna.py
+++ b/tuna/tuna.py
@@ -334,3 +334,81 @@ def threads_set_priority(tids, parm, affect_children = False):
for child in [int (a) for a in os.listdir("/proc/%d/task" % tid)]:
if child != tid:
thread_set_priority(child, policy, rtprio)
+
+class sched_tunings:
+ def __init__(self, name, pid, policy, rtprio, affinity):
+ self.name = name
+ self.pid = pid
+ self.policy = policy
+ self.rtprio = int(rtprio)
+ self.affinity = affinity
+
+def get_kthread_sched_tunings(proc = None):
+ if not proc:
+ proc = procfs.pidstats()
+
+ kthreads = {}
+ for pid in proc.keys():
+ if iskthread(pid):
+ name = proc[pid]["stat"]["comm"]
+ rtprio = int(proc[pid]["stat"]["rt_priority"])
+ policy = schedutils.get_scheduler(pid)
+ affinity = schedutils.get_affinity(pid)
+ kthreads[name] = sched_tunings(name, pid, policy,
+ rtprio, affinity)
+
+ return kthreads
+
+def generate_rtgroups(filename, kthreads):
+ f = file(filename, "w")
+ f.write('''# Generated by tuna
+#
+# Use it with rtctl:
+#
+# rtctl --file %s reset
+#
+# Please use 'man rtctl' for more operations
+#
+# Associate processes into named groups with default priority and
+# scheduling policy.
+#
+# Format is: <groupname>:<sched>:<prio>:<regex>
+#
+# groupname must start at beginning of line.
+# sched must be one of: 'f' (fifo)
+# 'b' (batch)
+# 'r' (round-robin)
+# 'o' (other)
+# '*' (leave alone)
+# regex is an awk regex
+#
+# The regex is matched against process names as printed by "ps -eo cmd".
+
+''' % filename)
+ f.write("kthreads:*:1:\[.*\]$\n\n")
+
+ per_cpu_kthreads = []
+ names = kthreads.keys()
+ names.sort()
+ for name in names:
+ kt = kthreads[name]
+ try:
+ idx = name.index("/")
+ common = name[:idx]
+ if common in per_cpu_kthreads:
+ continue
+ per_cpu_kthreads.append(common)
+ name = common
+ if common[:5] == "sirq-":
+ common = "(sirq|softirq)" + common[4:]
+ elif common[:8] == "softirq-":
+ common = "(sirq|softirq)" + common[7:]
+ name = "s" + name[4:]
+ regex = common + "\/.*"
+ except:
+ regex = name
+ pass
+ f.write("%s:%c:%d:\[%s\]$\n" % (name,
+ schedutils.schedstr(kt.policy)[6].lower(),
+ kt.rtprio, regex))
+ f.close()