ebpf实战(一)-------监控udp延迟

news/2024/5/18 15:13:48 标签: udp, 网络, ebpf, bpftrace, bcc

问题背景:
为了分析udp数据通信中端到端的延迟,我们需要对整个通信链路的每个阶段进行监控,找出延迟最长的阶段.

udp接收端有2个主要路径
1.数据包到达本机后,由软中断处理程序将数据包接收并放入udp socket的接收缓冲区
在这里插入图片描述

数据接收流程
2. 应用程序调用recvmsg等api将数据从socket缓冲区读出
在这里插入图片描述

应用程序读取数据流程
2和1之间可能由于调度等造成延迟,我们写一个bcc程序对指定接收端口和延迟大于某个值的情况进行监控

bcc程序原理
我们在流程1放入udp缓冲区时(udp_unicast_rcv_skb),记录此skb的时间

然后在流程2读取udp缓冲区时(__skb_recv_udp)时取出1中记录的skb时间,并与当前时间做差值得到延迟.

#!/usr/bin/python3
# @lint-avoid-python-3-compatibility-imports
#
# udplatency    Trace long udp recvmsg delays.
#               For Linux, uses BCC, eBPF.
#
# This script traces high delays between skb being
# ready to in recv queue and them recvmsg on CPU after that.
#
# USAGE: udplatency [-d dport] [-l lat]

import argparse
import ctypes as ct
from time import strftime
from bcc import BPF

bpf_text = '''
# include <linux/ip.h>
# include <linux/netfilter.h>
# include <net/ip.h>
# include <uapi/linux/bpf.h>

struct data_t {
    u64 ts;
    u64 lat;
};

BPF_PERF_OUTPUT(events);
BPF_HASH(recv_lat, struct sk_buff*);

int kprobe__udp_unicast_rcv_skb(struct pt_regs *ctx, struct sock *sk, struct sk_buff* skb)
{
        struct udphdr *udp_hdr = (struct udphdr *)(skb->head + skb->transport_header);
        u16 dst_port = bpf_ntohs(udp_hdr->dest);
        if (dst_port == DST_PORT) {
            u64 ts = bpf_ktime_get_ns();
            recv_lat.update(&skb, &ts);
        }
                return 0;
};

int kretprobe____skb_recv_udp(struct pt_regs *ctx)
{
  struct sk_buff* skb = (struct sk_buff*)PT_REGS_RC(ctx);
  struct udphdr *udp_hdr = (struct udphdr *)(skb->head + skb->transport_header);
  u16 dst_port = bpf_ntohs(udp_hdr->dest);

  if (dst_port == DST_PORT) {
    struct data_t data = {};
    u64 *tsp = recv_lat.lookup(&skb);
    if (tsp != 0) {
        Home = bpf_ktime_get_ns() - *tsp;
    }
    recv_lat.delete(&skb);

    if (data.lat >= LAT_NS) {
        bpf_probe_read_kernel(&(data.ts), sizeof(*tsp), tsp);
        events.perf_submit(ctx, &data, sizeof(data));
    }
  }

  return 0;
}
'''


class EventData(ct.Structure):
    _fields_ = [("ts", ct.c_ulonglong),
                ("lat", ct.c_ulonglong)]


def print_event(cpu, data, size):
    event = ct.cast(data, ct.POINTER(EventData)).contents
    print("%-8s ts:%d lat: %dms\n" % (strftime("%H:%M:%S"), event.ts, event.lat / 3000000))


parser = argparse.ArgumentParser(
    description="Track udp recv latency")
parser.add_argument("-d", "--dport", type=int, required=True,
                    help="udp dst port")
parser.add_argument("-l", "--lat", type=int,
                    help="report latency > ns, default is 3000000")
args = parser.parse_args()

lat_ns = 3000000

if args.lat:
    lat_ns = args.lat

bpf_text = bpf_text.replace('DST_PORT', str(args.dport))
bpf_text = bpf_text.replace('LAT_NS', str(lat_ns))

# initialize BPF
b = BPF(text=bpf_text)

b["events"].open_perf_buffer(print_event)
while True:
    try:
        b.perf_buffer_poll()
    except KeyboardInterrupt:
        exit()

http://www.niftyadmin.cn/n/5207952.html

相关文章

指针变量与指针类型的深入理解

1.知识总结 相关代码展示 #include <stdio.h> int main() {int n 0x11223344;int *pi &n; *pi 0; return 0; } #include <stdio.h> int main() {int n 0x11223344;char *pc (char *)&n;*pc 0;return 0; } #include <stdio.h> int main() {i…

HCIP---MPLS---LDP

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 MPLS 基于标签转发表进行转发&#xff0c;与路由表类似&#xff0c;标签转发表有两种获取渠道&#xff1a;一是手动配置(类似静态路由)&#xff0c;二是通过协议自动学习(类似OSPF)。手动配…

npm相关和私有云

安装node时npm会自动安装&#xff0c;npm也可以单独安装。 package.json 在使用npm时&#xff0c;package.json文件是非常重要的&#xff0c;因为它包含了关于项目的必要信息&#xff0c;比如名称、版本、依赖项等。在初始化新项目时&#xff0c;通常会使用npm init命令生成一…

用 HLS 实现 UART

用 HLS 实现 UART 介绍 UART 是一种旧的串行通信机制&#xff0c;但仍在很多平台中使用。它在 HDL 语言中的实现并不棘手&#xff0c;可以被视为本科生的作业。在这里&#xff0c;我将通过这个例子来展示在 HLS 中实现它是多么容易和有趣。 因此&#xff0c;从概念上讲&#xf…

Android WMS—— Surace管理 (二十)

WMS 负责创建 Surface 以及对 Surface 的摆放工作,之后将 Surface 提交给SurfaceFlinger 进行合并。在 App 层也创建了一个 Surface 对象,但是那个是空对象,用于 WMS 的填充。 一、Surface的创建 首先 APP 层在 ViewRootImpl 的 relayoutWindow() 方法中发起创建任务。 1、…

【C/PTA】函数专项练习(三)

本文结合PTA专项练习带领读者掌握函数&#xff0c;刷题为主注释为辅&#xff0c;在代码中理解思路&#xff0c;其它不做过多叙述。 目录 6-1 使用函数输出指定范围内的完数6-2 递归实现指数函数6-3 十进制转换二进制6-4 空心的数字金字塔 6-1 使用函数输出指定范围内的完数 本…

阿里入局鸿蒙!鸿蒙原生应用再添两员新丁

今日HarmonyOS微博称&#xff0c;阿里钉钉、蚂蚁集团旗下的移动开发平台mPaaS与华为达成合作&#xff0c;宣布启动鸿蒙原生应用的开发&#xff01;相关应用将以原生方式适配#HarmonyOS NEXT#系统。 #HarmonyOS#市场或迎来爆发式增长&#xff01; 阿里钉钉 阿里钉钉与华为达成合…

微型计算机原理MOOC题

一、8254 1.掉坑了&#xff0c;AL传到端口不意味着一定传到的是低位&#xff0c;要看控制字D5和D4&#xff0c;10是只写高位&#xff0c;所以是0A00.。。 2. 3. 4.待解决&#xff1a;