Re: Blocked I/O in read() and mmap()
Why do you need to block in mmap()? mmap is supposed to create a mapping area in virtual address space for the process. Actual transfer happens later through page fault handlers on demand basis. look at vm_operations fault/readpage etc methods, these might be the places you want to wait for the data. On Wed, Feb 26, 2014 at 4:14 PM, Le Tan <tamlokveer@gmail.com> wrote:
So what should I do if I want the mmap() not to return right now? Is it strange to block in mmap() and few people will do this? Thanks for your help!
2014-02-27 4:45 GMT+08:00 Rajat Sharma <fs.rajat@gmail.com>:
It seems this task "landscape-sysin" is trying to peek into virtual memory of your processes and the process within mmap call is holding its mm->mmap_sem semaphore which grants access to its address space. landscape-sysin is trying to grab this semaphore to poke into address space of your mmap process address space. As from your description, it might be invoked everytime you are opening a new shell. Not sure why this process bother's about other process address space. Little googling shows this as relevant to your case:
http://www.techques.com/question/2-66765/Disable-usage-of-console-kit-daemon...
Your read process is innocent and not involved in this deadlock.
-Rajat
On Wed, Feb 26, 2014 at 4:13 AM, Le Tan <tamlokveer@gmail.com> wrote:
Hi, I am writing a driver module. Now I have some questions about
blocked
I/O. my_read() is the read function in the file_operations struct in my module. my_read() is just as simple as this: ssize_t my_read(....) { if(wait_event_interruptible(dev->queue, a == b)) return -ERESTARTSYS; return count; } Then I write a simple program to open and read the device. Obviously the program will be blocked. Now I still can open a new shell window and log in ( I use xshell).
However, then I implement my_mmap(), the mmap function in the file_operations struct in my module, like this: int my_mmap(....) { if(wait_event_interruptible(dev->queue, a == b)) return -ERESTARTSYS; return 0; } Then I write a simple program to open and mmap() the device. Obviously the program will be blocked again. However, when I open a new shell window in xshell and try to connect to the linux, it displays like this:
Connecting to 192.168.146.118:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]'.
And I can't log in! Then after a while, in the syslog, there is one message like this: [38306.614103] INFO: task landscape-sysin:17616 blocked for more than 120 seconds. [38306.614114] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [38306.614120] landscape-sysin D ffffffff8180fb60 0 17616 17609 0x00000000 [38306.614125] ffff88031d609c90 0000000000000082 ffff88032fffdb08 0000000000000000 [38306.614130] ffff8803130bdc40 ffff88031d609fd8 ffff88031d609fd8 ffff88031d609fd8 [38306.614133] ffff88062150c530 ffff8803130bdc40 0000004100000000 ffff8803130bdc40 [38306.614137] Call Trace: [38306.614147] [<ffffffff816b2c49>] schedule+0x29/0x70 [38306.614151] [<ffffffff816b3acd>] rwsem_down_read_failed+0x9d/0xf0 [38306.614157] [<ffffffff81341824>] call_rwsem_down_read_failed+0x14/0x30 [38306.614160] [<ffffffff816b1644>] ? down_read+0x24/0x2b [38306.614166] [<ffffffff81153661>] __access_remote_vm+0x41/0x1f0 [38306.614170] [<ffffffff81153ddb>] access_process_vm+0x5b/0x80 [38306.614175] [<ffffffff811ea423>] proc_pid_cmdline+0x93/0x120 [38306.614178] [<ffffffff811eb425>] proc_info_read+0xa5/0xf0 [38306.614182] [<ffffffff81186e84>] vfs_read+0xb4/0x180 [38306.614185] [<ffffffff81187102>] SyS_read+0x52/0xa0 [38306.614189] [<ffffffff816bc8c2>] system_call_fastpath+0x16/0x1b
If I terminate the program by force, then I can log in right now. So, are there any differences between the read and the mmap function to the wait_event_interruptible()? Why? If I want to block mmap() just like blocking read(), what should I do? Or it is impossible? Thanks!
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
OK, I will look into this. Is it OK to block vm_fault? I have another question. In my userspace program, I mmap() my device, then read something, then munmap() my device() and then mmap() my device again. The program do this in a loop. Everytime it mmap() the same address and offset. My device maintains a list of pages. In vm_operations fault, I just map the address to the head of the list. And in vm_operations close, I just delete the head from the list and free the page. Everything seems to be OK except that after I call the munmap() in the program, there is an error message. The error seems to happens between the call of vm_operations fault and vm_operations close. I have posted this question before ( See this<http://www.spinics.net/lists/newbies/msg51339.html>). [42522.596689] logger_mmap():start:7f8ff57be000, end:7f8ff57bf000 //this is the mmap() function of my device module [42522.596694] logger_vma_fault():vmf->pgoff:0d,start:7f8ff57be000,pgoff:0,offset:0 //this is the fault function of struct vm_operations_struct [42522.596729] BUG: Bad page map in process logger_pro pte:8000000612a30025 pmd:314175067 //this is the error [42522.596740] page:ffffea00184a8c00 count:2 mapcount:-2146959356 mapping: (null) index:0xffff880612a36000 [42522.596747] page flags: 0x200000000004080(slab|head) [42522.596811] addr:00007f8ff57be000 vm_flags:04040071 anon_vma: (null) mapping:ffff880613b25f08 index:0 [42522.596824] vma->vm_ops->fault: logger_vma_fault+0x0/0x140 [logger] [42522.596834] vma->vm_file->f_op->mmap: logger_mmap+0x0/0xd50 [logger] [42522.596842] CPU: 1 PID: 21571 Comm: logger_pro Tainted: G B IO 3.11.0+ #1 [42522.596844] Hardware name: Dell Inc. PowerEdge M610/000HYJ, BIOS 2.0.13 04/06/2010 [42522.596846] 00007f8ff57be000 ffff880314199c98 ffffffff816ad166 0000000000006959 [42522.596851] ffff880314539a98 ffff880314199ce8 ffffffff8114e270 ffffea00184a8c00 [42522.596854] 0000000000000000 ffff880314199cc8 00007f8ff57be000 ffff880314199e18 [42522.596858] Call Trace: [42522.596867] [<ffffffff816ad166>] dump_stack+0x46/0x58 [42522.596872] [<ffffffff8114e270>] print_bad_pte+0x190/0x250 [42522.596877] [<ffffffff8115027b>] unmap_single_vma+0x6cb/0x7a0 [42522.596880] [<ffffffff81150bd4>] unmap_vmas+0x54/0xa0 [42522.596885] [<ffffffff81155aa7>] unmap_region+0xa7/0x110 [42522.596888] [<ffffffff81157f97>] do_munmap+0x1f7/0x3e0 [42522.596891] [<ffffffff811581ce>] vm_munmap+0x4e/0x70 [42522.596904] [<ffffffff811591bb>] SyS_munmap+0x2b/0x40 [42522.596915] [<ffffffff816bc9c2>] system_call_fastpath+0x16/0x1b [42522.596920] logger_vma_close():start:7f8ff57be000, end:7f8ff57bf000, vmas:0 //this is the close function of struct vm_operations_struct So do you have any idea about this error? Thanks very much! 2014-02-27 9:04 GMT+08:00 Rajat Sharma <fs.rajat@gmail.com>:
Why do you need to block in mmap()? mmap is supposed to create a mapping area in virtual address space for the process. Actual transfer happens later through page fault handlers on demand basis. look at vm_operations fault/readpage etc methods, these might be the places you want to wait for the data.
On Wed, Feb 26, 2014 at 4:14 PM, Le Tan <tamlokveer@gmail.com> wrote:
So what should I do if I want the mmap() not to return right now? Is it strange to block in mmap() and few people will do this? Thanks for your help!
2014-02-27 4:45 GMT+08:00 Rajat Sharma <fs.rajat@gmail.com>:
It seems this task "landscape-sysin" is trying to peek into virtual memory of your processes and the process within mmap call is holding its mm->mmap_sem semaphore which grants access to its address space. landscape-sysin is trying to grab this semaphore to poke into address space of your mmap process address space. As from your description, it might be invoked everytime you are opening a new shell. Not sure why this process bother's about other process address space. Little googling shows this as relevant to your case:
http://www.techques.com/question/2-66765/Disable-usage-of-console-kit-daemon...
Your read process is innocent and not involved in this deadlock.
-Rajat
On Wed, Feb 26, 2014 at 4:13 AM, Le Tan <tamlokveer@gmail.com> wrote:
Hi, I am writing a driver module. Now I have some questions about
blocked
I/O. my_read() is the read function in the file_operations struct in my module. my_read() is just as simple as this: ssize_t my_read(....) { if(wait_event_interruptible(dev->queue, a == b)) return -ERESTARTSYS; return count; } Then I write a simple program to open and read the device. Obviously the program will be blocked. Now I still can open a new shell window and log in ( I use xshell).
However, then I implement my_mmap(), the mmap function in the file_operations struct in my module, like this: int my_mmap(....) { if(wait_event_interruptible(dev->queue, a == b)) return -ERESTARTSYS; return 0; } Then I write a simple program to open and mmap() the device. Obviously the program will be blocked again. However, when I open a new shell window in xshell and try to connect to the linux, it displays like this:
Connecting to 192.168.146.118:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]'.
And I can't log in! Then after a while, in the syslog, there is one message like this: [38306.614103] INFO: task landscape-sysin:17616 blocked for more than 120 seconds. [38306.614114] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [38306.614120] landscape-sysin D ffffffff8180fb60 0 17616 17609 0x00000000 [38306.614125] ffff88031d609c90 0000000000000082 ffff88032fffdb08 0000000000000000 [38306.614130] ffff8803130bdc40 ffff88031d609fd8 ffff88031d609fd8 ffff88031d609fd8 [38306.614133] ffff88062150c530 ffff8803130bdc40 0000004100000000 ffff8803130bdc40 [38306.614137] Call Trace: [38306.614147] [<ffffffff816b2c49>] schedule+0x29/0x70 [38306.614151] [<ffffffff816b3acd>] rwsem_down_read_failed+0x9d/0xf0 [38306.614157] [<ffffffff81341824>] call_rwsem_down_read_failed+0x14/0x30 [38306.614160] [<ffffffff816b1644>] ? down_read+0x24/0x2b [38306.614166] [<ffffffff81153661>] __access_remote_vm+0x41/0x1f0 [38306.614170] [<ffffffff81153ddb>] access_process_vm+0x5b/0x80 [38306.614175] [<ffffffff811ea423>] proc_pid_cmdline+0x93/0x120 [38306.614178] [<ffffffff811eb425>] proc_info_read+0xa5/0xf0 [38306.614182] [<ffffffff81186e84>] vfs_read+0xb4/0x180 [38306.614185] [<ffffffff81187102>] SyS_read+0x52/0xa0 [38306.614189] [<ffffffff816bc8c2>] system_call_fastpath+0x16/0x1b
If I terminate the program by force, then I can log in right now. So, are there any differences between the read and the mmap function to the wait_event_interruptible()? Why? If I want to block mmap() just like blocking read(), what should I do? Or it is impossible? Thanks!
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Check for two things: 1. Handle error from mmap() call in user space, it seems munmap is called unconditionally. while(1) { str = mmap(vma); //always map the same address and offset (they are set to zero), logger will handle this fwrite(str, 4096, fd); munmap(str); } 2. Debug more why logger_vma_fault is failing? Is there a window where you might have buffer list empty while you arrange for new page? -Rajat On Wed, Feb 26, 2014 at 5:31 PM, Le Tan <tamlokveer@gmail.com> wrote:
OK, I will look into this. Is it OK to block vm_fault? I have another question. In my userspace program, I mmap() my device, then read something, then munmap() my device() and then mmap() my device again. The program do this in a loop. Everytime it mmap() the same address and offset. My device maintains a list of pages. In vm_operations fault, I just map the address to the head of the list. And in vm_operations close, I just delete the head from the list and free the page. Everything seems to be OK except that after I call the munmap() in the program, there is an error message. The error seems to happens between the call of vm_operations fault and vm_operations close. I have posted this question before ( See this<http://www.spinics.net/lists/newbies/msg51339.html>).
[42522.596689] logger_mmap():start:7f8ff57be000, end:7f8ff57bf000 //this is the mmap() function of my device module [42522.596694] logger_vma_fault():vmf->pgoff:0d,start:7f8ff57be000,pgoff:0,offset:0 //this is the fault function of struct vm_operations_struct [42522.596729] BUG: Bad page map in process logger_pro pte:8000000612a30025 pmd:314175067 //this is the error [42522.596740] page:ffffea00184a8c00 count:2 mapcount:-2146959356 mapping: (null) index:0xffff880612a36000 [42522.596747] page flags: 0x200000000004080(slab|head) [42522.596811] addr:00007f8ff57be000 vm_flags:04040071 anon_vma: (null) mapping:ffff880613b25f08 index:0 [42522.596824] vma->vm_ops->fault: logger_vma_fault+0x0/0x140 [logger] [42522.596834] vma->vm_file->f_op->mmap: logger_mmap+0x0/0xd50 [logger] [42522.596842] CPU: 1 PID: 21571 Comm: logger_pro Tainted: G B IO 3.11.0+ #1 [42522.596844] Hardware name: Dell Inc. PowerEdge M610/000HYJ, BIOS 2.0.13 04/06/2010 [42522.596846] 00007f8ff57be000 ffff880314199c98 ffffffff816ad166 0000000000006959 [42522.596851] ffff880314539a98 ffff880314199ce8 ffffffff8114e270 ffffea00184a8c00 [42522.596854] 0000000000000000 ffff880314199cc8 00007f8ff57be000 ffff880314199e18 [42522.596858] Call Trace: [42522.596867] [<ffffffff816ad166>] dump_stack+0x46/0x58 [42522.596872] [<ffffffff8114e270>] print_bad_pte+0x190/0x250 [42522.596877] [<ffffffff8115027b>] unmap_single_vma+0x6cb/0x7a0 [42522.596880] [<ffffffff81150bd4>] unmap_vmas+0x54/0xa0 [42522.596885] [<ffffffff81155aa7>] unmap_region+0xa7/0x110 [42522.596888] [<ffffffff81157f97>] do_munmap+0x1f7/0x3e0 [42522.596891] [<ffffffff811581ce>] vm_munmap+0x4e/0x70 [42522.596904] [<ffffffff811591bb>] SyS_munmap+0x2b/0x40 [42522.596915] [<ffffffff816bc9c2>] system_call_fastpath+0x16/0x1b [42522.596920] logger_vma_close():start:7f8ff57be000, end:7f8ff57bf000, vmas:0 //this is the close function of struct vm_operations_struct
So do you have any idea about this error? Thanks very much!
2014-02-27 9:04 GMT+08:00 Rajat Sharma <fs.rajat@gmail.com>:
Why do you need to block in mmap()? mmap is supposed to create a mapping
area in virtual address space for the process. Actual transfer happens later through page fault handlers on demand basis. look at vm_operations fault/readpage etc methods, these might be the places you want to wait for the data.
On Wed, Feb 26, 2014 at 4:14 PM, Le Tan <tamlokveer@gmail.com> wrote:
So what should I do if I want the mmap() not to return right now? Is it strange to block in mmap() and few people will do this? Thanks for your help!
2014-02-27 4:45 GMT+08:00 Rajat Sharma <fs.rajat@gmail.com>:
It seems this task "landscape-sysin" is trying to peek into virtual memory of your processes and the process within mmap call is holding its mm->mmap_sem semaphore which grants access to its address space. landscape-sysin is trying to grab this semaphore to poke into address space of your mmap process address space. As from your description, it might be invoked everytime you are opening a new shell. Not sure why this process bother's about other process address space. Little googling shows this as relevant to your case:
http://www.techques.com/question/2-66765/Disable-usage-of-console-kit-daemon...
Your read process is innocent and not involved in this deadlock.
-Rajat
On Wed, Feb 26, 2014 at 4:13 AM, Le Tan <tamlokveer@gmail.com> wrote:
Hi, I am writing a driver module. Now I have some questions about
blocked
I/O. my_read() is the read function in the file_operations struct in my module. my_read() is just as simple as this: ssize_t my_read(....) { if(wait_event_interruptible(dev->queue, a == b)) return -ERESTARTSYS; return count; } Then I write a simple program to open and read the device. Obviously the program will be blocked. Now I still can open a new shell window and log in ( I use xshell).
However, then I implement my_mmap(), the mmap function in the file_operations struct in my module, like this: int my_mmap(....) { if(wait_event_interruptible(dev->queue, a == b)) return -ERESTARTSYS; return 0; } Then I write a simple program to open and mmap() the device. Obviously the program will be blocked again. However, when I open a new shell window in xshell and try to connect to the linux, it displays like this:
Connecting to 192.168.146.118:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]'.
And I can't log in! Then after a while, in the syslog, there is one message like this: [38306.614103] INFO: task landscape-sysin:17616 blocked for more than 120 seconds. [38306.614114] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [38306.614120] landscape-sysin D ffffffff8180fb60 0 17616 17609 0x00000000 [38306.614125] ffff88031d609c90 0000000000000082 ffff88032fffdb08 0000000000000000 [38306.614130] ffff8803130bdc40 ffff88031d609fd8 ffff88031d609fd8 ffff88031d609fd8 [38306.614133] ffff88062150c530 ffff8803130bdc40 0000004100000000 ffff8803130bdc40 [38306.614137] Call Trace: [38306.614147] [<ffffffff816b2c49>] schedule+0x29/0x70 [38306.614151] [<ffffffff816b3acd>] rwsem_down_read_failed+0x9d/0xf0 [38306.614157] [<ffffffff81341824>] call_rwsem_down_read_failed+0x14/0x30 [38306.614160] [<ffffffff816b1644>] ? down_read+0x24/0x2b [38306.614166] [<ffffffff81153661>] __access_remote_vm+0x41/0x1f0 [38306.614170] [<ffffffff81153ddb>] access_process_vm+0x5b/0x80 [38306.614175] [<ffffffff811ea423>] proc_pid_cmdline+0x93/0x120 [38306.614178] [<ffffffff811eb425>] proc_info_read+0xa5/0xf0 [38306.614182] [<ffffffff81186e84>] vfs_read+0xb4/0x180 [38306.614185] [<ffffffff81187102>] SyS_read+0x52/0xa0 [38306.614189] [<ffffffff816bc8c2>] system_call_fastpath+0x16/0x1b
If I terminate the program by force, then I can log in right now. So, are there any differences between the read and the mmap function to the wait_event_interruptible()? Why? If I want to block mmap() just like blocking read(), what should I do? Or it is impossible? Thanks!
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
participants (2)
-
Le Tan -
Rajat Sharma