162306a36Sopenharmony_ci# Display a process of packets and processed time.
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci# It helps us to investigate networking or network device.
462306a36Sopenharmony_ci#
562306a36Sopenharmony_ci# options
662306a36Sopenharmony_ci# tx: show only tx chart
762306a36Sopenharmony_ci# rx: show only rx chart
862306a36Sopenharmony_ci# dev=: show only thing related to specified device
962306a36Sopenharmony_ci# debug: work with debug mode. It shows buffer status.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cifrom __future__ import print_function
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciimport os
1462306a36Sopenharmony_ciimport sys
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cisys.path.append(os.environ['PERF_EXEC_PATH'] + \
1762306a36Sopenharmony_ci	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cifrom perf_trace_context import *
2062306a36Sopenharmony_cifrom Core import *
2162306a36Sopenharmony_cifrom Util import *
2262306a36Sopenharmony_cifrom functools import cmp_to_key
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciall_event_list = []; # insert all tracepoint event related with this script
2562306a36Sopenharmony_ciirq_dic = {}; # key is cpu and value is a list which stacks irqs
2662306a36Sopenharmony_ci              # which raise NET_RX softirq
2762306a36Sopenharmony_cinet_rx_dic = {}; # key is cpu and value include time of NET_RX softirq-entry
2862306a36Sopenharmony_ci		 # and a list which stacks receive
2962306a36Sopenharmony_cireceive_hunk_list = []; # a list which include a sequence of receive events
3062306a36Sopenharmony_cirx_skb_list = []; # received packet list for matching
3162306a36Sopenharmony_ci		       # skb_copy_datagram_iovec
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cibuffer_budget = 65536; # the budget of rx_skb_list, tx_queue_list and
3462306a36Sopenharmony_ci		       # tx_xmit_list
3562306a36Sopenharmony_ciof_count_rx_skb_list = 0; # overflow count
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_citx_queue_list = []; # list of packets which pass through dev_queue_xmit
3862306a36Sopenharmony_ciof_count_tx_queue_list = 0; # overflow count
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_citx_xmit_list = [];  # list of packets which pass through dev_hard_start_xmit
4162306a36Sopenharmony_ciof_count_tx_xmit_list = 0; # overflow count
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_citx_free_list = [];  # list of packets which is freed
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci# options
4662306a36Sopenharmony_cishow_tx = 0;
4762306a36Sopenharmony_cishow_rx = 0;
4862306a36Sopenharmony_cidev = 0; # store a name of device specified by option "dev="
4962306a36Sopenharmony_cidebug = 0;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci# indices of event_info tuple
5262306a36Sopenharmony_ciEINFO_IDX_NAME=   0
5362306a36Sopenharmony_ciEINFO_IDX_CONTEXT=1
5462306a36Sopenharmony_ciEINFO_IDX_CPU=    2
5562306a36Sopenharmony_ciEINFO_IDX_TIME=   3
5662306a36Sopenharmony_ciEINFO_IDX_PID=    4
5762306a36Sopenharmony_ciEINFO_IDX_COMM=   5
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci# Calculate a time interval(msec) from src(nsec) to dst(nsec)
6062306a36Sopenharmony_cidef diff_msec(src, dst):
6162306a36Sopenharmony_ci	return (dst - src) / 1000000.0
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci# Display a process of transmitting a packet
6462306a36Sopenharmony_cidef print_transmit(hunk):
6562306a36Sopenharmony_ci	if dev != 0 and hunk['dev'].find(dev) < 0:
6662306a36Sopenharmony_ci		return
6762306a36Sopenharmony_ci	print("%7s %5d %6d.%06dsec %12.3fmsec      %12.3fmsec" %
6862306a36Sopenharmony_ci		(hunk['dev'], hunk['len'],
6962306a36Sopenharmony_ci		nsecs_secs(hunk['queue_t']),
7062306a36Sopenharmony_ci		nsecs_nsecs(hunk['queue_t'])/1000,
7162306a36Sopenharmony_ci		diff_msec(hunk['queue_t'], hunk['xmit_t']),
7262306a36Sopenharmony_ci		diff_msec(hunk['xmit_t'], hunk['free_t'])))
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci# Format for displaying rx packet processing
7562306a36Sopenharmony_ciPF_IRQ_ENTRY= "  irq_entry(+%.3fmsec irq=%d:%s)"
7662306a36Sopenharmony_ciPF_SOFT_ENTRY="  softirq_entry(+%.3fmsec)"
7762306a36Sopenharmony_ciPF_NAPI_POLL= "  napi_poll_exit(+%.3fmsec %s)"
7862306a36Sopenharmony_ciPF_JOINT=     "         |"
7962306a36Sopenharmony_ciPF_WJOINT=    "         |            |"
8062306a36Sopenharmony_ciPF_NET_RECV=  "         |---netif_receive_skb(+%.3fmsec skb=%x len=%d)"
8162306a36Sopenharmony_ciPF_NET_RX=    "         |---netif_rx(+%.3fmsec skb=%x)"
8262306a36Sopenharmony_ciPF_CPY_DGRAM= "         |      skb_copy_datagram_iovec(+%.3fmsec %d:%s)"
8362306a36Sopenharmony_ciPF_KFREE_SKB= "         |      kfree_skb(+%.3fmsec location=%x)"
8462306a36Sopenharmony_ciPF_CONS_SKB=  "         |      consume_skb(+%.3fmsec)"
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci# Display a process of received packets and interrputs associated with
8762306a36Sopenharmony_ci# a NET_RX softirq
8862306a36Sopenharmony_cidef print_receive(hunk):
8962306a36Sopenharmony_ci	show_hunk = 0
9062306a36Sopenharmony_ci	irq_list = hunk['irq_list']
9162306a36Sopenharmony_ci	cpu = irq_list[0]['cpu']
9262306a36Sopenharmony_ci	base_t = irq_list[0]['irq_ent_t']
9362306a36Sopenharmony_ci	# check if this hunk should be showed
9462306a36Sopenharmony_ci	if dev != 0:
9562306a36Sopenharmony_ci		for i in range(len(irq_list)):
9662306a36Sopenharmony_ci			if irq_list[i]['name'].find(dev) >= 0:
9762306a36Sopenharmony_ci				show_hunk = 1
9862306a36Sopenharmony_ci				break
9962306a36Sopenharmony_ci	else:
10062306a36Sopenharmony_ci		show_hunk = 1
10162306a36Sopenharmony_ci	if show_hunk == 0:
10262306a36Sopenharmony_ci		return
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	print("%d.%06dsec cpu=%d" %
10562306a36Sopenharmony_ci		(nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu))
10662306a36Sopenharmony_ci	for i in range(len(irq_list)):
10762306a36Sopenharmony_ci		print(PF_IRQ_ENTRY %
10862306a36Sopenharmony_ci			(diff_msec(base_t, irq_list[i]['irq_ent_t']),
10962306a36Sopenharmony_ci			irq_list[i]['irq'], irq_list[i]['name']))
11062306a36Sopenharmony_ci		print(PF_JOINT)
11162306a36Sopenharmony_ci		irq_event_list = irq_list[i]['event_list']
11262306a36Sopenharmony_ci		for j in range(len(irq_event_list)):
11362306a36Sopenharmony_ci			irq_event = irq_event_list[j]
11462306a36Sopenharmony_ci			if irq_event['event'] == 'netif_rx':
11562306a36Sopenharmony_ci				print(PF_NET_RX %
11662306a36Sopenharmony_ci					(diff_msec(base_t, irq_event['time']),
11762306a36Sopenharmony_ci					irq_event['skbaddr']))
11862306a36Sopenharmony_ci				print(PF_JOINT)
11962306a36Sopenharmony_ci	print(PF_SOFT_ENTRY %
12062306a36Sopenharmony_ci		diff_msec(base_t, hunk['sirq_ent_t']))
12162306a36Sopenharmony_ci	print(PF_JOINT)
12262306a36Sopenharmony_ci	event_list = hunk['event_list']
12362306a36Sopenharmony_ci	for i in range(len(event_list)):
12462306a36Sopenharmony_ci		event = event_list[i]
12562306a36Sopenharmony_ci		if event['event_name'] == 'napi_poll':
12662306a36Sopenharmony_ci			print(PF_NAPI_POLL %
12762306a36Sopenharmony_ci				(diff_msec(base_t, event['event_t']),
12862306a36Sopenharmony_ci				event['dev']))
12962306a36Sopenharmony_ci			if i == len(event_list) - 1:
13062306a36Sopenharmony_ci				print("")
13162306a36Sopenharmony_ci			else:
13262306a36Sopenharmony_ci				print(PF_JOINT)
13362306a36Sopenharmony_ci		else:
13462306a36Sopenharmony_ci			print(PF_NET_RECV %
13562306a36Sopenharmony_ci				(diff_msec(base_t, event['event_t']),
13662306a36Sopenharmony_ci				event['skbaddr'],
13762306a36Sopenharmony_ci				event['len']))
13862306a36Sopenharmony_ci			if 'comm' in event.keys():
13962306a36Sopenharmony_ci				print(PF_WJOINT)
14062306a36Sopenharmony_ci				print(PF_CPY_DGRAM %
14162306a36Sopenharmony_ci					(diff_msec(base_t, event['comm_t']),
14262306a36Sopenharmony_ci					event['pid'], event['comm']))
14362306a36Sopenharmony_ci			elif 'handle' in event.keys():
14462306a36Sopenharmony_ci				print(PF_WJOINT)
14562306a36Sopenharmony_ci				if event['handle'] == "kfree_skb":
14662306a36Sopenharmony_ci					print(PF_KFREE_SKB %
14762306a36Sopenharmony_ci						(diff_msec(base_t,
14862306a36Sopenharmony_ci						event['comm_t']),
14962306a36Sopenharmony_ci						event['location']))
15062306a36Sopenharmony_ci				elif event['handle'] == "consume_skb":
15162306a36Sopenharmony_ci					print(PF_CONS_SKB %
15262306a36Sopenharmony_ci						diff_msec(base_t,
15362306a36Sopenharmony_ci							event['comm_t']))
15462306a36Sopenharmony_ci			print(PF_JOINT)
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cidef trace_begin():
15762306a36Sopenharmony_ci	global show_tx
15862306a36Sopenharmony_ci	global show_rx
15962306a36Sopenharmony_ci	global dev
16062306a36Sopenharmony_ci	global debug
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	for i in range(len(sys.argv)):
16362306a36Sopenharmony_ci		if i == 0:
16462306a36Sopenharmony_ci			continue
16562306a36Sopenharmony_ci		arg = sys.argv[i]
16662306a36Sopenharmony_ci		if arg == 'tx':
16762306a36Sopenharmony_ci			show_tx = 1
16862306a36Sopenharmony_ci		elif arg =='rx':
16962306a36Sopenharmony_ci			show_rx = 1
17062306a36Sopenharmony_ci		elif arg.find('dev=',0, 4) >= 0:
17162306a36Sopenharmony_ci			dev = arg[4:]
17262306a36Sopenharmony_ci		elif arg == 'debug':
17362306a36Sopenharmony_ci			debug = 1
17462306a36Sopenharmony_ci	if show_tx == 0  and show_rx == 0:
17562306a36Sopenharmony_ci		show_tx = 1
17662306a36Sopenharmony_ci		show_rx = 1
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cidef trace_end():
17962306a36Sopenharmony_ci	# order all events in time
18062306a36Sopenharmony_ci	all_event_list.sort(key=cmp_to_key(lambda a,b :a[EINFO_IDX_TIME] < b[EINFO_IDX_TIME]))
18162306a36Sopenharmony_ci	# process all events
18262306a36Sopenharmony_ci	for i in range(len(all_event_list)):
18362306a36Sopenharmony_ci		event_info = all_event_list[i]
18462306a36Sopenharmony_ci		name = event_info[EINFO_IDX_NAME]
18562306a36Sopenharmony_ci		if name == 'irq__softirq_exit':
18662306a36Sopenharmony_ci			handle_irq_softirq_exit(event_info)
18762306a36Sopenharmony_ci		elif name == 'irq__softirq_entry':
18862306a36Sopenharmony_ci			handle_irq_softirq_entry(event_info)
18962306a36Sopenharmony_ci		elif name == 'irq__softirq_raise':
19062306a36Sopenharmony_ci			handle_irq_softirq_raise(event_info)
19162306a36Sopenharmony_ci		elif name == 'irq__irq_handler_entry':
19262306a36Sopenharmony_ci			handle_irq_handler_entry(event_info)
19362306a36Sopenharmony_ci		elif name == 'irq__irq_handler_exit':
19462306a36Sopenharmony_ci			handle_irq_handler_exit(event_info)
19562306a36Sopenharmony_ci		elif name == 'napi__napi_poll':
19662306a36Sopenharmony_ci			handle_napi_poll(event_info)
19762306a36Sopenharmony_ci		elif name == 'net__netif_receive_skb':
19862306a36Sopenharmony_ci			handle_netif_receive_skb(event_info)
19962306a36Sopenharmony_ci		elif name == 'net__netif_rx':
20062306a36Sopenharmony_ci			handle_netif_rx(event_info)
20162306a36Sopenharmony_ci		elif name == 'skb__skb_copy_datagram_iovec':
20262306a36Sopenharmony_ci			handle_skb_copy_datagram_iovec(event_info)
20362306a36Sopenharmony_ci		elif name == 'net__net_dev_queue':
20462306a36Sopenharmony_ci			handle_net_dev_queue(event_info)
20562306a36Sopenharmony_ci		elif name == 'net__net_dev_xmit':
20662306a36Sopenharmony_ci			handle_net_dev_xmit(event_info)
20762306a36Sopenharmony_ci		elif name == 'skb__kfree_skb':
20862306a36Sopenharmony_ci			handle_kfree_skb(event_info)
20962306a36Sopenharmony_ci		elif name == 'skb__consume_skb':
21062306a36Sopenharmony_ci			handle_consume_skb(event_info)
21162306a36Sopenharmony_ci	# display receive hunks
21262306a36Sopenharmony_ci	if show_rx:
21362306a36Sopenharmony_ci		for i in range(len(receive_hunk_list)):
21462306a36Sopenharmony_ci			print_receive(receive_hunk_list[i])
21562306a36Sopenharmony_ci	# display transmit hunks
21662306a36Sopenharmony_ci	if show_tx:
21762306a36Sopenharmony_ci		print("   dev    len      Qdisc        "
21862306a36Sopenharmony_ci			"       netdevice             free")
21962306a36Sopenharmony_ci		for i in range(len(tx_free_list)):
22062306a36Sopenharmony_ci			print_transmit(tx_free_list[i])
22162306a36Sopenharmony_ci	if debug:
22262306a36Sopenharmony_ci		print("debug buffer status")
22362306a36Sopenharmony_ci		print("----------------------------")
22462306a36Sopenharmony_ci		print("xmit Qdisc:remain:%d overflow:%d" %
22562306a36Sopenharmony_ci			(len(tx_queue_list), of_count_tx_queue_list))
22662306a36Sopenharmony_ci		print("xmit netdevice:remain:%d overflow:%d" %
22762306a36Sopenharmony_ci			(len(tx_xmit_list), of_count_tx_xmit_list))
22862306a36Sopenharmony_ci		print("receive:remain:%d overflow:%d" %
22962306a36Sopenharmony_ci			(len(rx_skb_list), of_count_rx_skb_list))
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci# called from perf, when it finds a correspoinding event
23262306a36Sopenharmony_cidef irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
23362306a36Sopenharmony_ci	if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
23462306a36Sopenharmony_ci		return
23562306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
23662306a36Sopenharmony_ci	all_event_list.append(event_info)
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cidef irq__softirq_exit(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
23962306a36Sopenharmony_ci	if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
24062306a36Sopenharmony_ci		return
24162306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
24262306a36Sopenharmony_ci	all_event_list.append(event_info)
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_cidef irq__softirq_raise(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
24562306a36Sopenharmony_ci	if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
24662306a36Sopenharmony_ci		return
24762306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
24862306a36Sopenharmony_ci	all_event_list.append(event_info)
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_cidef irq__irq_handler_entry(name, context, cpu, sec, nsec, pid, comm,
25162306a36Sopenharmony_ci			callchain, irq, irq_name):
25262306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
25362306a36Sopenharmony_ci			irq, irq_name)
25462306a36Sopenharmony_ci	all_event_list.append(event_info)
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_cidef irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, callchain, irq, ret):
25762306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret)
25862306a36Sopenharmony_ci	all_event_list.append(event_info)
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_cidef napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi,
26162306a36Sopenharmony_ci		dev_name, work=None, budget=None):
26262306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
26362306a36Sopenharmony_ci			napi, dev_name, work, budget)
26462306a36Sopenharmony_ci	all_event_list.append(event_info)
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cidef net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
26762306a36Sopenharmony_ci			skblen, dev_name):
26862306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
26962306a36Sopenharmony_ci			skbaddr, skblen, dev_name)
27062306a36Sopenharmony_ci	all_event_list.append(event_info)
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_cidef net__netif_rx(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
27362306a36Sopenharmony_ci			skblen, dev_name):
27462306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
27562306a36Sopenharmony_ci			skbaddr, skblen, dev_name)
27662306a36Sopenharmony_ci	all_event_list.append(event_info)
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_cidef net__net_dev_queue(name, context, cpu, sec, nsec, pid, comm, callchain,
27962306a36Sopenharmony_ci			skbaddr, skblen, dev_name):
28062306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
28162306a36Sopenharmony_ci			skbaddr, skblen, dev_name)
28262306a36Sopenharmony_ci	all_event_list.append(event_info)
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_cidef net__net_dev_xmit(name, context, cpu, sec, nsec, pid, comm, callchain,
28562306a36Sopenharmony_ci			skbaddr, skblen, rc, dev_name):
28662306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
28762306a36Sopenharmony_ci			skbaddr, skblen, rc ,dev_name)
28862306a36Sopenharmony_ci	all_event_list.append(event_info)
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cidef skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, callchain,
29162306a36Sopenharmony_ci			skbaddr, location, protocol, reason):
29262306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
29362306a36Sopenharmony_ci			skbaddr, location, protocol, reason)
29462306a36Sopenharmony_ci	all_event_list.append(event_info)
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cidef skb__consume_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr):
29762306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
29862306a36Sopenharmony_ci			skbaddr)
29962306a36Sopenharmony_ci	all_event_list.append(event_info)
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_cidef skb__skb_copy_datagram_iovec(name, context, cpu, sec, nsec, pid, comm, callchain,
30262306a36Sopenharmony_ci	skbaddr, skblen):
30362306a36Sopenharmony_ci	event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
30462306a36Sopenharmony_ci			skbaddr, skblen)
30562306a36Sopenharmony_ci	all_event_list.append(event_info)
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_cidef handle_irq_handler_entry(event_info):
30862306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, irq, irq_name) = event_info
30962306a36Sopenharmony_ci	if cpu not in irq_dic.keys():
31062306a36Sopenharmony_ci		irq_dic[cpu] = []
31162306a36Sopenharmony_ci	irq_record = {'irq':irq, 'name':irq_name, 'cpu':cpu, 'irq_ent_t':time}
31262306a36Sopenharmony_ci	irq_dic[cpu].append(irq_record)
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_cidef handle_irq_handler_exit(event_info):
31562306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, irq, ret) = event_info
31662306a36Sopenharmony_ci	if cpu not in irq_dic.keys():
31762306a36Sopenharmony_ci		return
31862306a36Sopenharmony_ci	irq_record = irq_dic[cpu].pop()
31962306a36Sopenharmony_ci	if irq != irq_record['irq']:
32062306a36Sopenharmony_ci		return
32162306a36Sopenharmony_ci	irq_record.update({'irq_ext_t':time})
32262306a36Sopenharmony_ci	# if an irq doesn't include NET_RX softirq, drop.
32362306a36Sopenharmony_ci	if 'event_list' in irq_record.keys():
32462306a36Sopenharmony_ci		irq_dic[cpu].append(irq_record)
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cidef handle_irq_softirq_raise(event_info):
32762306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, vec) = event_info
32862306a36Sopenharmony_ci	if cpu not in irq_dic.keys() \
32962306a36Sopenharmony_ci	or len(irq_dic[cpu]) == 0:
33062306a36Sopenharmony_ci		return
33162306a36Sopenharmony_ci	irq_record = irq_dic[cpu].pop()
33262306a36Sopenharmony_ci	if 'event_list' in irq_record.keys():
33362306a36Sopenharmony_ci		irq_event_list = irq_record['event_list']
33462306a36Sopenharmony_ci	else:
33562306a36Sopenharmony_ci		irq_event_list = []
33662306a36Sopenharmony_ci	irq_event_list.append({'time':time, 'event':'sirq_raise'})
33762306a36Sopenharmony_ci	irq_record.update({'event_list':irq_event_list})
33862306a36Sopenharmony_ci	irq_dic[cpu].append(irq_record)
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_cidef handle_irq_softirq_entry(event_info):
34162306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, vec) = event_info
34262306a36Sopenharmony_ci	net_rx_dic[cpu] = {'sirq_ent_t':time, 'event_list':[]}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_cidef handle_irq_softirq_exit(event_info):
34562306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, vec) = event_info
34662306a36Sopenharmony_ci	irq_list = []
34762306a36Sopenharmony_ci	event_list = 0
34862306a36Sopenharmony_ci	if cpu in irq_dic.keys():
34962306a36Sopenharmony_ci		irq_list = irq_dic[cpu]
35062306a36Sopenharmony_ci		del irq_dic[cpu]
35162306a36Sopenharmony_ci	if cpu in net_rx_dic.keys():
35262306a36Sopenharmony_ci		sirq_ent_t = net_rx_dic[cpu]['sirq_ent_t']
35362306a36Sopenharmony_ci		event_list = net_rx_dic[cpu]['event_list']
35462306a36Sopenharmony_ci		del net_rx_dic[cpu]
35562306a36Sopenharmony_ci	if irq_list == [] or event_list == 0:
35662306a36Sopenharmony_ci		return
35762306a36Sopenharmony_ci	rec_data = {'sirq_ent_t':sirq_ent_t, 'sirq_ext_t':time,
35862306a36Sopenharmony_ci			'irq_list':irq_list, 'event_list':event_list}
35962306a36Sopenharmony_ci	# merge information related to a NET_RX softirq
36062306a36Sopenharmony_ci	receive_hunk_list.append(rec_data)
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_cidef handle_napi_poll(event_info):
36362306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, napi, dev_name,
36462306a36Sopenharmony_ci		work, budget) = event_info
36562306a36Sopenharmony_ci	if cpu in net_rx_dic.keys():
36662306a36Sopenharmony_ci		event_list = net_rx_dic[cpu]['event_list']
36762306a36Sopenharmony_ci		rec_data = {'event_name':'napi_poll',
36862306a36Sopenharmony_ci				'dev':dev_name, 'event_t':time,
36962306a36Sopenharmony_ci				'work':work, 'budget':budget}
37062306a36Sopenharmony_ci		event_list.append(rec_data)
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cidef handle_netif_rx(event_info):
37362306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm,
37462306a36Sopenharmony_ci		skbaddr, skblen, dev_name) = event_info
37562306a36Sopenharmony_ci	if cpu not in irq_dic.keys() \
37662306a36Sopenharmony_ci	or len(irq_dic[cpu]) == 0:
37762306a36Sopenharmony_ci		return
37862306a36Sopenharmony_ci	irq_record = irq_dic[cpu].pop()
37962306a36Sopenharmony_ci	if 'event_list' in irq_record.keys():
38062306a36Sopenharmony_ci		irq_event_list = irq_record['event_list']
38162306a36Sopenharmony_ci	else:
38262306a36Sopenharmony_ci		irq_event_list = []
38362306a36Sopenharmony_ci	irq_event_list.append({'time':time, 'event':'netif_rx',
38462306a36Sopenharmony_ci		'skbaddr':skbaddr, 'skblen':skblen, 'dev_name':dev_name})
38562306a36Sopenharmony_ci	irq_record.update({'event_list':irq_event_list})
38662306a36Sopenharmony_ci	irq_dic[cpu].append(irq_record)
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cidef handle_netif_receive_skb(event_info):
38962306a36Sopenharmony_ci	global of_count_rx_skb_list
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm,
39262306a36Sopenharmony_ci		skbaddr, skblen, dev_name) = event_info
39362306a36Sopenharmony_ci	if cpu in net_rx_dic.keys():
39462306a36Sopenharmony_ci		rec_data = {'event_name':'netif_receive_skb',
39562306a36Sopenharmony_ci				'event_t':time, 'skbaddr':skbaddr, 'len':skblen}
39662306a36Sopenharmony_ci		event_list = net_rx_dic[cpu]['event_list']
39762306a36Sopenharmony_ci		event_list.append(rec_data)
39862306a36Sopenharmony_ci		rx_skb_list.insert(0, rec_data)
39962306a36Sopenharmony_ci		if len(rx_skb_list) > buffer_budget:
40062306a36Sopenharmony_ci			rx_skb_list.pop()
40162306a36Sopenharmony_ci			of_count_rx_skb_list += 1
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_cidef handle_net_dev_queue(event_info):
40462306a36Sopenharmony_ci	global of_count_tx_queue_list
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm,
40762306a36Sopenharmony_ci		skbaddr, skblen, dev_name) = event_info
40862306a36Sopenharmony_ci	skb = {'dev':dev_name, 'skbaddr':skbaddr, 'len':skblen, 'queue_t':time}
40962306a36Sopenharmony_ci	tx_queue_list.insert(0, skb)
41062306a36Sopenharmony_ci	if len(tx_queue_list) > buffer_budget:
41162306a36Sopenharmony_ci		tx_queue_list.pop()
41262306a36Sopenharmony_ci		of_count_tx_queue_list += 1
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cidef handle_net_dev_xmit(event_info):
41562306a36Sopenharmony_ci	global of_count_tx_xmit_list
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm,
41862306a36Sopenharmony_ci		skbaddr, skblen, rc, dev_name) = event_info
41962306a36Sopenharmony_ci	if rc == 0: # NETDEV_TX_OK
42062306a36Sopenharmony_ci		for i in range(len(tx_queue_list)):
42162306a36Sopenharmony_ci			skb = tx_queue_list[i]
42262306a36Sopenharmony_ci			if skb['skbaddr'] == skbaddr:
42362306a36Sopenharmony_ci				skb['xmit_t'] = time
42462306a36Sopenharmony_ci				tx_xmit_list.insert(0, skb)
42562306a36Sopenharmony_ci				del tx_queue_list[i]
42662306a36Sopenharmony_ci				if len(tx_xmit_list) > buffer_budget:
42762306a36Sopenharmony_ci					tx_xmit_list.pop()
42862306a36Sopenharmony_ci					of_count_tx_xmit_list += 1
42962306a36Sopenharmony_ci				return
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_cidef handle_kfree_skb(event_info):
43262306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm,
43362306a36Sopenharmony_ci		skbaddr, location, protocol, reason) = event_info
43462306a36Sopenharmony_ci	for i in range(len(tx_queue_list)):
43562306a36Sopenharmony_ci		skb = tx_queue_list[i]
43662306a36Sopenharmony_ci		if skb['skbaddr'] == skbaddr:
43762306a36Sopenharmony_ci			del tx_queue_list[i]
43862306a36Sopenharmony_ci			return
43962306a36Sopenharmony_ci	for i in range(len(tx_xmit_list)):
44062306a36Sopenharmony_ci		skb = tx_xmit_list[i]
44162306a36Sopenharmony_ci		if skb['skbaddr'] == skbaddr:
44262306a36Sopenharmony_ci			skb['free_t'] = time
44362306a36Sopenharmony_ci			tx_free_list.append(skb)
44462306a36Sopenharmony_ci			del tx_xmit_list[i]
44562306a36Sopenharmony_ci			return
44662306a36Sopenharmony_ci	for i in range(len(rx_skb_list)):
44762306a36Sopenharmony_ci		rec_data = rx_skb_list[i]
44862306a36Sopenharmony_ci		if rec_data['skbaddr'] == skbaddr:
44962306a36Sopenharmony_ci			rec_data.update({'handle':"kfree_skb",
45062306a36Sopenharmony_ci					'comm':comm, 'pid':pid, 'comm_t':time})
45162306a36Sopenharmony_ci			del rx_skb_list[i]
45262306a36Sopenharmony_ci			return
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_cidef handle_consume_skb(event_info):
45562306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, skbaddr) = event_info
45662306a36Sopenharmony_ci	for i in range(len(tx_xmit_list)):
45762306a36Sopenharmony_ci		skb = tx_xmit_list[i]
45862306a36Sopenharmony_ci		if skb['skbaddr'] == skbaddr:
45962306a36Sopenharmony_ci			skb['free_t'] = time
46062306a36Sopenharmony_ci			tx_free_list.append(skb)
46162306a36Sopenharmony_ci			del tx_xmit_list[i]
46262306a36Sopenharmony_ci			return
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_cidef handle_skb_copy_datagram_iovec(event_info):
46562306a36Sopenharmony_ci	(name, context, cpu, time, pid, comm, skbaddr, skblen) = event_info
46662306a36Sopenharmony_ci	for i in range(len(rx_skb_list)):
46762306a36Sopenharmony_ci		rec_data = rx_skb_list[i]
46862306a36Sopenharmony_ci		if skbaddr == rec_data['skbaddr']:
46962306a36Sopenharmony_ci			rec_data.update({'handle':"skb_copy_datagram_iovec",
47062306a36Sopenharmony_ci					'comm':comm, 'pid':pid, 'comm_t':time})
47162306a36Sopenharmony_ci			del rx_skb_list[i]
47262306a36Sopenharmony_ci			return
473