summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-11-06 09:52:29 -0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2009-11-06 09:52:29 -0200
commit2c581bf2b4dd9d6dbc6c16b06f6108f2caa2cfec (patch)
tree3077803eb38c5490a28c31edb5e55ef2dd3265ce
parent6c9e359f1bad4f455a52db7705ef515372ff9077 (diff)
downloadtuna-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-xtuna-cmd.py92
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"):