关于在写linux driver时的ERESTARTSYS的作用

作用:
-ERESTARTSYS的与“可重新执行的系统调用”的概念相关联,一个可重新执行的系统调用是一个当有一些中断发生后能透明的被kernel重新执行的系统调用。
比如用户空间进程在执行一个系统调用时产生休眠,此时捕获到一个信号,执行信号处理函数,然后当从信号处理函数返回,表现为重新执行之前的那个系统调用进入睡眠状态。
使用sigaction 系统API,进程能够安排与信号相关的重新执行行为。这些都是POSIX所规定的。可以看看APUE中的sigaction函数说明。
在linux kernel中,当一个驱动或其它模块阻塞在一个系统调用的上下文中,探测到一个task己经被一个信号唤醒,它会返回-EINTR。但-EINTR将向上冒泡般传递到用户空间,并导致这个系统调用返回-1,errno被设置为EINTR。
如果你返回-ERESTARTSYS代替-EINTR,那么它意味着你的系统调用是可以重新启动的。ERESTARTSYS将不是必须在用户空间被感觉到,有两种表现形式,一种是在用户空间这个返回被翻译为一个-1的返回值,并且errno被设为EINTR(这时,很显然是被用户空间感觉到),另一种是被kernel透明的重新执行,使用之前执行这个系统调用时的参数,(没有在用户空间处理的部分:kernel隐藏所有信息)。

这里大家也许己经有疑问了,相同的参数,这不会出问题吗?的确,在某些系统调用中,这的确是会出问题的,比如:你执行系统调用nanosleep, 睡眠5.3秒,结果睡了5秒后,被 一个信号中断了,当信号处理结束返回时,就不能简单的继续执行nanosleep睡5.3秒,这时应该睡0.3秒,也就是说,这个参数需要改变。有一个方法做这个:你修改一个不同的参数在task的restart block上,然后用ERESTART_RESTARTBLOCK做返回值。


Consider the following:

Global variable :

wait_queue_head_t my_wait_q_head;
int read_avail = 0;

device_init() :

init_waitqueue_head(&my_wait_q_head);


device_read():

printk("I'm inside driver read!\n");
wait_event_interruptible(&my_wait_q_head, read_avail != 0);
printk("I'm awaken!\n");

device_write():

read_avail = 1;
wake_up_interruptible(&my_wait_q_head);

When I call the read() from user space, the command prompt hang until I call the write() as expected. The printk messages appear accordingly as well in dmesg. However, I'm seeing some of the drivers written like this :

Another version of device_read():

printk("I'm inside driver read!\n");
if(wait_event_interruptible(&my_wait_q_head, read_avail != 0))    
{return -ERESTARTSYS;}
printk("I'm awaken!\n");
I tested the second version of device_read() using the same method in user space, and the result is exactly the same, so, what's the use of ERESTARTSYS?

回答:
what's the difference? Why not just write the read routine without checking the return value and returning -ERESTARTSYS? Well, because that is incorrect in the case that the wakeup is due to a signal! Do you want a read to return 0 bytes read whenever a signal arrives? That could be misinterpreted by user space as end of data. This kind of problem won't show up in test cases that don't use signals.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值