diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2008-08-07 13:08:58 -0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2008-08-07 13:08:58 -0300 |
commit | 797eb2f4a8d07b660ef3fbd59470d2459e2d526b (patch) | |
tree | 1d8f246612ed83abe13bb94949a364f08fb26c19 | |
parent | fc9170d2859e209fce7fd6ed86c3d0bf7b14a4c0 (diff) | |
download | tuna-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-x | tuna-cmd.py | 23 | ||||
-rwxr-xr-x | tuna/tuna.py | 78 |
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() |