1219820Sjeff#!/usr/bin/perl
2219820Sjeff#
3219820Sjeff# Copyright (c) 2008 Voltaire, Inc. All rights reserved.
4219820Sjeff# Copyright (c) 2006 The Regents of the University of California.
5219820Sjeff#
6219820Sjeff# Produced at Lawrence Livermore National Laboratory.
7219820Sjeff# Written by Ira Weiny <weiny2@llnl.gov>.
8219820Sjeff#
9219820Sjeff# This software is available to you under a choice of one of two
10219820Sjeff# licenses.  You may choose to be licensed under the terms of the GNU
11219820Sjeff# General Public License (GPL) Version 2, available from the file
12219820Sjeff# COPYING in the main directory of this source tree, or the
13219820Sjeff# OpenIB.org BSD license below:
14219820Sjeff#
15219820Sjeff#     Redistribution and use in source and binary forms, with or
16219820Sjeff#     without modification, are permitted provided that the following
17219820Sjeff#     conditions are met:
18219820Sjeff#
19219820Sjeff#      - Redistributions of source code must retain the above
20219820Sjeff#        copyright notice, this list of conditions and the following
21219820Sjeff#        disclaimer.
22219820Sjeff#
23219820Sjeff#      - Redistributions in binary form must reproduce the above
24219820Sjeff#        copyright notice, this list of conditions and the following
25219820Sjeff#        disclaimer in the documentation and/or other materials
26219820Sjeff#        provided with the distribution.
27219820Sjeff#
28219820Sjeff# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29219820Sjeff# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30219820Sjeff# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31219820Sjeff# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
32219820Sjeff# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
33219820Sjeff# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34219820Sjeff# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35219820Sjeff# SOFTWARE.
36219820Sjeff#
37219820Sjeff
38219820Sjeffuse strict;
39219820Sjeff
40219820Sjeffuse Getopt::Std;
41219820Sjeffuse IBswcountlimits;
42219820Sjeff
43219820Sjeffmy $sw_addr = "";
44219820Sjeffmy $sw_port = "";
45219820Sjeffmy $verbose = undef;
46219820Sjeff
47219820Sjeff# =========================================================================
48219820Sjeff#
49219820Sjeffsub print_verbose
50219820Sjeff{
51219820Sjeff	if ($verbose) {
52219820Sjeff		print $_[0];
53219820Sjeff	}
54219820Sjeff}
55219820Sjeff
56219820Sjeff# =========================================================================
57219820Sjeff#
58219820Sjeffsub print_all_counts
59219820Sjeff{
60219820Sjeff	if (!$verbose) { return; }
61219820Sjeff
62219820Sjeff	print "   Counter\t\t\tNew ==> Old\n";
63219820Sjeff	foreach my $cnt (@IBswcountlimits::counters) {
64219820Sjeff		print
65219820Sjeff"   $cnt\t\t\t$IBswcountlimits::new_counts{$cnt} ==> $IBswcountlimits::cur_counts{$cnt}\n";
66219820Sjeff	}
67219820Sjeff}
68219820Sjeff
69219820Sjeff# =========================================================================
70219820Sjeff#
71219820Sjeffsub usage_and_exit
72219820Sjeff{
73219820Sjeff	my $prog = $_[0];
74219820Sjeff	print
75219820Sjeff	  "Usage: $prog [-p <pause_time> -b -v -n <cycles> -G] <guid|lid> <port>\n";
76219820Sjeff	print "   Attempt to diagnose a problem on a port\n";
77219820Sjeff	print
78219820Sjeff"   Run this on a link while a job is running which utilizes that link.\n";
79219820Sjeff	print
80219820Sjeff"   -p <pause_time> define the ammount of time between counter polls (default $IBswcountlimits::pause_time)\n";
81219820Sjeff	print "   -v Be verbose\n";
82219820Sjeff	print "   -n <cycles> run n cycles then exit (default -1 == forever)\n";
83219820Sjeff	print "   -G Address provided is a GUID\n";
84219820Sjeff	print "   -b report bytes/second packets/second\n";
85219820Sjeff	exit 2;
86219820Sjeff}
87219820Sjeff
88219820Sjeff# =========================================================================
89219820Sjeff#
90219820Sjeffsub clear_counters
91219820Sjeff{
92219820Sjeff	# clear the counters
93219820Sjeff	foreach my $count (@IBswcountlimits::counters) {
94219820Sjeff		$IBswcountlimits::cur_counts{$count} = 0;
95219820Sjeff		$IBswcountlimits::new_counts{$count} = 0;
96219820Sjeff	}
97219820Sjeff}
98219820Sjeff
99219820Sjeff# =========================================================================
100219820Sjeff#
101219820Sjeffsub mv_counts
102219820Sjeff{
103219820Sjeff	foreach my $count (@IBswcountlimits::counters) {
104219820Sjeff		$IBswcountlimits::cur_counts{$count} =
105219820Sjeff		  $IBswcountlimits::new_counts{$count};
106219820Sjeff	}
107219820Sjeff}
108219820Sjeff
109219820Sjeff# =========================================================================
110219820Sjeff# use perfquery to get the counters.
111219820Sjeffmy $GUID = "";
112219820Sjeff
113219820Sjeffsub get_new_counts
114219820Sjeff{
115219820Sjeff	my $addr = $_[0];
116219820Sjeff	my $port = $_[1];
117219820Sjeff	mv_counts;
118219820Sjeff	ensure_cache_dir;
119219820Sjeff	if (
120219820Sjeff		system(
121219820Sjeff"perfquery $GUID $addr $port > $IBswcountlimits::cache_dir/perfquery.out"
122219820Sjeff		)
123219820Sjeff	  )
124219820Sjeff	{
125219820Sjeff		die "perfquery failed : \"perfquery $GUID $addr $port\"\n";
126219820Sjeff	}
127219820Sjeff	open PERF_QUERY, "<$IBswcountlimits::cache_dir/perfquery.out"
128219820Sjeff	  or die "cannot read '$IBswcountlimits::cache_dir/perfquery.out': $!\n";
129219820Sjeff	while (my $line = <PERF_QUERY>) {
130219820Sjeff		foreach my $count (@IBswcountlimits::counters) {
131219820Sjeff			if ($line =~ /^$count:\.+(\d+)/) {
132219820Sjeff				$IBswcountlimits::new_counts{$count} = $1;
133219820Sjeff			}
134219820Sjeff		}
135219820Sjeff	}
136219820Sjeff	close PERF_QUERY;
137219820Sjeff}
138219820Sjeff
139219820Sjeffmy $cycle = -1;    # forever
140219820Sjeff
141219820Sjeffmy $bytes_per_second = undef;
142219820Sjeffmy $argv0            = `basename $0`;
143219820Sjeffchomp $argv0;
144219820Sjeffif (!getopts("hbvp:n:G"))        { usage_and_exit $argv0; }
145219820Sjeffif (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; }
146219820Sjeffif (defined $Getopt::Std::opt_p) {
147219820Sjeff	$IBswcountlimits::pause_time = $Getopt::Std::opt_p;
148219820Sjeff}
149219820Sjeffif (defined $Getopt::Std::opt_v) { $verbose          = $Getopt::Std::opt_v; }
150219820Sjeffif (defined $Getopt::Std::opt_n) { $cycle            = $Getopt::Std::opt_n; }
151219820Sjeffif (defined $Getopt::Std::opt_G) { $GUID             = "-G"; }
152219820Sjeffif (defined $Getopt::Std::opt_b) { $bytes_per_second = $Getopt::Std::opt_b; }
153219820Sjeff
154219820Sjeffmy $sw_addr = $ARGV[0];
155219820Sjeffmy $sw_port = $ARGV[1];
156219820Sjeff
157219820Sjeffsub main
158219820Sjeff{
159219820Sjeff	clear_counters;
160219820Sjeff	get_new_counts($sw_addr, $sw_port);
161219820Sjeff	while ($cycle != 0) {
162219820Sjeff		print "Checking counts...\n";
163219820Sjeff		sleep($IBswcountlimits::pause_time);
164219820Sjeff		get_new_counts($sw_addr, $sw_port);
165219820Sjeff		check_counter_rates;
166219820Sjeff		if ($bytes_per_second) {
167219820Sjeff			print_data_rates;
168219820Sjeff		}
169219820Sjeff		print_all_counts;
170219820Sjeff		if ($cycle != -1) { $cycle = $cycle - 1; }
171219820Sjeff	}
172219820Sjeff}
173219820Sjeffmain;
174219820Sjeff
175