AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 419449
Accepted
Kenny
Kenny
Asked: 2018-01-25 12:29:09 +0800 CST2018-01-25 12:29:09 +0800 CST 2018-01-25 12:29:09 +0800 CST

如何确定延迟是由驱动程序还是调度程序引起的?

  • 772

使用示波器并切换一些引脚,我有时会看到从传输 8 字节 UART 数据包到阻塞读取返回时的 1-2 秒延迟。数据包是 1 秒部分,有几毫秒的抖动。我还测量了系统调用的时间(见下文)strace,结果与我的 I/O 测量结果一致。

我正在尝试确定此延迟是否存在于 UART 驱动程序中,或者是否其他任务正在影响我的任务,该任务的 niceness 值为 -20。我想知道驱动程序的原因是该代码的早期版本可靠地使用 UART 传输每秒约 26 kB 的数据包(驱动程序缓冲区为 4 kB)。

该过程是一个 Python 脚本,它使用pyserial. 在这种失败的情况下strace,报告介于epoll_wait和之间的时间clock_gettime超过 3 秒。

0.000883 epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=8589934599}}) = -1 EEXIST (File exists)
0.000681 clock_gettime(CLOCK_MONOTONIC, {92406, 209555006}) = 0
0.000655 epoll_wait(3, {}, 64, 98) = 0
3.004082 clock_gettime(CLOCK_MONOTONIC, {92409, 214251206}) = 0

重复动作为: 接收 8 字节数据包,请求 Linux 通过 SPI 读取 N 个字节。执行 SPI。读取 8 字节数据包以查看 SPI 请求是否成功完成。SPI 传输大约需要 40 毫秒。请求数据包和结果数据包之间的健康模式约为 40 ms。大约 960 毫秒,直到它收到下一个请求。

Duchess: strace -r -e read -p 7564
Process 7564 attached
     0.000000 read(7, "\355\336\255\336\20d\0\0", 8) = 8
     0.049142 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
     0.950381 read(7, "\355\336\255\336\20d\0\0", 8) = 8
     0.050035 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
     0.949962 read(7, "\355\336\255\336\20d\0\0", 8) = 8
     0.049601 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
     0.950417 read(7, "\355\336\255\336\20d\0\0", 8) = 8
     0.049654 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
     0.950507 read(7, "\355\336\255\336\20d\0\0", 8) = 80.950516 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
     0.049944 read(7, "\255\336\355\336\1\0\0\0", 8) = 8 [Success]
     2.196903 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
     0.048876 read(7, "\255\336\355\336\0\0\0\0", 8) = 8 [Failure]
     0.015570 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
     0.053889 read(7, "\255\336\355\336\0\0\0\0", 8) = 8 [Failure]
     0.634720 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
     0.050070 read(7, "\255\336\355\336\1\0\0\0", 8) = 8 [Success]
strace uart
  • 1 1 个回答
  • 525 Views

1 个回答

  • Voted
  1. Best Answer
    thrig
    2018-01-27T12:31:59+08:002018-01-27T12:31:59+08:00

    strace不太可能为您提供必要的详细信息;您可能需要 SystemTap、sysdig 或类似的内核级调试来更好地显示发生了什么。例如,安装了 SystemTap 并处理了所有必要的调试信息和设置细节,可以从以下开始:

    probe begin
    {
            printf("%-16s %s\n", "TIME", "WHAT");
    }
    
    probe tty.{ioctl,receive}
    {
            if (pid() != target()) next;
            printf("%d ttyx    %s\n", gettimeofday_us(), name);
    }
    
    probe tty.poll
    {
            if (pid() != target()) next;
            printf("%d ttypoll %s\n", gettimeofday_us(), file_name);
    }
    
    probe tty.{read,write}
    {
            if (pid() != target()) next;
            printf("%d ttyio   %s %d\n", gettimeofday_us(), file_name, nr);
    }
    
    probe syscall.{read,write,epoll_*}
    {
            if (pid() != target()) next;
            printf("%d syscall %s\tenter\n", gettimeofday_us(), name);
    }
    
    probe syscall.{read,write,epoll_*}.return
    {
            if (pid() != target()) next;
            printf("%d syscall %s\treturn\n", gettimeofday_us(), name);
    }
    

    并通过

    $ sudo stap -x "$(pidof ...)" filecontainingtheabovecode.stp
    

    对于我的串行测试程序和附加的 Arduino显示:

    TIME             WHAT
    1516997916648359 syscall read   enter
    1516997916648366 ttyio   ttyACM0 4096
    1516997916652456 syscall read   return
    1516997916652465 syscall read   enter
    1516997916652470 ttyio   ttyACM0 4096
    1516997916656459 syscall read   return
    1516997916656497 syscall write  enter
    1516997916656503 ttyio   4 21
    1516997916656511 syscall write  return
    ...
    

    如果上面没有显示延迟的位置,您可能还需要查阅 SystemTap Tapsets 文档以了解其他感兴趣的探测点(调度程序、I/O 调度程序、IRQ?)。并且可能将时间与旧版本的代码/驱动程序/系统进行比较......

    • 2

相关问题

  • 可以使用 getauxval 来确定您是否被追踪吗?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve