我如何测量此 Linux 中断处理程序需要多长时间才能 运行?

How can I measure how long this Linux interrupt handler takes to run?

我正在尝试调试自定义 Linux 串行驱动程序,该驱动程序存在一些问题,缺少一些接收数据。它有一个中断用于 4 个串口,波特率为 115200。首先我想看看如何测量中断处理程序需要多长时间。我使用过 perf,但事情只是以百分比而不是秒为单位。其次,有没有人发现以下代码有任何问题可以改进以加快速度?

 void serial_interrupt(int irq, void *dev_id)
{
    ...

  // Need to loop through each port to see which port caused the interrupt.
  list_for_each(lpNode, &serial_ports)
  {
    struct serial_port_module *ser_dev = list_entry(lpNode, struct serial_port_module, port_list);

    lnIsr = ioread8(ser_dev->membase + ser_dev->chan_num * PORT_OFFSET + SERIAL_ISR);

     if (lnIsr & IPM512_RX_INT)
      {
        while (serialdata_is_data_available(ser_dev)) // equals a ioread8()
        {
          lcIn = ioread8(ser_dev->membase + ser_dev->chan_num * PORT_OFFSET + SERIAL_RBR);

          kfifo_in(&ser_dev->rx_fifo, &lcIn, sizeof(lcIn));

          // Notify if anyone is doing a blocking read.
          wake_up_interruptible(&ser_dev->read_queue);
        }
      }
    }
  }

使用 ftrace API 尝试追踪您的延迟问题。值得花时间了解一下:https://www.kernel.org/doc/Documentation/trace/ftrace.txt

如果这太重量级了,自己添加一些简单的检测怎么样? getnstimeofday(struct timespec *ts) 相对轻量级...只需少量代码,您就可以在 sysfs 调试文件中输出最坏情况下的执行时间、有关调用此函数的延迟的一些统计信息、最坏情况下每个中断可用的字节数…… .如果这个数字接近你的硬件 FIFO 大小,你就有麻烦了。

一种优化方法是将数据分批读取到缓冲区中,只要数据可用,然后输入整个缓冲区,然后唤醒任何读取器。

while(data_available(dev))
{
  buf[cnt++] = ioread8();
}
kfifo_in(fifo, buf, cnt);
wake_up_interruptible();

但是这么简单的代码执行时间不太可能成为问题。您可能正在遭受错过的中断或中断处理的意外延迟。