我们之前介绍过简单的read,write操作,那么会有一个问题:当驱动无法立即响应请求该怎么办?比如一个进程调用read读取数据,当没有数据可读时该怎么办,是立即返回还是等到有数据的时候;另一种情况是进程调用write向设备写数据,如果缓冲区满了或者设备正忙的时候怎么办,是立即返回还是继续等待直到设备可写?这种情况下,一般的缺省做法是使进程睡眠直到请求可以满足为止。本篇就介绍遇到这类问题驱动的处理方法。
睡眠
什么是睡眠?一个进程睡眠意味着它暂时放弃了CPU的运行权,直到某个条件发生后才可再次被系统调度。
在驱动里面很容易使一个进程进入睡眠状态,但是这里有几个规则需要特别注意。
- 原子上下文不能睡眠。这意味着驱动在持有一个自旋锁, seqlock, 或者 RCU 锁时不能睡眠。
- 关闭中断的情况下不能睡眠。在中断处理函数中不能睡眠。
- 在持有信号量时可以睡眠,但是会造成其他等待的进程也会进入睡眠,所以应该特别注意,睡眠时间应很短。
- 在被唤醒后应做一些必要的检查,确定你等待的条件已经满足。因为你不知道睡眠的这段时间发生了什么。
- 睡眠前确定能被唤醒,否则不要睡眠。
如何睡眠和唤醒
睡眠的进程会进入等待队列,一个等待队列可以如下声明:
DECLARE_WAIT_QUEUE_HEAD(name);
或者动态地, 如下:
wait_queue_head_t my_queue;
init_waitqueue_head(&my_queue);
当一个进程需要睡眠,可以调用下面的接口: