1

我正在编写代码来记录 PCI 设备上发生的用户空间中的错误(内核已经将它们记录在内核环形缓冲区中)。目前,我面前有两种方法,

  1. 修改内核设备驱动程序以向我的用户空间进程发送中断(使用 eventfd),然后在收到此中断时(使用 select() 或 poll())我可以使用 ioctl 获取详细的错误信息(需要更改设备驱动程序)。这需要更改我想避免的内核代码。

  2. 我的进程以 root 身份运行,因此,我可以使用 sysfs 读取/写入设备的错误状态寄存器。为此,我将不得不不断地轮询寄存器,一旦发生错误,我可以读取状态寄存器,对其进行解码,获取详细的错误信息,然后清除寄存器。

我更倾向于第二种方法,因为它只需要在用户空间中进行更改。

我的问题是:

  1. 第二种方法是否有意义?
  2. 如果是这样,那么这两种方法的优缺点是什么?
  3. 第二种方法的轮询将导致 CPU 周期的浪费。在第一种方法中使用 select() 或 poll() 是否也会导致类似比例的 CPU 周期浪费。

非常感谢您的帮助!:)

4

2 回答 2

1
  1. 第二种方法是丑陋的可憎之物。在您的特定情况下是否有意义,只有您可以决定。

  2. 驱动程序的目的是封装和控制硬件访问。使用第二种方法,驱动程序和进程可能都需要知道对方可能会干扰设备。

    您说您“希望避免”更改内核代码。你不说为什么;这样做的原因可能是合理的,也可能不是。

  3. 如果驱动程序循环轮询设备,它将浪费 CPU。通过中断,CPU 可以休眠。

于 2013-10-25T08:17:33.000 回答
0

在恒定轮询模式下读/写状态寄存器不是一个好主意。检查读取状态寄存器的函数,因为这通常在关键部分完成,在这种情况下,在访问状态寄存器期间会有很多锁定/解锁,以及一次又一次的系统调用(软中断)的开销.

因此,驱动程序将异步事件发送到用户空间以解决错误条件的第一个想法是更好的方法。

于 2016-02-25T12:18:00.840 回答