How to implement a driver's read and write operations with synchronization properly
Hi everyone, I'm trying to write a misc char driver with read and write operations, and I choose reader writer lock for synchronization between them. Suppose that when writing 2000 bytes, the write operation is called twice, each time writing only 1000 bytes. There are 2 ways to implement synchronization as below: 1. Acquire and release lock everytime the write operation is called. Same with read operation. 2. Acquire the lock when the write operation is called for the first time, and release when the whole write procedure is completed. In this case, the lock is acquired before transfering the 1st byte, and released after transfering the 2000th byte. Same with read operation. As how I see it, both of these approaches have problems. The first one release the lock in between the write operations, so a reader can get in while the writer has only finished a portion of its work. With the second approach, I have no way to tell that the write procedure ends with the 2000th byte. What if there are more? Could anyone tell me the proper way to deal with this situation? Thanks in advance. -- Le Quoc Anh
On Tue, Jul 29, 2014 at 03:03:55PM +0700, Anh Le wrote:
Hi everyone, I'm trying to write a misc char driver with read and write operations, and I choose reader writer lock for synchronization between them. Suppose that when writing 2000 bytes, the write operation is called twice, each time writing only 1000 bytes. There are 2 ways to implement synchronization as below:
Which "write operation" is called twice in your scenario?
1. Acquire and release lock everytime the write operation is called. Same with read operation. 2. Acquire the lock when the write operation is called for the first time, and release when the whole write procedure is completed. In this case, the lock is acquired before transfering the 1st byte, and released after transfering the 2000th byte. Same with read operation.
If a userspace program writes 1000 bytes at first, how can you know that it wants to perform another write later on?
As how I see it, both of these approaches have problems. The first one release the lock in between the write operations, so a reader can get in while the writer has only finished a portion of its work.
If a userspace program wants to write a chunk of data atomically, it should use just one call to write(2). (On Linux, one can save some copying by using writev(2), which writes data from multiple buffers in one atomic step.)
With the second approach, I have no way to tell that the write procedure ends with the 2000th byte. What if there are more?
Again, where does this write procedure run? Greetings, Jonathan Neuschäfer
Could anyone tell me the proper way to deal with this situation? Thanks in advance.
-- Le Quoc Anh
On 29-Jul-2014 1:34 PM, "Anh Le" <anhlq2110@gmail.com> wrote:
Hi everyone, I'm trying to write a misc char driver with read and write operations, and I choose reader writer lock for synchronization between them. Suppose that when writing 2000 bytes, the write operation is called twice, each time writing only 1000 bytes. There are 2 ways to implement synchronization as below:
Your application is doing 2 writes as I understand. So let's say if only your process is the only one writing do you need locking?
1. Acquire and release lock everytime the write operation is called. Same with read operation. 2. Acquire the lock when the write operation is called for the first time, and release when the whole write procedure is completed. In this case, the lock is acquired before transfering the 1st byte, and released after transfering the 2000th byte. Same with read operation.
How about doing page flipping here? Your locking will be for shorter duration for reads. See your read/write as one operation no matter how many bytes. You are synchronizing for different processes.
As how I see it, both of these approaches have problems. The first one release the lock in between the write operations, so a reader can get in while the writer has only finished a portion of its work. With the second approach, I have no way to tell that the write procedure ends
One read / write thats it. You make promise at kernel level that you wont give false data on reads and wont allow parallel write op. Thats all. How applications honor who goes first is upto them. Say 4 processes writing on same file no synchronization at user space level is gonna screw data even when you made a good enough promise that write op wont be in parallel. The syncing is at 2 places not only kernel.
with the 2000th byte. What if there are more?
Could anyone tell me the proper way to deal with this situation? Thanks in advance.
Just make a good enough promise that data reads would be valid and that writes wont be screwed up. If applications are not good citizens then kernel cant do anything except keep its own promises.
-- Le Quoc Anh
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
participants (3)
-
Anh Le -
Jonathan Neuschäfer -
Pranay Srivastava