# Monitor the system for dropped packets and proudce a report of drop locations and counts

import os
import sys

sys.path.append(os.environ['PERF_EXEC_PATH'] + \
		'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')

from perf_trace_context import *
from Core import *
from Util import *

drop_log = {}
kallsyms = []

def get_kallsyms_table():
	global kallsyms

	try:
		f = open("/proc/kallsyms", "r")
	except:
		return

	for line in f:
		loc = int(line.split()[0], 16)
		name = line.split()[2]
		kallsyms.append((loc, name))
	kallsyms.sort()

def get_sym(sloc):
	loc = int(sloc)

	# Invariant: kallsyms[i][0] <= loc for all 0 <= i <= start
	#            kallsyms[i][0] > loc for all end <= i < len(kallsyms)
	start, end = -1, len(kallsyms)
	while end != start + 1:
		pivot = (start + end) // 2
		if loc < kallsyms[pivot][0]:
			end = pivot
		else:
			start = pivot

	# Now (start == -1 or kallsyms[start][0] <= loc)
	# and (start == len(kallsyms) - 1 or loc < kallsyms[start + 1][0])
	if start >= 0:
		symloc, name = kallsyms[start]
		return (name, loc - symloc)
	else:
		return (None, 0)

def print_drop_table():
	print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT")
	for i in drop_log.keys():
		(sym, off) = get_sym(i)
		if sym == None:
			sym = i
		print "%25s %25s %25s" % (sym, off, drop_log[i])


def trace_begin():
	print "Starting trace (Ctrl-C to dump results)"

def trace_end():
	print "Gathering kallsyms data"
	get_kallsyms_table()
	print_drop_table()

# called from perf, when it finds a correspoinding event
def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, callchain,
		   skbaddr, location, protocol):
	slocation = str(location)
	try:
		drop_log[slocation] = drop_log[slocation] + 1
	except:
		drop_log[slocation] = 1
ipv4/tcp_recovery.c?h=nds-private-remove'>log</a><a href='/cgit.cgi/linux/net-next.git/tree/net/ipv4/tcp_recovery.c?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6'>tree</a><a href='/cgit.cgi/linux/net-next.git/commit/net/ipv4/tcp_recovery.c?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6'>commit</a><a href='/cgit.cgi/linux/net-next.git/diff/net/ipv4/tcp_recovery.c?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6'>diff</a></td><td class='form'><form class='right' method='get' action='/cgit.cgi/linux/net-next.git/log/net/ipv4/tcp_recovery.c'>
<input type='hidden' name='h' value='nds-private-remove'/><input type='hidden' name='id' value='f01a2161577d31b14581e0db3bbbdfa963f145b6'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/cgit.cgi/linux/net-next.git/log/?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6'>root</a>/<a href='/cgit.cgi/linux/net-next.git/log/net?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6'>net</a>/<a href='/cgit.cgi/linux/net-next.git/log/net/ipv4?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6'>ipv4</a>/<a href='/cgit.cgi/linux/net-next.git/log/net/ipv4/tcp_recovery.c?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6'>tcp_recovery.c</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th class='left'>Age</th><th class='left'>Commit message (<a href='/cgit.cgi/linux/net-next.git/log/net/ipv4/tcp_recovery.c?h=nds-private-remove&amp;id=f01a2161577d31b14581e0db3bbbdfa963f145b6&amp;showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Files</th><th class='left'>Lines</th></tr>