Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux device driver file operations: it is possible to have race conditions?

Consider a linux device driver that implements the open(), read(), write(), close(), unlocked_ioctl() and, maybe, mmap().

Now, imagine that multiple (or the same) processes open the same device (/dev/device) concurrently.

Are those file operations guaranteed in any way to be atomic w.r.t. to each other or should each of the open(), read(), write(), close() take a mutex so that one of their pairs doesn't preempt them while in the middle of changing, for example, a buffer data (through the same inode)?

It should not be necessary if the kernel guarantee their atomicity with respect to each other and if each operation finds and leave the buffer/hardware in a consistent state.

Please, redirect me towards some reference (if you know).

Thank you.

edit: it is in one of the comments, but the best reference that I found is here:

http://www.makelinux.net/ldd3/chp-6-sect-6

It also show strategies to alleviate the problem, either by restricting to a single user, either by creating copies, either by forcing the user to wait etc.

like image 947
user1284631 Avatar asked Oct 03 '22 22:10

user1284631


1 Answers

Device driver code runs in the process which invoked the system calls. The kernel does not have an implicit "module lock" it locks before invoking module code. It is definitely possible for concurrent driver calls to happen when separate processes invoke system calls that end up in your driver code.

As you might expect, the kernel favors simplicity and performance over ease of implementation. It is up to you to grab the necessary spinlocks and semaphores when accessing shared state.

See Chapter 5 of Linux Device Drivers, which talks about concurrency and race conditions in great detail.

Concurrency and Its Management

In a modern Linux system, there are numerous sources of concurrency and, therefore, possible race conditions. Multiple user-space processes are running, and they can access your code in surprising combinations of ways. SMP systems can be executing your code simultaneously on different processors. Kernel code is preemptible; your driver’s code can lose the processor at any time, and the process that replaces it could also be running in your driver. Device interrupts are asynchronous events that can cause concurrent execution of your code. The kernel also provides various mechanisms for delayed code execution, such as workqueues, tasklets, and timers, which can cause your code to run at any time in ways unrelated to what the current process is doing. In the modern, hot-pluggable world, your device could simply disappear while you are in the middle of working with it.

like image 75
John Kugelman Avatar answered Oct 20 '22 00:10

John Kugelman