本文调查这个问题的解决方案:如果我暴露一个设备的IO空间给用户态的程序,这个设备出了异常,我如何可以终止用户态的程序,不让它继续访问这个设备。
我发现设备异常,无论是设备自己报错,还是通过RAS系统报错,反映出来肯定是中断。所以我肯定是从中断开始做我的处理,这是基本假设。
发生异常后需要立即通知用户程序终止对设备的访问,我第一个考虑是用是kill_pid(pid, SIGXXX, 1),发一个信号给用户进程。但这是异步的,要等到用户程序被中断了,或者从系统调用中返回才会起作用。当我收到中断的时候,用户进程大可以正在工作在另一个核的用户态上,不会被打断。这时如果我回收设备的相关资源,肯定不妥。
第二种方法是把mmap的IO空间的页表给它回收了,但这个更危险,因为这要主动拿到这个进程的vma,然后在另一个CPU的上下文中操作它。这从锁的角度也很不安全,估计要改变不少内核的锁设计上的假设,不到万不得已,我们不考虑走这条路。
这些方法的问题是没法立即打断那个执行的进程,而很明显,要立即打断某个被执行的进程,唯一的手段是给它所在CPU发一个中断,比如发一个IPI。但收到一个中断,然后发起一个IPI,这个事情本身就是异步的。既然不能通过同步方式立即终止一个进程,快一点慢一点又有什么所谓?反正在(设备)异常发生的时候,用户进程怎么都得走几步的。
所以,这种情形需要做的设计是这样的:
首先硬件接口必须能保证,无论硬件发生什么异常,用户进程做任何硬件动作,最多没反应,但不能造成设备本身状态的异常。
其次,