Blocked I/O in read() and mmap()

Le Tan tamlokveer at gmail.com
Wed Feb 26 07:13:23 EST 2014


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!



More information about the Kernelnewbies mailing list