Linux kernel 轮询用户空间中设备的控制寄存器以检查错误

Linux kernel 轮询用户空间中设备的控制寄存器以检查错误,linux-kernel,kernel,linux-device-driver,pci,sysfs,Linux Kernel,Kernel,Linux Device Driver,Pci,Sysfs,我正在编写代码来记录PCI设备上发生的用户空间错误(内核已经将它们记录在内核环缓冲区中)。目前,我面前有两种方法 修改内核设备驱动程序以向我的用户空间进程发送中断(使用eventfd),然后在收到此中断(使用select()或poll())后,我可以使用ioctl获取详细的错误信息(需要更改设备驱动程序)。这需要对内核代码进行更改,我希望避免这样做 我的进程以根用户身份运行,因此,我可以使用sysfs读取/写入设备的错误状态寄存器。为此,我必须不断轮询寄存器,一旦发生错误,我可以读取状态寄存器,

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

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

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

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

    我的问题是:

  • 第二种方法有意义吗
  • 如果是这样,那么这两种方法的优缺点是什么
  • 第二种方法中的轮询将导致CPU周期的浪费。在第一种方法中使用select()或poll()是否也会导致CPU周期以类似的比例浪费
  • 非常感谢您的回复!:)

  • 第二种方法是令人憎恶的。 这在你的特殊情况下是否有意义只有你自己能决定

  • 封装和控制硬件访问是驱动程序的职责。 对于第二种方法,驱动程序和进程可能都需要知道另一个可能会干扰设备

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

  • 如果驱动程序在循环中轮询设备,则会浪费CPU。 有了中断,CPU就可以休眠了

  • 第二种方法是令人憎恶的。 这在你的特殊情况下是否有意义只有你自己能决定

  • 封装和控制硬件访问是驱动程序的职责。 对于第二种方法,驱动程序和进程可能都需要知道另一个可能会干扰设备

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

  • 如果驱动程序在循环中轮询设备,则会浪费CPU。 有了中断,CPU就可以休眠了


  • 在恒定轮询模式下读/写状态寄存器不是一个好主意。检查您读取状态寄存器的功能,因为这通常是在关键部分完成的,在这种情况下,在访问状态寄存器的过程中会有太多的锁定/解锁,并且还会一次又一次地增加系统调用(softirq)的开销


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

    在恒定轮询模式下读取/写入状态寄存器不是一个好主意。检查您读取状态寄存器的功能,因为这通常是在关键部分完成的,在这种情况下,在访问状态寄存器的过程中会有太多的锁定/解锁,并且还会一次又一次地增加系统调用(softirq)的开销

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