Reputation: 1869
If i have a piece of driver code likethis:
down_interruptible(&semA); //success
if(down_interruptible(&semB)) { //wait
return -ERESTARTSYS;
}
up(&semA);
up(&semB);
I have read that if driver code returns -ERESTARTSYS
, VFS layer may handle restarting the system call without user knowing about it. But, what about freeing resources like locks, memory etc..? should we undo them before returning -ERESTARTSYS
or kernel will handle that magically?
for ex: Does the above code should be look like?
down_interruptible(&semA); //success
if(down_interruptible(&semB)) { //wait
up(&semA);
return -ERESTARTSYS;
}
up(&semA);
up(&semB);
I am not sure usage of two semaphores like this is normal, but i have mentioned it to understand the concept. If possible please also point to me real code in linux kernel, where this kind of scenario is handled.
Upvotes: 1
Views: 297
Reputation: 180162
When you exit from a function (because of a signal, or because of any other error), you must release all locks you have taken, or you wouldn't be able to take them the next time. The same applies to any other temporary resources such as memory.
Please note that when you are using down_interruptible
, you must always check the return value, because otherwise you wouldn't know if you actually got the lock.
A common pattern of handling errors is to free resources in reverse order and to use a series of goto
statements, which allows you to combine the normal and error exit paths, which reduces bugs:
int my_function(...)
{
char *temp_buf;
int err;
err = -ENOMEM;
temp_buf = kmalloc(123, GFP_KERNEL);
if (!temp_buf)
goto err_exit;
err = -ERESTARTSYS;
if (down_interruptible(&semA))
goto err_free_temp;
if (down_interruptible(&semB))
goto err_unlock_A;
strcpy(temp_buf, "do the needful ...");
err = 0;
up(&semB);
err_unlock_A:
up(&semA);
err_free_temp:
free(temp_buf);
err_exit:
return err;
}
Upvotes: 4