What does ERESTARTSYS used while writing linux driver?

放肆的年华 提交于 2019-11-30 01:30:00

-ERESTARTSYS is connected to the concept of a restartable system call. A restartable system call is one that can be transparently re-executed by the kernel when there is some interruption.

For instance the user space process which is sleeping in a system call can get a signal, execute a handler, and then when the handler returns, it appears to go back into the kernel and keeps sleeping on the original system call.

Using the POSIX sigaction API's SA_RESTART flag, processes can arrange the restart behavior associated with signals.

In the Linux kernel, when a driver or other module blocking in the context of a system call detects that a task has been woken because of a signal, it can return -EINTR. But -EINTR will bubble up to user space and cause the system call to return -1 with errno set to EINTR.

If you return -ERESTARTSYS instead, it means that your system call is restartable. The ERESTARTSYS code will not necessarily be seen in user space. It either gets translated to a -1 return and errno set to EINTR (then, obviously, seen in user space), or it is translated into a system call restart behavior, which means that your syscall is called again with the same arguments (by no action on part of the user space process: the kernel does this by stashing the info in a special restart block).

Note the obvious problem with "same arguments" in the previous paragraph: some system calls can't be restarted with the same parameters, because they are not idempotent! For instance, suppose there is a sleep call like nanosleep, for 5.3 seconds. It gets interrupted after 5 seconds. If it restarts naively, it will sleep for another 5.3 seconds. It has to pass new parameters to the restarted call to sleep for only the remaining 0.3 seconds; i.e. alter the contents of the restart block. There is a way to do that: you stuff different arguments into the task's restart block and use the -ERESTART_RESTARTBLOCK return value.

To address the second question: 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!