itop更方便的了解Linux下中断情况

通过itop工具了解系统中每秒多少中断发生,发生在哪个CPU上。

Linux下中断来源可以从 /proc/interrupts 中了解到:

$ cat /proc/interrupts
           CPU0       CPU1
  0:     247701     250313   IO-APIC-edge      timer
  1:        501        567   IO-APIC-edge      i8042
  3:          1          1   IO-APIC-edge
  8:          1          0   IO-APIC-edge      rtc0
  9:        256        240   IO-APIC-fasteoi   acpi
 12:       1134       1149   IO-APIC-edge      i8042
 16:        629        554   IO-APIC-fasteoi   nvidia
 17:      21313      20869   IO-APIC-fasteoi   firewire_ohci, eth1
 18:          0          0   IO-APIC-fasteoi   mmc0
 19:      51822      50079   IO-APIC-fasteoi   ata_piix, ata_piix
 20:       5605       5255   IO-APIC-fasteoi   ehci_hcd:usb2, uhci_hcd:usb3, uhci_hcd:usb6
 21:          0          0   IO-APIC-fasteoi   uhci_hcd:usb4, uhci_hcd:usb7
 22:         33         33   IO-APIC-fasteoi   ehci_hcd:usb1, uhci_hcd:usb5, uhci_hcd:usb8
 45:        337        247   PCI-MSI-edge      eth0
 46:        441        447   PCI-MSI-edge      hda_intel
NMI:          0          0   Non-maskable interrupts
LOC:     169176     174899   Local timer interrupts
SPU:          0          0   Spurious interrupts
PMI:          0          0   Performance monitoring interrupts
PND:          0          0   Performance pending work
RES:      42289      40236   Rescheduling interrupts
CAL:        154       1076   Function call interrupts
TLB:       5838       5365   TLB shootdowns
TRM:          0          0   Thermal event interrupts
THR:          0          0   Threshold APIC interrupts
MCE:          0          0   Machine check exceptions
MCP:          5          5   Machine check polls
ERR:          1
MIS:          0

软中断可以从/proc/softirqs 了解到:

$ cat /proc/softirqs
                CPU0       CPU1
      HI:          0          0
   TIMER:     160508    1170976
  NET_TX:          2          2
  NET_RX:       3303       3165
   BLOCK:      50964      49198
BLOCK_IOPOLL:          0          0
 TASKLET:      24743      24284
   SCHED:      39483      41848
 HRTIMER:         34         40
     RCU:      92193      92592

总的中断次数可以从vmstat或者dstat了解到:

$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 3  0      0  44160 327144 876600    0    0   894   584  458 2295 11  5 70 15

itop提供了更方便的方式了解,作者Hunz在源码里面写:

It’s quite simple but it does its job.

虽然简单,但是适用:

Ubutun下可以这样安装: apt-get install itop

$ itop
INT                NAME          RATE             MAX
  0 [PIC-edge      time]   628 Ints/s     (max:   628)
  1 [PIC-edge      i804]     4 Ints/s     (max:     4)
 17 [PIC-fasteoi   fire]     8 Ints/s     (max:    22)
 19 [PIC-fasteoi   ata_]     1 Ints/s     (max:    14)
 20 [PIC-fasteoi   ehci]    25 Ints/s     (max:    25)
 45 [MSI-edge      eth0]     1 Ints/s     (max:     1)

他会计算每秒每个中断源中断的次数,看起来比较方便.

itop 程序代码 (redhat)

#!/usr/bin/perl
#
#	Interrupt top
#
#	Show the interrupts per second/per IRQ per CPU

# Parse /proc/interrupts file for data
#
#            CPU0       CPU1       
#   0: 3025267376 3026744388    IO-APIC-edge  timer
#   1:     833854     843315    IO-APIC-edge  i8042
#   6:         15         63    IO-APIC-edge  floppy
#   7:          0          0    IO-APIC-edge  parport0
#   8:     532620     522911    IO-APIC-edge  rtc
#   9:          1          0   IO-APIC-level  acpi
#  12:    9812189    9981980    IO-APIC-edge  i8042
#  14:   27181914   27208373    IO-APIC-edge  ide0
#  58:  249517917          0   IO-APIC-level  eth0
#  66:    1090230    1089904   IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
# 169:      82497      85243   IO-APIC-level  HDA Intel, uhci_hcd:usb5, i915@pci:0000:00:02.0
# 217:          0          0   IO-APIC-level  uhci_hcd:usb4
# 233:    2809674    2795397   IO-APIC-level  libata, uhci_hcd:usb3
# NMI:          0          0 
# LOC: 1754237653 1754237661 
# ERR:          0
# MIS:          0

use IO::File;
use Term::Cap;

$term = Tgetent Term::Cap;
print $term->Tputs('cl');

$fh = new IO::File;

if (!$fh->open("</proc/interrupts")) {
	die "Unable to open /proc/interrupts";
}

$top = $fh->getpos();
$first_time = 0;
while (1) {
	$fh->setpos($top);

	# Read and parse interrupts
	$header = <$fh>; # Header line
	# Count CPUs
	$cpus = () = $header =~ /CPU/g;

	my %irqs;
	while (<$fh>) {
		#if (/^\s*(\d+):(\s*(\d+)\s*)*(\S+)\s*(.*)$/) {
		if (/^\s*(\d+):\s*(\d+)\s+(\S+)\s+(.*)$/) {
			# Found a IRQ line, Build an assoc array of CPU values
			#print $1 . ":" . $2 .":". $3 .":". $4 .":". $5 .":". $6 . ":" . $7 .":". $8 .":". $9 . "\n";
			$irq = $1;
			for ($cpu = 0; $cpu < $cpus; $cpu++) {
				$exp = '$icount = $' . ($cpu + 2);
				eval $exp;
				$irqs{$irq}[$cpu] = $icount
			}
			eval '$desc = $' . ($cpus + 2);
			$desc =~ /(\S+)\s+(.*)$/;
			$irq_type{$irq} = $1;
			$irq_device{$irq} = $2;
			#eval '$irq_type{$irq} = $' . ($cpus + 2);
			#print $irq_type{$irq} . "\n";
			#eval '$irq_device{$irq} = $' . ($cpus + 3);

		}
	}

	if ($first_time != 0) {
		# Prepare sceeen
		print $term->Tputs('ho');
		# Output header
		printf("%28s%" . ($cpus + 1) * 16 . "s", "", "IRQs/Second\n");
		printf('%20s (%3s)  ', "Device", "IRQ");
		foreach ($cpu = 0; $cpu < $cpus; $cpu++) {
			printf('%15s ', 'CPU' . $cpu);
		}
		printf("%15s\n", "TOTAL");
		foreach $irq (keys %irqs) {
			printf('%20s (%3d): ', substr($irq_device{$irq}, 0, 20), $irq);
			$total = 0;
			for ($cpu = 0; $cpu < 2; $cpu ++) {
				printf("%15s ", $irqs{$irq}[$cpu] - $last{$irq}[$cpu]);
				$total += $irqs{$irq}[$cpu] - $last{$irq}[$cpu];
			}
			printf("%15s\n", $total);
		}
	}
	$first_time = 1;
	

	%last = %irqs;
	sleep 1;
}

你可能感兴趣的:(中断,itop)