我有一个Linux角色设备驱动程序,它创建一个/dev/mything
条目,然后是一个打开设备并使用它的C ++ / Qt程序。如果该程序正确退出,使用exit()
,设备将关闭,驱动程序将自行重置。但是,如果程序异常退出,通过段错误或SIGINT
或其他东西,则设备未正确关闭。
我目前的解决方法是在驱动程序陷入“打开”状态时重新加载驱动程序。
驱动程序中的这一行试图阻止多个程序同时使用该设备:
int mything_open( struct inode* inode, struct file* filp ) {
...
if ( port->rings[bufcount].virt_addr ) return -EBUSY;
...
}
然后清理它:
int mything_release( struct inode* inode, struct file* filp ) {
...
port->rings[bufcount].virt_addr = NULL;
...
}
我认为exit()
导致mything_release
被调用,但SIGINT
未被调用。如何在这种情况下让驱动程序更加强大?
编辑:
以下是我实施的操作。也许我错过了什么?
static struct file_operations fatpipe_fops = {
.owner = THIS_MODULE,
.open = mything_open,
.release = mything_release,
.read = mything_read,
.write = mything_write,
.ioctl = mything_ioctl
};
答案 0 :(得分:2)
没有必要进行这项测试;问题不在于程序终止异常(从驱动程序的角度来看,它与设备上的正常close
完全相同),而是在设备的状态保持方面存在问题。换句话说,如果您在程序崩溃的确切位置插入close(dev_fd)
甚至exit(0)
,则会遇到同样的问题。
你应该弄清楚你的驱动程序行为的哪个部分导致它保持繁忙状态并修复它。
答案 1 :(得分:1)
问题归结为mything_release
中的这一行,等待一些内存写入完成:
if (wait_event_interruptible_timeout(port->inq, false, 10)) return -ERESTARTSYS;
通过正常的程序退出,这将旋转10个jiffies并继续。但是由于SIGINT或其他东西的异常退出,我认为可中断的超时被中断并返回-ERESTARTSYS
,导致我的if返回相同的内容。
对我有用的事情就是摆脱if
并等待:
wait_event_interruptible_timeout(port->inq, false, 10);
多年前的这个补丁使我相信从close / _release函数返回ERESTARTSYS
并不是一个好主意:http://us.generation-nt.com/answer/patch-fix-wrong-error-code-interrupted-close-syscalls-help-181191441.html