xref: /aosp_15_r20/external/bcc/tools/netqtop.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python
2*387f9dfdSAndroid Build Coastguard Worker
3*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
4*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
5*387f9dfdSAndroid Build Coastguard Workerfrom ctypes import *
6*387f9dfdSAndroid Build Coastguard Workerimport argparse
7*387f9dfdSAndroid Build Coastguard Workerimport os
8*387f9dfdSAndroid Build Coastguard Workerfrom time import sleep,time,localtime,asctime
9*387f9dfdSAndroid Build Coastguard Worker
10*387f9dfdSAndroid Build Coastguard Worker# pre defines -------------------------------
11*387f9dfdSAndroid Build Coastguard WorkerROOT_PATH = "/sys/class/net"
12*387f9dfdSAndroid Build Coastguard WorkerIFNAMSIZ = 16
13*387f9dfdSAndroid Build Coastguard WorkerCOL_WIDTH = 10
14*387f9dfdSAndroid Build Coastguard WorkerMAX_QUEUE_NUM = 1024
15*387f9dfdSAndroid Build Coastguard WorkerEBPF_FILE = "netqtop.c"
16*387f9dfdSAndroid Build Coastguard Worker
17*387f9dfdSAndroid Build Coastguard Worker# structure for network interface name array
18*387f9dfdSAndroid Build Coastguard Workerclass Devname(Structure):
19*387f9dfdSAndroid Build Coastguard Worker    _fields_=[
20*387f9dfdSAndroid Build Coastguard Worker        ('name', c_char*IFNAMSIZ)
21*387f9dfdSAndroid Build Coastguard Worker    ]
22*387f9dfdSAndroid Build Coastguard Worker
23*387f9dfdSAndroid Build Coastguard Worker################## printer for results ###################
24*387f9dfdSAndroid Build Coastguard Workerdef to_str(num):
25*387f9dfdSAndroid Build Coastguard Worker    s = ""
26*387f9dfdSAndroid Build Coastguard Worker    if num > 1000000:
27*387f9dfdSAndroid Build Coastguard Worker        return str(round(num/(1024*1024.0), 2)) + 'M'
28*387f9dfdSAndroid Build Coastguard Worker    elif num > 1000:
29*387f9dfdSAndroid Build Coastguard Worker        return str(round(num/1024.0, 2)) + 'K'
30*387f9dfdSAndroid Build Coastguard Worker    else:
31*387f9dfdSAndroid Build Coastguard Worker        if isinstance(num, float):
32*387f9dfdSAndroid Build Coastguard Worker            return str(round(num, 2))
33*387f9dfdSAndroid Build Coastguard Worker        else:
34*387f9dfdSAndroid Build Coastguard Worker            return str(num)
35*387f9dfdSAndroid Build Coastguard Worker
36*387f9dfdSAndroid Build Coastguard Workerdef print_table(table, qnum):
37*387f9dfdSAndroid Build Coastguard Worker    global print_interval
38*387f9dfdSAndroid Build Coastguard Worker
39*387f9dfdSAndroid Build Coastguard Worker    # ---- print headers ----------------
40*387f9dfdSAndroid Build Coastguard Worker    headers = [
41*387f9dfdSAndroid Build Coastguard Worker		"QueueID",
42*387f9dfdSAndroid Build Coastguard Worker		"avg_size",
43*387f9dfdSAndroid Build Coastguard Worker		"[0, 64)",
44*387f9dfdSAndroid Build Coastguard Worker		"[64, 512)",
45*387f9dfdSAndroid Build Coastguard Worker		"[512, 2K)",
46*387f9dfdSAndroid Build Coastguard Worker		"[2K, 16K)",
47*387f9dfdSAndroid Build Coastguard Worker		"[16K, 64K)"
48*387f9dfdSAndroid Build Coastguard Worker	]
49*387f9dfdSAndroid Build Coastguard Worker    if args.throughput:
50*387f9dfdSAndroid Build Coastguard Worker        headers.append("BPS")
51*387f9dfdSAndroid Build Coastguard Worker        headers.append("PPS")
52*387f9dfdSAndroid Build Coastguard Worker
53*387f9dfdSAndroid Build Coastguard Worker    print(" ", end="")
54*387f9dfdSAndroid Build Coastguard Worker    for hd in headers:
55*387f9dfdSAndroid Build Coastguard Worker        print( "%-11s" % hd, end="")
56*387f9dfdSAndroid Build Coastguard Worker    print()
57*387f9dfdSAndroid Build Coastguard Worker
58*387f9dfdSAndroid Build Coastguard Worker    # ------- calculates --------------
59*387f9dfdSAndroid Build Coastguard Worker    qids=[]
60*387f9dfdSAndroid Build Coastguard Worker    tBPS = 0
61*387f9dfdSAndroid Build Coastguard Worker    tPPS = 0
62*387f9dfdSAndroid Build Coastguard Worker    tAVG = 0
63*387f9dfdSAndroid Build Coastguard Worker    tGroup = [0,0,0,0,0]
64*387f9dfdSAndroid Build Coastguard Worker    tpkt = 0
65*387f9dfdSAndroid Build Coastguard Worker    tlen = 0
66*387f9dfdSAndroid Build Coastguard Worker    for k, v in table.items():
67*387f9dfdSAndroid Build Coastguard Worker        qids += [k.value]
68*387f9dfdSAndroid Build Coastguard Worker        tlen += v.total_pkt_len
69*387f9dfdSAndroid Build Coastguard Worker        tpkt += v.num_pkt
70*387f9dfdSAndroid Build Coastguard Worker        tGroup[0] += v.size_64B
71*387f9dfdSAndroid Build Coastguard Worker        tGroup[1] += v.size_512B
72*387f9dfdSAndroid Build Coastguard Worker        tGroup[2] += v.size_2K
73*387f9dfdSAndroid Build Coastguard Worker        tGroup[3] += v.size_16K
74*387f9dfdSAndroid Build Coastguard Worker        tGroup[4] += v.size_64K
75*387f9dfdSAndroid Build Coastguard Worker    tBPS = tlen / print_interval
76*387f9dfdSAndroid Build Coastguard Worker    tPPS = tpkt / print_interval
77*387f9dfdSAndroid Build Coastguard Worker    if tpkt != 0:
78*387f9dfdSAndroid Build Coastguard Worker        tAVG = tlen / tpkt
79*387f9dfdSAndroid Build Coastguard Worker
80*387f9dfdSAndroid Build Coastguard Worker    # -------- print table --------------
81*387f9dfdSAndroid Build Coastguard Worker    for k in range(qnum):
82*387f9dfdSAndroid Build Coastguard Worker        if k in qids:
83*387f9dfdSAndroid Build Coastguard Worker            item = table[c_ushort(k)]
84*387f9dfdSAndroid Build Coastguard Worker            data = [
85*387f9dfdSAndroid Build Coastguard Worker                k,
86*387f9dfdSAndroid Build Coastguard Worker                item.total_pkt_len,
87*387f9dfdSAndroid Build Coastguard Worker                item.num_pkt,
88*387f9dfdSAndroid Build Coastguard Worker                item.size_64B,
89*387f9dfdSAndroid Build Coastguard Worker                item.size_512B,
90*387f9dfdSAndroid Build Coastguard Worker                item.size_2K,
91*387f9dfdSAndroid Build Coastguard Worker                item.size_16K,
92*387f9dfdSAndroid Build Coastguard Worker                item.size_64K
93*387f9dfdSAndroid Build Coastguard Worker            ]
94*387f9dfdSAndroid Build Coastguard Worker        else:
95*387f9dfdSAndroid Build Coastguard Worker            data = [k,0,0,0,0,0,0,0]
96*387f9dfdSAndroid Build Coastguard Worker
97*387f9dfdSAndroid Build Coastguard Worker        # print a line per queue
98*387f9dfdSAndroid Build Coastguard Worker        avg = 0
99*387f9dfdSAndroid Build Coastguard Worker        if data[2] != 0:
100*387f9dfdSAndroid Build Coastguard Worker            avg = data[1] / data[2]
101*387f9dfdSAndroid Build Coastguard Worker        print(" %-11d%-11s%-11s%-11s%-11s%-11s%-11s" % (
102*387f9dfdSAndroid Build Coastguard Worker            data[0],
103*387f9dfdSAndroid Build Coastguard Worker            to_str(avg),
104*387f9dfdSAndroid Build Coastguard Worker            to_str(data[3]),
105*387f9dfdSAndroid Build Coastguard Worker            to_str(data[4]),
106*387f9dfdSAndroid Build Coastguard Worker            to_str(data[5]),
107*387f9dfdSAndroid Build Coastguard Worker            to_str(data[6]),
108*387f9dfdSAndroid Build Coastguard Worker            to_str(data[7])
109*387f9dfdSAndroid Build Coastguard Worker        ), end="")
110*387f9dfdSAndroid Build Coastguard Worker        if args.throughput:
111*387f9dfdSAndroid Build Coastguard Worker            BPS = data[1] / print_interval
112*387f9dfdSAndroid Build Coastguard Worker            PPS = data[2] / print_interval
113*387f9dfdSAndroid Build Coastguard Worker            print("%-11s%-11s" % (
114*387f9dfdSAndroid Build Coastguard Worker                to_str(BPS),
115*387f9dfdSAndroid Build Coastguard Worker                to_str(PPS)
116*387f9dfdSAndroid Build Coastguard Worker            ))
117*387f9dfdSAndroid Build Coastguard Worker        else:
118*387f9dfdSAndroid Build Coastguard Worker            print()
119*387f9dfdSAndroid Build Coastguard Worker
120*387f9dfdSAndroid Build Coastguard Worker    # ------- print total --------------
121*387f9dfdSAndroid Build Coastguard Worker    print(" Total      %-11s%-11s%-11s%-11s%-11s%-11s" % (
122*387f9dfdSAndroid Build Coastguard Worker        to_str(tAVG),
123*387f9dfdSAndroid Build Coastguard Worker        to_str(tGroup[0]),
124*387f9dfdSAndroid Build Coastguard Worker        to_str(tGroup[1]),
125*387f9dfdSAndroid Build Coastguard Worker        to_str(tGroup[2]),
126*387f9dfdSAndroid Build Coastguard Worker        to_str(tGroup[3]),
127*387f9dfdSAndroid Build Coastguard Worker        to_str(tGroup[4])
128*387f9dfdSAndroid Build Coastguard Worker    ), end="")
129*387f9dfdSAndroid Build Coastguard Worker
130*387f9dfdSAndroid Build Coastguard Worker    if args.throughput:
131*387f9dfdSAndroid Build Coastguard Worker        print("%-11s%-11s" % (
132*387f9dfdSAndroid Build Coastguard Worker            to_str(tBPS),
133*387f9dfdSAndroid Build Coastguard Worker            to_str(tPPS)
134*387f9dfdSAndroid Build Coastguard Worker        ))
135*387f9dfdSAndroid Build Coastguard Worker    else:
136*387f9dfdSAndroid Build Coastguard Worker        print()
137*387f9dfdSAndroid Build Coastguard Worker
138*387f9dfdSAndroid Build Coastguard Worker
139*387f9dfdSAndroid Build Coastguard Workerdef print_result(b):
140*387f9dfdSAndroid Build Coastguard Worker    # --------- print tx queues ---------------
141*387f9dfdSAndroid Build Coastguard Worker    print(asctime(localtime(time())))
142*387f9dfdSAndroid Build Coastguard Worker    print("TX")
143*387f9dfdSAndroid Build Coastguard Worker    table = b['tx_q']
144*387f9dfdSAndroid Build Coastguard Worker    print_table(table, tx_num)
145*387f9dfdSAndroid Build Coastguard Worker    b['tx_q'].clear()
146*387f9dfdSAndroid Build Coastguard Worker
147*387f9dfdSAndroid Build Coastguard Worker    # --------- print rx queues ---------------
148*387f9dfdSAndroid Build Coastguard Worker    print("")
149*387f9dfdSAndroid Build Coastguard Worker    print("RX")
150*387f9dfdSAndroid Build Coastguard Worker    table = b['rx_q']
151*387f9dfdSAndroid Build Coastguard Worker    print_table(table, rx_num)
152*387f9dfdSAndroid Build Coastguard Worker    b['rx_q'].clear()
153*387f9dfdSAndroid Build Coastguard Worker    if args.throughput:
154*387f9dfdSAndroid Build Coastguard Worker        print("-"*95)
155*387f9dfdSAndroid Build Coastguard Worker    else:
156*387f9dfdSAndroid Build Coastguard Worker        print("-"*77)
157*387f9dfdSAndroid Build Coastguard Worker
158*387f9dfdSAndroid Build Coastguard Worker############## specify network interface #################
159*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(description="")
160*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--name", "-n", type=str, default="")
161*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--interval", "-i", type=float, default=1)
162*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--throughput", "-t", action="store_true")
163*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true", help=argparse.SUPPRESS)
164*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
165*387f9dfdSAndroid Build Coastguard Worker
166*387f9dfdSAndroid Build Coastguard Workerif args.ebpf:
167*387f9dfdSAndroid Build Coastguard Worker    with open(EBPF_FILE) as fileobj:
168*387f9dfdSAndroid Build Coastguard Worker        progtxt = fileobj.read()
169*387f9dfdSAndroid Build Coastguard Worker        print(progtxt)
170*387f9dfdSAndroid Build Coastguard Worker    exit()
171*387f9dfdSAndroid Build Coastguard Worker
172*387f9dfdSAndroid Build Coastguard Workerif args.name == "":
173*387f9dfdSAndroid Build Coastguard Worker	print ("Please specify a network interface.")
174*387f9dfdSAndroid Build Coastguard Worker	exit()
175*387f9dfdSAndroid Build Coastguard Workerelse:
176*387f9dfdSAndroid Build Coastguard Worker	dev_name = args.name
177*387f9dfdSAndroid Build Coastguard Worker
178*387f9dfdSAndroid Build Coastguard Workerif len(dev_name) > IFNAMSIZ-1:
179*387f9dfdSAndroid Build Coastguard Worker    print ("NIC name too long")
180*387f9dfdSAndroid Build Coastguard Worker    exit()
181*387f9dfdSAndroid Build Coastguard Worker
182*387f9dfdSAndroid Build Coastguard Workerprint_interval = args.interval + 0.0
183*387f9dfdSAndroid Build Coastguard Workerif print_interval == 0:
184*387f9dfdSAndroid Build Coastguard Worker    print ("print interval must be non-zero")
185*387f9dfdSAndroid Build Coastguard Worker    exit()
186*387f9dfdSAndroid Build Coastguard Worker
187*387f9dfdSAndroid Build Coastguard Worker################ get number of queues #####################
188*387f9dfdSAndroid Build Coastguard Workertx_num = 0
189*387f9dfdSAndroid Build Coastguard Workerrx_num = 0
190*387f9dfdSAndroid Build Coastguard Workerpath = ROOT_PATH + "/" + dev_name + "/queues"
191*387f9dfdSAndroid Build Coastguard Workerif not os.path.exists(path):
192*387f9dfdSAndroid Build Coastguard Worker	print ("Net interface", dev_name, "does not exits.")
193*387f9dfdSAndroid Build Coastguard Worker	exit()
194*387f9dfdSAndroid Build Coastguard Worker
195*387f9dfdSAndroid Build Coastguard Workerlist = os.listdir(path)
196*387f9dfdSAndroid Build Coastguard Workerfor s in list:
197*387f9dfdSAndroid Build Coastguard Worker    if s[0] == 'r':
198*387f9dfdSAndroid Build Coastguard Worker        rx_num += 1
199*387f9dfdSAndroid Build Coastguard Worker    if s[0] == 't':
200*387f9dfdSAndroid Build Coastguard Worker        tx_num += 1
201*387f9dfdSAndroid Build Coastguard Worker
202*387f9dfdSAndroid Build Coastguard Workerif tx_num > MAX_QUEUE_NUM or rx_num > MAX_QUEUE_NUM:
203*387f9dfdSAndroid Build Coastguard Worker    print ("number of queues over 1024 is not supported.")
204*387f9dfdSAndroid Build Coastguard Worker    exit()
205*387f9dfdSAndroid Build Coastguard Worker
206*387f9dfdSAndroid Build Coastguard Worker################## start tracing ##################
207*387f9dfdSAndroid Build Coastguard Workerb = BPF(src_file = EBPF_FILE)
208*387f9dfdSAndroid Build Coastguard Worker# --------- set hash array --------
209*387f9dfdSAndroid Build Coastguard Workerdevname_map = b['name_map']
210*387f9dfdSAndroid Build Coastguard Worker_name = Devname()
211*387f9dfdSAndroid Build Coastguard Worker_name.name = dev_name.encode()
212*387f9dfdSAndroid Build Coastguard Workerdevname_map[0] = _name
213*387f9dfdSAndroid Build Coastguard Worker
214*387f9dfdSAndroid Build Coastguard Workerwhile 1:
215*387f9dfdSAndroid Build Coastguard Worker    try:
216*387f9dfdSAndroid Build Coastguard Worker        sleep(print_interval)
217*387f9dfdSAndroid Build Coastguard Worker        print_result(b)
218*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
219*387f9dfdSAndroid Build Coastguard Worker        exit()
220