diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-06 09:52:29 -0200 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-06 09:52:29 -0200 |
commit | 2c581bf2b4dd9d6dbc6c16b06f6108f2caa2cfec (patch) | |
tree | 3077803eb38c5490a28c31edb5e55ef2dd3265ce | |
parent | 6c9e359f1bad4f455a52db7705ef515372ff9077 (diff) | |
download | tuna-2c581bf2b4dd9d6dbc6c16b06f6108f2caa2cfec.tar.gz |
cmdline: Introduce --show_irqs/-Q
To show the IRQs without thread details (pid, sched policy):
[root@emilia tuna]# tuna -q eth* -Q
# users affinity
51 eth1-rx-5 0xaf ixgbe
52 eth2-tx-4 2,4 ixgbe
59 eth1-rx-6 4,6 ixgbe
60 eth2-tx-5 0,2,6 ixgbe
67 eth1-rx-7 0,2,6 ixgbe
68 eth2-tx-6 2,6 ixgbe
75 eth1-tx-0 0,2,6 ixgbe
76 eth2-tx-7 0,2,6 ixgbe
83 eth1-tx-1 4,6 ixgbe
84 eth2:lsc 0xff
91 eth1-tx-2 0,2,6 ixgbe
92 eth0 0,2,4,6 tg3
98 eth4-tx-0 0xff igb
99 eth1-tx-3 0,2,6 ixgbe
106 eth4-rx-0 4,6 igb
107 eth1-tx-4 2,6 ixgbe
114 eth4-rx-1 2,4 igb
115 eth1-tx-5 0xaf ixgbe
122 eth4-rx-2 0xaf igb
123 eth1-tx-6 2,6 ixgbe
130 eth4-rx-3 0,2,6 igb
131 eth1-tx-7 2,4 ixgbe
138 eth4 0xff igb
139 eth1:lsc 0xff
147 eth2-rx-0 2,6 ixgbe
154 eth3-tx-0 0xff igb
155 eth2-rx-1 0,2,6 ixgbe
162 eth3-rx-0 0xae igb
163 eth2-rx-2 0xaf ixgbe
170 eth3-rx-1 0xea igb
171 eth2-rx-3 2,6 ixgbe
178 eth3-rx-2 2,4,6 igb
179 eth2-rx-4 0,2,6 ixgbe
186 eth3-rx-3 0xfe igb
187 eth2-rx-5 0xaf ixgbe
194 eth3 0xff igb
195 eth2-rx-6 2,6 ixgbe
202 eth1-rx-0 2,4 ixgbe
203 eth2-rx-7 2,4 ixgbe
210 eth1-rx-1 0,2,6 ixgbe
211 eth2-tx-0 4,6 ixgbe
218 eth1-rx-2 0,2,6 ixgbe
219 eth2-tx-1 2,4 ixgbe
226 eth1-rx-3 2,6 ixgbe
227 eth2-tx-2 0,2,6 ixgbe
234 eth1-rx-4 2,6 ixgbe
235 eth2-tx-3 2,6 ixgbe
[root@emilia tuna]#
Operations on IRQs also work well, on kernels with/without threaded IRQs:
[root@emilia tuna]# tuna -q eth3* -Q --cpu 3 --move -Q
# users affinity
154 eth3-tx-0 0xff igb
162 eth3-rx-0 0xae igb
170 eth3-rx-1 0xea igb
178 eth3-rx-2 2,4,6 igb
186 eth3-rx-3 0xfe igb
194 eth3 0xff igb
# users affinity
154 eth3-tx-0 0xff igb
162 eth3-rx-0 0xae igb
170 eth3-rx-1 0xea igb
178 eth3-rx-2 2,4,6 igb
186 eth3-rx-3 0xfe igb
194 eth3 0xff igb
[root@emilia tuna]# tuna -q eth3* -Q --cpu 3 --move -Q
# users affinity
154 eth3-tx-0 0xff igb
162 eth3-rx-0 3 igb
170 eth3-rx-1 3 igb
178 eth3-rx-2 3 igb
186 eth3-rx-3 3 igb
194 eth3 0xff igb
# users affinity
154 eth3-tx-0 0xff igb
162 eth3-rx-0 3 igb
170 eth3-rx-1 3 igb
178 eth3-rx-2 3 igb
186 eth3-rx-3 3 igb
194 eth3 0xff igb
[root@emilia tuna]#
As we can see there is the delay in updating the IRQ affinity mask in
/proc/irq/N/smp_affinity, I'll have to think about a way to generate an
interrupt after changing it, perhaps by calling some ethtool method to get
statistics just after changing the IRQ mask...
Also multi-q NICs such as the above ones probably deserve some special --spread
cmdline option so that NICs with the same number of RX and TX queues get rx-N
and tx-N on the same core for roundtrip workloads (aka benchmarks ;-)).
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rwxr-xr-x | tuna-cmd.py | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/tuna-cmd.py b/tuna-cmd.py index 068dbab..99d3aea 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -62,6 +62,7 @@ def usage(): _('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 % ('-s, --save=' + _('FILENAME'), _('Save kthreads sched tunables to %(filename)s') % \ @@ -85,6 +86,15 @@ def get_nr_cpus(): nr_cpus = procfs.cpuinfo().nr_cpus return nr_cpus +nics = None + +def get_nics(): + global nics + if nics: + return nics + nics = ethtool.get_active_devices() + return nics + def thread_help(tid): global ps if not ps: @@ -149,18 +159,20 @@ def ps_show_sockets(pid, ps, inodes, inode_re, indent = 0): s.receive_queue(), s.write_queue(), s.saddr(), s.sport(), s.daddr(), s.dport()) -def ps_show_thread(pid, affect_children, ps, cpuinfo, nics, +def format_affinity(affinity): + if len(affinity) <= 4: + return ",".join(str(a) for a in 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): global irqs try: - affinity = schedutils.get_affinity(pid) + affinity = format_affinity(schedutils.get_affinity(pid)) except SystemError: # (3, 'No such process') return - if len(affinity) <= 4: - affinity = ",".join(str(a) for a in affinity) - else: - affinity = ",".join(str(hex(a)) for a in procfs.hexbitmask(affinity, cpuinfo.nr_cpus)) sched = schedutils.schedstr(schedutils.get_scheduler(pid))[6:] rtprio = int(ps[pid]["stat"]["rt_priority"]) cmd = ps[pid]["stat"]["comm"] @@ -172,12 +184,12 @@ def ps_show_thread(pid, affect_children, ps, cpuinfo, nics, if cmd[4:] == "IRQ-": users = irqs[tuna.irq_thread_number(cmd)]["users"] for u in users: - if u in nics: + 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:] - if u in nics: + if u in get_nics(): users = ethtool.get_module(u) except: users = "Not found in /proc/interrupts!" @@ -201,11 +213,11 @@ def ps_show_thread(pid, affect_children, ps, cpuinfo, nics, if affect_children and ps[pid].has_key("threads"): for tid in ps[pid]["threads"].keys(): ps_show_thread(tid, False, ps[pid]["threads"], - cpuinfo, nics, has_ctxt_switch_info, + has_ctxt_switch_info, sock_inodes, sock_inode_re) -def ps_show(ps, affect_children, cpuinfo, thread_list, cpu_list, +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): @@ -242,10 +254,8 @@ def ps_show(ps, affect_children, cpuinfo, thread_list, cpu_list, ps_list.sort() - nics = ethtool.get_active_devices() - for pid in ps_list: - ps_show_thread(pid, affect_children, ps, cpuinfo, nics, + ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, sock_inode_re) @@ -277,17 +287,57 @@ def do_ps(thread_list, cpu_list, irq_list, show_uthreads, sock_inodes = load_sockets() sock_inode_re = re.compile(r"socket:\[(\d+)\]") - cpuinfo = procfs.cpuinfo() has_ctxt_switch_info = ps[1]["status"].has_key("voluntary_ctxt_switches") try: ps_show_header(has_ctxt_switch_info) - ps_show(ps, affect_children, cpuinfo, thread_list, + ps_show(ps, affect_children, thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, has_ctxt_switch_info, sock_inodes, sock_inode_re) except IOError: # 'tuna -P | head' for instance pass +def find_drivers_by_users(users): + nics = get_nics() + drivers = [] + for u in users: + try: + idx = u.index('-') + u = u[:idx] + except: + pass + if u in nics: + driver = ethtool.get_module(u) + if driver not in drivers: + drivers.append(driver) + + return drivers + +def show_irqs(irq_list): + global irqs + if not irqs: + irqs = procfs.interrupts() + + print "%4s %-16s %8s" % ("#", _("users"), _("affinity"),) + sorted_irqs = [] + for k in irqs.keys(): + try: + sorted_irqs.append(int(k)) + except: + pass + sorted_irqs.sort() + for irq in sorted_irqs: + if irqs[irq].has_key("affinity"): + if irq in irq_list: + affinity = format_affinity(irqs[irq]["affinity"]) + users = irqs[irq]["users"] + print "%4d %-16s %8s" % (irq, ",".join(users), affinity), + drivers = find_drivers_by_users(users) + if drivers: + print " %s" % ",".join(drivers) + else: + print + def do_list_op(op, current_list, op_list): if not current_list: current_list = [] @@ -327,6 +377,7 @@ def irq_mapper(s): irq_list.append(int(i)) except: pass + return irq_list def pick_op(argument): @@ -344,10 +395,11 @@ def i18n_init(): def main(): i18n_init() try: - short = "c:CfghiIKmp:Pq:s:S:t:UvWx" + short = "c:CfghiIKmp:PQq:s:S:t:UvWx" long = ["cpus=", "affect_children", "filter", "gui", "help", "isolate", "include", "no_kthreads", "move", - "show_sockets", "priority=", "show_threads", "irqs=", + "show_sockets", "priority=", "show_threads", + "show_irqs", "irqs=", "save=", "sockets=", "threads=", "no_uthreads", "version", "what_is", "spread"] if have_inet_diag: @@ -420,6 +472,12 @@ def main(): continue do_ps(thread_list, cpu_list, irq_list, uthreads, kthreads, affect_children, show_sockets) + 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) elif o in ("-n", "--show_sockets"): show_sockets = True elif o in ("-m", "--move", "-x", "--spread"): |