Linux 可重启系统调用的实现

Linux 可重启系统调用的实现,linux,linux-kernel,linux-device-driver,Linux,Linux Kernel,Linux Device Driver,如果我有这样一段驱动程序代码: down_interruptible(&semA); //success if(down_interruptible(&semB)) { //wait return -ERESTARTSYS; } up(&semA); up(&semB); 我已经读到,如果驱动程序代码返回-ERESTARTSYS,VFS层可能会在用户不知道的情况下重新启动系统调用。但是,释放锁、内存等资源怎么样。。?我们应该在返回-ERESTARTSYS之

如果我有这样一段驱动程序代码:

down_interruptible(&semA); //success
if(down_interruptible(&semB)) { //wait
   return -ERESTARTSYS;
}
up(&semA);
up(&semB);
我已经读到,如果驱动程序代码返回
-ERESTARTSYS
,VFS层可能会在用户不知道的情况下重新启动系统调用。但是,释放锁、内存等资源怎么样。。?我们应该在返回
-ERESTARTSYS
之前撤销它们,还是内核会神奇地处理它们

例如:上面的代码应该是什么样子

down_interruptible(&semA); //success
if(down_interruptible(&semB)) { //wait
   up(&semA);
   return -ERESTARTSYS;
}
up(&semA);
up(&semB);
我不确定这样使用两个信号量是否正常,但我提到它是为了理解这个概念。
如果可能的话,还请指出linux内核中的真实代码,在这里处理这种情况。

当您退出某个函数时(由于信号或任何其他错误),您必须释放已获取的所有锁,否则下次将无法获取它们。 这同样适用于任何其他临时资源,如内存

请注意,当您使用
down\u interruptible
时,必须始终检查返回值,否则您将无法知道是否实际获得了锁


处理错误的一种常见模式是以相反的顺序释放资源,并使用一系列的
goto
语句,这允许您组合正常路径和错误退出路径,从而减少错误:

int my_函数(…)
{
char*temp_buf;
INTERR;
err=-ENOMEM;
temp_buf=kmalloc(123,GFP_内核);
如果(!temp_buf)
转到错误退出;
err=-ERESTARTSYS;
if(向下可中断(&semA))
转到无错误温度;
if(向下可中断(&semB))
转到错误解锁;
strcpy(temp_buf,“做需要的…”);
误差=0;
up(小型企业和中小企业);
错误\u解锁\u A:
up&semA;
无错误温度:
免费(临时);
错误退出:
返回错误;
}

当您退出某个功能时(由于信号或任何其他错误),您必须释放所有已锁定的锁,否则下次将无法锁定。 这同样适用于任何其他临时资源,如内存

请注意,当您使用
down\u interruptible
时,必须始终检查返回值,否则您将无法知道是否实际获得了锁


处理错误的一种常见模式是以相反的顺序释放资源,并使用一系列的
goto
语句,这允许您组合正常路径和错误退出路径,从而减少错误:

int my_函数(…)
{
char*temp_buf;
INTERR;
err=-ENOMEM;
temp_buf=kmalloc(123,GFP_内核);
如果(!temp_buf)
转到错误退出;
err=-ERESTARTSYS;
if(向下可中断(&semA))
转到无错误温度;
if(向下可中断(&semB))
转到错误解锁;
strcpy(temp_buf,“做需要的…”);
误差=0;
up(小型企业和中小企业);
错误\u解锁\u A:
up&semA;
无错误温度:
免费(临时);
错误退出:
返回错误;
}
以及CL-answer,我不确定这样使用两个信号量是否正常。这是不正常的,;这是坏习惯。一个互斥只能用于一种工作类型;像这样锁定重复的互斥锁可能会导致这种情况非常罕见,并且非常难以诊断。尽你所能避免这种情况。例如,其他人先锁定B,然后锁定A。以及CL应答,我不确定这样使用两个信号量是否正常。这是不正常的,;这是坏习惯。一个互斥只能用于一种工作类型;像这样锁定重复的互斥锁可能会导致这种情况非常罕见,并且非常难以诊断。尽你所能避免这种情况。例如,其他人先锁定B,然后锁定A。