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