我如何测量此 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();
但是这么简单的代码执行时间不太可能成为问题。您可能正在遭受错过的中断或中断处理的意外延迟。
我正在尝试调试自定义 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();
但是这么简单的代码执行时间不太可能成为问题。您可能正在遭受错过的中断或中断处理的意外延迟。