Re: How to implement a driver's read and write operations with synchronization properly
Thanks, Jonathan, for the quick reply. On Tue, Jul 29, 2014 at 3:36 PM, Jonathan Neuschäfer <j.neuschaefer@gmx.net> wrote:
Which "write operation" is called twice in your scenario?
It's the "write" method of the "struct file_operations" structure. I define it like this (no synchronizatin yet): static ssize_t sample_write(struct file *f, const char __user *buf, size_t len, loff_t *ppos) { printk(KERN_DEBUG "[sample] buf len: %u, *ppos: %u\n", len, *ppos); return simple_write_to_buffer(kbuf, 2048, ppos, buf, len); }
If a userspace program writes 1000 bytes at first, how can you know that it wants to perform another write later on?
I use printk to debug the module. More details in the answer below.
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.)
I tried the following command: echo $(perl -e "print 'a'x2000") > /dev/sample and get the following messages from dmesg: [30884.066433] [sample] buf len: 1008, *ppos: 0 [30884.066451] [sample] buf len: 993, *ppos: 1008 So as I understand my 2001 bytes has been split into 2 chunks, the first one with 1008 bytes and the second one with 993 bytes, and therefore the write operation is called 2 times to consume the whole input. -- Le Quoc Anh
On 29-Jul-2014 5:54 PM, "Anh Le" <anhlq2110@gmail.com> wrote:
Thanks, Jonathan, for the quick reply.
On Tue, Jul 29, 2014 at 3:36 PM, Jonathan Neuschäfer <j.neuschaefer@gmx.net> wrote:
Which "write operation" is called twice in your scenario?
It's the "write" method of the "struct file_operations" structure. I define it like this (no synchronizatin yet): static ssize_t sample_write(struct file *f, const char __user *buf, size_t len, loff_t *ppos) { printk(KERN_DEBUG "[sample] buf len: %u, *ppos: %u\n", len,
*ppos);
return simple_write_to_buffer(kbuf, 2048, ppos, buf, len); }
If a userspace program writes 1000 bytes at first, how can you know that it wants to perform another write later on?
I use printk to debug the module. More details in the answer below.
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.)
I tried the following command: echo $(perl -e "print 'a'x2000") >
/dev/sample
and get the following messages from dmesg: [30884.066433] [sample] buf len: 1008, *ppos: 0 [30884.066451] [sample] buf len: 993, *ppos: 1008
So as I understand my 2001 bytes has been split into 2 chunks, the
Who do you think did this split? I would say write a simple program and do only a single write syscall for your buffer size. Just see if that split happens again.
first one with 1008 bytes and the second one with 993 bytes, and therefore the write operation is called 2 times to consume the whole input.
-- Le Quoc Anh
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Tue, Jul 29, 2014 at 07:15:08PM +0700, Anh Le wrote: [...]
I tried the following command: echo $(perl -e "print 'a'x2000") > /dev/sample and get the following messages from dmesg: [30884.066433] [sample] buf len: 1008, *ppos: 0 [30884.066451] [sample] buf len: 993, *ppos: 1008
So as I understand my 2001 bytes has been split into 2 chunks, the first one with 1008 bytes and the second one with 993 bytes, and therefore the write operation is called 2 times to consume the whole input.
I've tried this out myself, and it seems to be an issue with bash: $ cat /tmp/aaaa.sh #!/bin/sh echo aaaaaaa...[trimmed to fit in an e-mail]...aaaaaaa $ strace -e trace=write /tmp/aaaa.sh > /dev/null write(1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 2001) = 2001 +++ exited with 0 +++ $ strace -e trace=write bash /tmp/aaaa.sh > /dev/null write(1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 1008) = 1008 write(1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 993) = 993 +++ exited with 0 +++ [ My default shell, /bin/sh, is Debian's dash. ] As you can see, I observed the same pattern of 1008 and 993 bytes. Greetings, Jonathan Neuschäfer
participants (3)
-
Anh Le -
Jonathan Neuschäfer -
Pranay Srivastava