xref: /OK3568_Linux_fs/kernel/tools/perf/scripts/python/netdev-times.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun# Display a process of packets and processed time.
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun# It helps us to investigate networking or network device.
4*4882a593Smuzhiyun#
5*4882a593Smuzhiyun# options
6*4882a593Smuzhiyun# tx: show only tx chart
7*4882a593Smuzhiyun# rx: show only rx chart
8*4882a593Smuzhiyun# dev=: show only thing related to specified device
9*4882a593Smuzhiyun# debug: work with debug mode. It shows buffer status.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyunfrom __future__ import print_function
12*4882a593Smuzhiyun
13*4882a593Smuzhiyunimport os
14*4882a593Smuzhiyunimport sys
15*4882a593Smuzhiyun
16*4882a593Smuzhiyunsys.path.append(os.environ['PERF_EXEC_PATH'] + \
17*4882a593Smuzhiyun	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
18*4882a593Smuzhiyun
19*4882a593Smuzhiyunfrom perf_trace_context import *
20*4882a593Smuzhiyunfrom Core import *
21*4882a593Smuzhiyunfrom Util import *
22*4882a593Smuzhiyunfrom functools import cmp_to_key
23*4882a593Smuzhiyun
24*4882a593Smuzhiyunall_event_list = []; # insert all tracepoint event related with this script
25*4882a593Smuzhiyunirq_dic = {}; # key is cpu and value is a list which stacks irqs
26*4882a593Smuzhiyun              # which raise NET_RX softirq
27*4882a593Smuzhiyunnet_rx_dic = {}; # key is cpu and value include time of NET_RX softirq-entry
28*4882a593Smuzhiyun		 # and a list which stacks receive
29*4882a593Smuzhiyunreceive_hunk_list = []; # a list which include a sequence of receive events
30*4882a593Smuzhiyunrx_skb_list = []; # received packet list for matching
31*4882a593Smuzhiyun		       # skb_copy_datagram_iovec
32*4882a593Smuzhiyun
33*4882a593Smuzhiyunbuffer_budget = 65536; # the budget of rx_skb_list, tx_queue_list and
34*4882a593Smuzhiyun		       # tx_xmit_list
35*4882a593Smuzhiyunof_count_rx_skb_list = 0; # overflow count
36*4882a593Smuzhiyun
37*4882a593Smuzhiyuntx_queue_list = []; # list of packets which pass through dev_queue_xmit
38*4882a593Smuzhiyunof_count_tx_queue_list = 0; # overflow count
39*4882a593Smuzhiyun
40*4882a593Smuzhiyuntx_xmit_list = [];  # list of packets which pass through dev_hard_start_xmit
41*4882a593Smuzhiyunof_count_tx_xmit_list = 0; # overflow count
42*4882a593Smuzhiyun
43*4882a593Smuzhiyuntx_free_list = [];  # list of packets which is freed
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun# options
46*4882a593Smuzhiyunshow_tx = 0;
47*4882a593Smuzhiyunshow_rx = 0;
48*4882a593Smuzhiyundev = 0; # store a name of device specified by option "dev="
49*4882a593Smuzhiyundebug = 0;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun# indices of event_info tuple
52*4882a593SmuzhiyunEINFO_IDX_NAME=   0
53*4882a593SmuzhiyunEINFO_IDX_CONTEXT=1
54*4882a593SmuzhiyunEINFO_IDX_CPU=    2
55*4882a593SmuzhiyunEINFO_IDX_TIME=   3
56*4882a593SmuzhiyunEINFO_IDX_PID=    4
57*4882a593SmuzhiyunEINFO_IDX_COMM=   5
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun# Calculate a time interval(msec) from src(nsec) to dst(nsec)
60*4882a593Smuzhiyundef diff_msec(src, dst):
61*4882a593Smuzhiyun	return (dst - src) / 1000000.0
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun# Display a process of transmitting a packet
64*4882a593Smuzhiyundef print_transmit(hunk):
65*4882a593Smuzhiyun	if dev != 0 and hunk['dev'].find(dev) < 0:
66*4882a593Smuzhiyun		return
67*4882a593Smuzhiyun	print("%7s %5d %6d.%06dsec %12.3fmsec      %12.3fmsec" %
68*4882a593Smuzhiyun		(hunk['dev'], hunk['len'],
69*4882a593Smuzhiyun		nsecs_secs(hunk['queue_t']),
70*4882a593Smuzhiyun		nsecs_nsecs(hunk['queue_t'])/1000,
71*4882a593Smuzhiyun		diff_msec(hunk['queue_t'], hunk['xmit_t']),
72*4882a593Smuzhiyun		diff_msec(hunk['xmit_t'], hunk['free_t'])))
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun# Format for displaying rx packet processing
75*4882a593SmuzhiyunPF_IRQ_ENTRY= "  irq_entry(+%.3fmsec irq=%d:%s)"
76*4882a593SmuzhiyunPF_SOFT_ENTRY="  softirq_entry(+%.3fmsec)"
77*4882a593SmuzhiyunPF_NAPI_POLL= "  napi_poll_exit(+%.3fmsec %s)"
78*4882a593SmuzhiyunPF_JOINT=     "         |"
79*4882a593SmuzhiyunPF_WJOINT=    "         |            |"
80*4882a593SmuzhiyunPF_NET_RECV=  "         |---netif_receive_skb(+%.3fmsec skb=%x len=%d)"
81*4882a593SmuzhiyunPF_NET_RX=    "         |---netif_rx(+%.3fmsec skb=%x)"
82*4882a593SmuzhiyunPF_CPY_DGRAM= "         |      skb_copy_datagram_iovec(+%.3fmsec %d:%s)"
83*4882a593SmuzhiyunPF_KFREE_SKB= "         |      kfree_skb(+%.3fmsec location=%x)"
84*4882a593SmuzhiyunPF_CONS_SKB=  "         |      consume_skb(+%.3fmsec)"
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun# Display a process of received packets and interrputs associated with
87*4882a593Smuzhiyun# a NET_RX softirq
88*4882a593Smuzhiyundef print_receive(hunk):
89*4882a593Smuzhiyun	show_hunk = 0
90*4882a593Smuzhiyun	irq_list = hunk['irq_list']
91*4882a593Smuzhiyun	cpu = irq_list[0]['cpu']
92*4882a593Smuzhiyun	base_t = irq_list[0]['irq_ent_t']
93*4882a593Smuzhiyun	# check if this hunk should be showed
94*4882a593Smuzhiyun	if dev != 0:
95*4882a593Smuzhiyun		for i in range(len(irq_list)):
96*4882a593Smuzhiyun			if irq_list[i]['name'].find(dev) >= 0:
97*4882a593Smuzhiyun				show_hunk = 1
98*4882a593Smuzhiyun				break
99*4882a593Smuzhiyun	else:
100*4882a593Smuzhiyun		show_hunk = 1
101*4882a593Smuzhiyun	if show_hunk == 0:
102*4882a593Smuzhiyun		return
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun	print("%d.%06dsec cpu=%d" %
105*4882a593Smuzhiyun		(nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu))
106*4882a593Smuzhiyun	for i in range(len(irq_list)):
107*4882a593Smuzhiyun		print(PF_IRQ_ENTRY %
108*4882a593Smuzhiyun			(diff_msec(base_t, irq_list[i]['irq_ent_t']),
109*4882a593Smuzhiyun			irq_list[i]['irq'], irq_list[i]['name']))
110*4882a593Smuzhiyun		print(PF_JOINT)
111*4882a593Smuzhiyun		irq_event_list = irq_list[i]['event_list']
112*4882a593Smuzhiyun		for j in range(len(irq_event_list)):
113*4882a593Smuzhiyun			irq_event = irq_event_list[j]
114*4882a593Smuzhiyun			if irq_event['event'] == 'netif_rx':
115*4882a593Smuzhiyun				print(PF_NET_RX %
116*4882a593Smuzhiyun					(diff_msec(base_t, irq_event['time']),
117*4882a593Smuzhiyun					irq_event['skbaddr']))
118*4882a593Smuzhiyun				print(PF_JOINT)
119*4882a593Smuzhiyun	print(PF_SOFT_ENTRY %
120*4882a593Smuzhiyun		diff_msec(base_t, hunk['sirq_ent_t']))
121*4882a593Smuzhiyun	print(PF_JOINT)
122*4882a593Smuzhiyun	event_list = hunk['event_list']
123*4882a593Smuzhiyun	for i in range(len(event_list)):
124*4882a593Smuzhiyun		event = event_list[i]
125*4882a593Smuzhiyun		if event['event_name'] == 'napi_poll':
126*4882a593Smuzhiyun			print(PF_NAPI_POLL %
127*4882a593Smuzhiyun				(diff_msec(base_t, event['event_t']),
128*4882a593Smuzhiyun				event['dev']))
129*4882a593Smuzhiyun			if i == len(event_list) - 1:
130*4882a593Smuzhiyun				print("")
131*4882a593Smuzhiyun			else:
132*4882a593Smuzhiyun				print(PF_JOINT)
133*4882a593Smuzhiyun		else:
134*4882a593Smuzhiyun			print(PF_NET_RECV %
135*4882a593Smuzhiyun				(diff_msec(base_t, event['event_t']),
136*4882a593Smuzhiyun				event['skbaddr'],
137*4882a593Smuzhiyun				event['len']))
138*4882a593Smuzhiyun			if 'comm' in event.keys():
139*4882a593Smuzhiyun				print(PF_WJOINT)
140*4882a593Smuzhiyun				print(PF_CPY_DGRAM %
141*4882a593Smuzhiyun					(diff_msec(base_t, event['comm_t']),
142*4882a593Smuzhiyun					event['pid'], event['comm']))
143*4882a593Smuzhiyun			elif 'handle' in event.keys():
144*4882a593Smuzhiyun				print(PF_WJOINT)
145*4882a593Smuzhiyun				if event['handle'] == "kfree_skb":
146*4882a593Smuzhiyun					print(PF_KFREE_SKB %
147*4882a593Smuzhiyun						(diff_msec(base_t,
148*4882a593Smuzhiyun						event['comm_t']),
149*4882a593Smuzhiyun						event['location']))
150*4882a593Smuzhiyun				elif event['handle'] == "consume_skb":
151*4882a593Smuzhiyun					print(PF_CONS_SKB %
152*4882a593Smuzhiyun						diff_msec(base_t,
153*4882a593Smuzhiyun							event['comm_t']))
154*4882a593Smuzhiyun			print(PF_JOINT)
155*4882a593Smuzhiyun
156*4882a593Smuzhiyundef trace_begin():
157*4882a593Smuzhiyun	global show_tx
158*4882a593Smuzhiyun	global show_rx
159*4882a593Smuzhiyun	global dev
160*4882a593Smuzhiyun	global debug
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun	for i in range(len(sys.argv)):
163*4882a593Smuzhiyun		if i == 0:
164*4882a593Smuzhiyun			continue
165*4882a593Smuzhiyun		arg = sys.argv[i]
166*4882a593Smuzhiyun		if arg == 'tx':
167*4882a593Smuzhiyun			show_tx = 1
168*4882a593Smuzhiyun		elif arg =='rx':
169*4882a593Smuzhiyun			show_rx = 1
170*4882a593Smuzhiyun		elif arg.find('dev=',0, 4) >= 0:
171*4882a593Smuzhiyun			dev = arg[4:]
172*4882a593Smuzhiyun		elif arg == 'debug':
173*4882a593Smuzhiyun			debug = 1
174*4882a593Smuzhiyun	if show_tx == 0  and show_rx == 0:
175*4882a593Smuzhiyun		show_tx = 1
176*4882a593Smuzhiyun		show_rx = 1
177*4882a593Smuzhiyun
178*4882a593Smuzhiyundef trace_end():
179*4882a593Smuzhiyun	# order all events in time
180*4882a593Smuzhiyun	all_event_list.sort(key=cmp_to_key(lambda a,b :a[EINFO_IDX_TIME] < b[EINFO_IDX_TIME]))
181*4882a593Smuzhiyun	# process all events
182*4882a593Smuzhiyun	for i in range(len(all_event_list)):
183*4882a593Smuzhiyun		event_info = all_event_list[i]
184*4882a593Smuzhiyun		name = event_info[EINFO_IDX_NAME]
185*4882a593Smuzhiyun		if name == 'irq__softirq_exit':
186*4882a593Smuzhiyun			handle_irq_softirq_exit(event_info)
187*4882a593Smuzhiyun		elif name == 'irq__softirq_entry':
188*4882a593Smuzhiyun			handle_irq_softirq_entry(event_info)
189*4882a593Smuzhiyun		elif name == 'irq__softirq_raise':
190*4882a593Smuzhiyun			handle_irq_softirq_raise(event_info)
191*4882a593Smuzhiyun		elif name == 'irq__irq_handler_entry':
192*4882a593Smuzhiyun			handle_irq_handler_entry(event_info)
193*4882a593Smuzhiyun		elif name == 'irq__irq_handler_exit':
194*4882a593Smuzhiyun			handle_irq_handler_exit(event_info)
195*4882a593Smuzhiyun		elif name == 'napi__napi_poll':
196*4882a593Smuzhiyun			handle_napi_poll(event_info)
197*4882a593Smuzhiyun		elif name == 'net__netif_receive_skb':
198*4882a593Smuzhiyun			handle_netif_receive_skb(event_info)
199*4882a593Smuzhiyun		elif name == 'net__netif_rx':
200*4882a593Smuzhiyun			handle_netif_rx(event_info)
201*4882a593Smuzhiyun		elif name == 'skb__skb_copy_datagram_iovec':
202*4882a593Smuzhiyun			handle_skb_copy_datagram_iovec(event_info)
203*4882a593Smuzhiyun		elif name == 'net__net_dev_queue':
204*4882a593Smuzhiyun			handle_net_dev_queue(event_info)
205*4882a593Smuzhiyun		elif name == 'net__net_dev_xmit':
206*4882a593Smuzhiyun			handle_net_dev_xmit(event_info)
207*4882a593Smuzhiyun		elif name == 'skb__kfree_skb':
208*4882a593Smuzhiyun			handle_kfree_skb(event_info)
209*4882a593Smuzhiyun		elif name == 'skb__consume_skb':
210*4882a593Smuzhiyun			handle_consume_skb(event_info)
211*4882a593Smuzhiyun	# display receive hunks
212*4882a593Smuzhiyun	if show_rx:
213*4882a593Smuzhiyun		for i in range(len(receive_hunk_list)):
214*4882a593Smuzhiyun			print_receive(receive_hunk_list[i])
215*4882a593Smuzhiyun	# display transmit hunks
216*4882a593Smuzhiyun	if show_tx:
217*4882a593Smuzhiyun		print("   dev    len      Qdisc        "
218*4882a593Smuzhiyun			"       netdevice             free")
219*4882a593Smuzhiyun		for i in range(len(tx_free_list)):
220*4882a593Smuzhiyun			print_transmit(tx_free_list[i])
221*4882a593Smuzhiyun	if debug:
222*4882a593Smuzhiyun		print("debug buffer status")
223*4882a593Smuzhiyun		print("----------------------------")
224*4882a593Smuzhiyun		print("xmit Qdisc:remain:%d overflow:%d" %
225*4882a593Smuzhiyun			(len(tx_queue_list), of_count_tx_queue_list))
226*4882a593Smuzhiyun		print("xmit netdevice:remain:%d overflow:%d" %
227*4882a593Smuzhiyun			(len(tx_xmit_list), of_count_tx_xmit_list))
228*4882a593Smuzhiyun		print("receive:remain:%d overflow:%d" %
229*4882a593Smuzhiyun			(len(rx_skb_list), of_count_rx_skb_list))
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun# called from perf, when it finds a correspoinding event
232*4882a593Smuzhiyundef irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
233*4882a593Smuzhiyun	if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
234*4882a593Smuzhiyun		return
235*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
236*4882a593Smuzhiyun	all_event_list.append(event_info)
237*4882a593Smuzhiyun
238*4882a593Smuzhiyundef irq__softirq_exit(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
239*4882a593Smuzhiyun	if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
240*4882a593Smuzhiyun		return
241*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
242*4882a593Smuzhiyun	all_event_list.append(event_info)
243*4882a593Smuzhiyun
244*4882a593Smuzhiyundef irq__softirq_raise(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
245*4882a593Smuzhiyun	if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
246*4882a593Smuzhiyun		return
247*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
248*4882a593Smuzhiyun	all_event_list.append(event_info)
249*4882a593Smuzhiyun
250*4882a593Smuzhiyundef irq__irq_handler_entry(name, context, cpu, sec, nsec, pid, comm,
251*4882a593Smuzhiyun			callchain, irq, irq_name):
252*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
253*4882a593Smuzhiyun			irq, irq_name)
254*4882a593Smuzhiyun	all_event_list.append(event_info)
255*4882a593Smuzhiyun
256*4882a593Smuzhiyundef irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, callchain, irq, ret):
257*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret)
258*4882a593Smuzhiyun	all_event_list.append(event_info)
259*4882a593Smuzhiyun
260*4882a593Smuzhiyundef napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi,
261*4882a593Smuzhiyun		dev_name, work=None, budget=None):
262*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
263*4882a593Smuzhiyun			napi, dev_name, work, budget)
264*4882a593Smuzhiyun	all_event_list.append(event_info)
265*4882a593Smuzhiyun
266*4882a593Smuzhiyundef net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
267*4882a593Smuzhiyun			skblen, dev_name):
268*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
269*4882a593Smuzhiyun			skbaddr, skblen, dev_name)
270*4882a593Smuzhiyun	all_event_list.append(event_info)
271*4882a593Smuzhiyun
272*4882a593Smuzhiyundef net__netif_rx(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
273*4882a593Smuzhiyun			skblen, dev_name):
274*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
275*4882a593Smuzhiyun			skbaddr, skblen, dev_name)
276*4882a593Smuzhiyun	all_event_list.append(event_info)
277*4882a593Smuzhiyun
278*4882a593Smuzhiyundef net__net_dev_queue(name, context, cpu, sec, nsec, pid, comm, callchain,
279*4882a593Smuzhiyun			skbaddr, skblen, dev_name):
280*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
281*4882a593Smuzhiyun			skbaddr, skblen, dev_name)
282*4882a593Smuzhiyun	all_event_list.append(event_info)
283*4882a593Smuzhiyun
284*4882a593Smuzhiyundef net__net_dev_xmit(name, context, cpu, sec, nsec, pid, comm, callchain,
285*4882a593Smuzhiyun			skbaddr, skblen, rc, dev_name):
286*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
287*4882a593Smuzhiyun			skbaddr, skblen, rc ,dev_name)
288*4882a593Smuzhiyun	all_event_list.append(event_info)
289*4882a593Smuzhiyun
290*4882a593Smuzhiyundef skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, callchain,
291*4882a593Smuzhiyun			skbaddr, protocol, location):
292*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
293*4882a593Smuzhiyun			skbaddr, protocol, location)
294*4882a593Smuzhiyun	all_event_list.append(event_info)
295*4882a593Smuzhiyun
296*4882a593Smuzhiyundef skb__consume_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr):
297*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
298*4882a593Smuzhiyun			skbaddr)
299*4882a593Smuzhiyun	all_event_list.append(event_info)
300*4882a593Smuzhiyun
301*4882a593Smuzhiyundef skb__skb_copy_datagram_iovec(name, context, cpu, sec, nsec, pid, comm, callchain,
302*4882a593Smuzhiyun	skbaddr, skblen):
303*4882a593Smuzhiyun	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
304*4882a593Smuzhiyun			skbaddr, skblen)
305*4882a593Smuzhiyun	all_event_list.append(event_info)
306*4882a593Smuzhiyun
307*4882a593Smuzhiyundef handle_irq_handler_entry(event_info):
308*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, irq, irq_name) = event_info
309*4882a593Smuzhiyun	if cpu not in irq_dic.keys():
310*4882a593Smuzhiyun		irq_dic[cpu] = []
311*4882a593Smuzhiyun	irq_record = {'irq':irq, 'name':irq_name, 'cpu':cpu, 'irq_ent_t':time}
312*4882a593Smuzhiyun	irq_dic[cpu].append(irq_record)
313*4882a593Smuzhiyun
314*4882a593Smuzhiyundef handle_irq_handler_exit(event_info):
315*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, irq, ret) = event_info
316*4882a593Smuzhiyun	if cpu not in irq_dic.keys():
317*4882a593Smuzhiyun		return
318*4882a593Smuzhiyun	irq_record = irq_dic[cpu].pop()
319*4882a593Smuzhiyun	if irq != irq_record['irq']:
320*4882a593Smuzhiyun		return
321*4882a593Smuzhiyun	irq_record.update({'irq_ext_t':time})
322*4882a593Smuzhiyun	# if an irq doesn't include NET_RX softirq, drop.
323*4882a593Smuzhiyun	if 'event_list' in irq_record.keys():
324*4882a593Smuzhiyun		irq_dic[cpu].append(irq_record)
325*4882a593Smuzhiyun
326*4882a593Smuzhiyundef handle_irq_softirq_raise(event_info):
327*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, vec) = event_info
328*4882a593Smuzhiyun	if cpu not in irq_dic.keys() \
329*4882a593Smuzhiyun	or len(irq_dic[cpu]) == 0:
330*4882a593Smuzhiyun		return
331*4882a593Smuzhiyun	irq_record = irq_dic[cpu].pop()
332*4882a593Smuzhiyun	if 'event_list' in irq_record.keys():
333*4882a593Smuzhiyun		irq_event_list = irq_record['event_list']
334*4882a593Smuzhiyun	else:
335*4882a593Smuzhiyun		irq_event_list = []
336*4882a593Smuzhiyun	irq_event_list.append({'time':time, 'event':'sirq_raise'})
337*4882a593Smuzhiyun	irq_record.update({'event_list':irq_event_list})
338*4882a593Smuzhiyun	irq_dic[cpu].append(irq_record)
339*4882a593Smuzhiyun
340*4882a593Smuzhiyundef handle_irq_softirq_entry(event_info):
341*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, vec) = event_info
342*4882a593Smuzhiyun	net_rx_dic[cpu] = {'sirq_ent_t':time, 'event_list':[]}
343*4882a593Smuzhiyun
344*4882a593Smuzhiyundef handle_irq_softirq_exit(event_info):
345*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, vec) = event_info
346*4882a593Smuzhiyun	irq_list = []
347*4882a593Smuzhiyun	event_list = 0
348*4882a593Smuzhiyun	if cpu in irq_dic.keys():
349*4882a593Smuzhiyun		irq_list = irq_dic[cpu]
350*4882a593Smuzhiyun		del irq_dic[cpu]
351*4882a593Smuzhiyun	if cpu in net_rx_dic.keys():
352*4882a593Smuzhiyun		sirq_ent_t = net_rx_dic[cpu]['sirq_ent_t']
353*4882a593Smuzhiyun		event_list = net_rx_dic[cpu]['event_list']
354*4882a593Smuzhiyun		del net_rx_dic[cpu]
355*4882a593Smuzhiyun	if irq_list == [] or event_list == 0:
356*4882a593Smuzhiyun		return
357*4882a593Smuzhiyun	rec_data = {'sirq_ent_t':sirq_ent_t, 'sirq_ext_t':time,
358*4882a593Smuzhiyun			'irq_list':irq_list, 'event_list':event_list}
359*4882a593Smuzhiyun	# merge information realted to a NET_RX softirq
360*4882a593Smuzhiyun	receive_hunk_list.append(rec_data)
361*4882a593Smuzhiyun
362*4882a593Smuzhiyundef handle_napi_poll(event_info):
363*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, napi, dev_name,
364*4882a593Smuzhiyun		work, budget) = event_info
365*4882a593Smuzhiyun	if cpu in net_rx_dic.keys():
366*4882a593Smuzhiyun		event_list = net_rx_dic[cpu]['event_list']
367*4882a593Smuzhiyun		rec_data = {'event_name':'napi_poll',
368*4882a593Smuzhiyun				'dev':dev_name, 'event_t':time,
369*4882a593Smuzhiyun				'work':work, 'budget':budget}
370*4882a593Smuzhiyun		event_list.append(rec_data)
371*4882a593Smuzhiyun
372*4882a593Smuzhiyundef handle_netif_rx(event_info):
373*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm,
374*4882a593Smuzhiyun		skbaddr, skblen, dev_name) = event_info
375*4882a593Smuzhiyun	if cpu not in irq_dic.keys() \
376*4882a593Smuzhiyun	or len(irq_dic[cpu]) == 0:
377*4882a593Smuzhiyun		return
378*4882a593Smuzhiyun	irq_record = irq_dic[cpu].pop()
379*4882a593Smuzhiyun	if 'event_list' in irq_record.keys():
380*4882a593Smuzhiyun		irq_event_list = irq_record['event_list']
381*4882a593Smuzhiyun	else:
382*4882a593Smuzhiyun		irq_event_list = []
383*4882a593Smuzhiyun	irq_event_list.append({'time':time, 'event':'netif_rx',
384*4882a593Smuzhiyun		'skbaddr':skbaddr, 'skblen':skblen, 'dev_name':dev_name})
385*4882a593Smuzhiyun	irq_record.update({'event_list':irq_event_list})
386*4882a593Smuzhiyun	irq_dic[cpu].append(irq_record)
387*4882a593Smuzhiyun
388*4882a593Smuzhiyundef handle_netif_receive_skb(event_info):
389*4882a593Smuzhiyun	global of_count_rx_skb_list
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm,
392*4882a593Smuzhiyun		skbaddr, skblen, dev_name) = event_info
393*4882a593Smuzhiyun	if cpu in net_rx_dic.keys():
394*4882a593Smuzhiyun		rec_data = {'event_name':'netif_receive_skb',
395*4882a593Smuzhiyun				'event_t':time, 'skbaddr':skbaddr, 'len':skblen}
396*4882a593Smuzhiyun		event_list = net_rx_dic[cpu]['event_list']
397*4882a593Smuzhiyun		event_list.append(rec_data)
398*4882a593Smuzhiyun		rx_skb_list.insert(0, rec_data)
399*4882a593Smuzhiyun		if len(rx_skb_list) > buffer_budget:
400*4882a593Smuzhiyun			rx_skb_list.pop()
401*4882a593Smuzhiyun			of_count_rx_skb_list += 1
402*4882a593Smuzhiyun
403*4882a593Smuzhiyundef handle_net_dev_queue(event_info):
404*4882a593Smuzhiyun	global of_count_tx_queue_list
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm,
407*4882a593Smuzhiyun		skbaddr, skblen, dev_name) = event_info
408*4882a593Smuzhiyun	skb = {'dev':dev_name, 'skbaddr':skbaddr, 'len':skblen, 'queue_t':time}
409*4882a593Smuzhiyun	tx_queue_list.insert(0, skb)
410*4882a593Smuzhiyun	if len(tx_queue_list) > buffer_budget:
411*4882a593Smuzhiyun		tx_queue_list.pop()
412*4882a593Smuzhiyun		of_count_tx_queue_list += 1
413*4882a593Smuzhiyun
414*4882a593Smuzhiyundef handle_net_dev_xmit(event_info):
415*4882a593Smuzhiyun	global of_count_tx_xmit_list
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm,
418*4882a593Smuzhiyun		skbaddr, skblen, rc, dev_name) = event_info
419*4882a593Smuzhiyun	if rc == 0: # NETDEV_TX_OK
420*4882a593Smuzhiyun		for i in range(len(tx_queue_list)):
421*4882a593Smuzhiyun			skb = tx_queue_list[i]
422*4882a593Smuzhiyun			if skb['skbaddr'] == skbaddr:
423*4882a593Smuzhiyun				skb['xmit_t'] = time
424*4882a593Smuzhiyun				tx_xmit_list.insert(0, skb)
425*4882a593Smuzhiyun				del tx_queue_list[i]
426*4882a593Smuzhiyun				if len(tx_xmit_list) > buffer_budget:
427*4882a593Smuzhiyun					tx_xmit_list.pop()
428*4882a593Smuzhiyun					of_count_tx_xmit_list += 1
429*4882a593Smuzhiyun				return
430*4882a593Smuzhiyun
431*4882a593Smuzhiyundef handle_kfree_skb(event_info):
432*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm,
433*4882a593Smuzhiyun		skbaddr, protocol, location) = event_info
434*4882a593Smuzhiyun	for i in range(len(tx_queue_list)):
435*4882a593Smuzhiyun		skb = tx_queue_list[i]
436*4882a593Smuzhiyun		if skb['skbaddr'] == skbaddr:
437*4882a593Smuzhiyun			del tx_queue_list[i]
438*4882a593Smuzhiyun			return
439*4882a593Smuzhiyun	for i in range(len(tx_xmit_list)):
440*4882a593Smuzhiyun		skb = tx_xmit_list[i]
441*4882a593Smuzhiyun		if skb['skbaddr'] == skbaddr:
442*4882a593Smuzhiyun			skb['free_t'] = time
443*4882a593Smuzhiyun			tx_free_list.append(skb)
444*4882a593Smuzhiyun			del tx_xmit_list[i]
445*4882a593Smuzhiyun			return
446*4882a593Smuzhiyun	for i in range(len(rx_skb_list)):
447*4882a593Smuzhiyun		rec_data = rx_skb_list[i]
448*4882a593Smuzhiyun		if rec_data['skbaddr'] == skbaddr:
449*4882a593Smuzhiyun			rec_data.update({'handle':"kfree_skb",
450*4882a593Smuzhiyun					'comm':comm, 'pid':pid, 'comm_t':time})
451*4882a593Smuzhiyun			del rx_skb_list[i]
452*4882a593Smuzhiyun			return
453*4882a593Smuzhiyun
454*4882a593Smuzhiyundef handle_consume_skb(event_info):
455*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, skbaddr) = event_info
456*4882a593Smuzhiyun	for i in range(len(tx_xmit_list)):
457*4882a593Smuzhiyun		skb = tx_xmit_list[i]
458*4882a593Smuzhiyun		if skb['skbaddr'] == skbaddr:
459*4882a593Smuzhiyun			skb['free_t'] = time
460*4882a593Smuzhiyun			tx_free_list.append(skb)
461*4882a593Smuzhiyun			del tx_xmit_list[i]
462*4882a593Smuzhiyun			return
463*4882a593Smuzhiyun
464*4882a593Smuzhiyundef handle_skb_copy_datagram_iovec(event_info):
465*4882a593Smuzhiyun	(name, context, cpu, time, pid, comm, skbaddr, skblen) = event_info
466*4882a593Smuzhiyun	for i in range(len(rx_skb_list)):
467*4882a593Smuzhiyun		rec_data = rx_skb_list[i]
468*4882a593Smuzhiyun		if skbaddr == rec_data['skbaddr']:
469*4882a593Smuzhiyun			rec_data.update({'handle':"skb_copy_datagram_iovec",
470*4882a593Smuzhiyun					'comm':comm, 'pid':pid, 'comm_t':time})
471*4882a593Smuzhiyun			del rx_skb_list[i]
472*4882a593Smuzhiyun			return
473