在内核中使用读写锁死锁
deadlock using read write lock in kernel
我正在尝试编写一个具有读写文件操作的简单调试文件。代码如下
static ssize_t foo_read(struct file *fp, char __user *user,
size_t size, loff_t *loff)
{
ssize_t retval;
up_read(&foo_sem);
retval = simple_read_from_buffer(user, size, loff, fooBuffer,
fooBufferSize);
down_read(&foo_sem);
return retval;
}
static ssize_t foo_write(struct file *fp, const char __user *data,
size_t size, loff_t *loff)
{
ssize_t retval;
pr_debug("foo Write Funcion data %s=,size=%zu\n", data, size);
up_write(&foo_sem);
retval = simple_write_to_buffer(fooBuffer, sizeof(fooBuffer)-1, loff,
data, size);
if (retval > 0) {
fooBufferSize = size + *loff;
fooBuffer[fooBufferSize] = '[=10=]';
}
down_write(&foo_sem);
return retval;
}
并且读写锁初始化为
static DECLARE_RWSEM(foo_sem);
当我编译代码并且 运行 没有锁时它工作正常。
然而,当我 运行 锁定时,程序似乎被调度程序杀死。
[ 8640.104388] INFO: task a.out:6387 blocked for more than 120 seconds.
[ 8640.104398] Tainted: G OE 3.17.0-rc5+ #1
[ 8640.104402] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 8640.104407] a.out D ffff88007fc14580 0 6387 1 0x00000004
[ 8640.104415] ffff880075497df0 0000000000000002 ffff88007a0e9900 ffff880075497fd8
[ 8640.104422] 0000000000014580 0000000000014580 ffffffff81c1d480 ffff88007a0e9900
[ 8640.104428] ffff88007a0e9900 ffffffffa013b018 ffffffffa013b000 ffffffff00000000
[ 8640.104434] Call Trace:
[ 8640.104450] [<ffffffff8174a8a9>] schedule+0x29/0x70
[ 8640.104460] [<ffffffff8174d62d>] rwsem_down_write_failed+0x1ed/0x390
[ 8640.104472] [<ffffffff81381d03>] call_rwsem_down_write_failed+0x13/0x20
[ 8640.104482] [<ffffffff8174cf7d>] ? down_write+0x2d/0x40
[ 8640.104492] [<ffffffffa013906e>] foo_write+0x6e/0xa0 [firstmodule]
[ 8640.104503] [<ffffffff811d42f7>] vfs_write+0xb7/0x1f0
[ 8640.104513] [<ffffffff811d4e96>] SyS_write+0x46/0xb0
[ 8640.104523] [<ffffffff8174f47f>] tracesys+0xe1/0xe6
您正在颠倒使用 up
和 down
操作。当您想访问资源时调用 down
,然后在完成访问后调用 up
。
例如:
down_read(&foo_sem);
retval = simple_read_from_buffer(user, size, loff, fooBuffer,
fooBufferSize);
up_read(&foo_sem);
我正在尝试编写一个具有读写文件操作的简单调试文件。代码如下
static ssize_t foo_read(struct file *fp, char __user *user,
size_t size, loff_t *loff)
{
ssize_t retval;
up_read(&foo_sem);
retval = simple_read_from_buffer(user, size, loff, fooBuffer,
fooBufferSize);
down_read(&foo_sem);
return retval;
}
static ssize_t foo_write(struct file *fp, const char __user *data,
size_t size, loff_t *loff)
{
ssize_t retval;
pr_debug("foo Write Funcion data %s=,size=%zu\n", data, size);
up_write(&foo_sem);
retval = simple_write_to_buffer(fooBuffer, sizeof(fooBuffer)-1, loff,
data, size);
if (retval > 0) {
fooBufferSize = size + *loff;
fooBuffer[fooBufferSize] = '[=10=]';
}
down_write(&foo_sem);
return retval;
}
并且读写锁初始化为
static DECLARE_RWSEM(foo_sem);
当我编译代码并且 运行 没有锁时它工作正常。
然而,当我 运行 锁定时,程序似乎被调度程序杀死。
[ 8640.104388] INFO: task a.out:6387 blocked for more than 120 seconds.
[ 8640.104398] Tainted: G OE 3.17.0-rc5+ #1
[ 8640.104402] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 8640.104407] a.out D ffff88007fc14580 0 6387 1 0x00000004
[ 8640.104415] ffff880075497df0 0000000000000002 ffff88007a0e9900 ffff880075497fd8
[ 8640.104422] 0000000000014580 0000000000014580 ffffffff81c1d480 ffff88007a0e9900
[ 8640.104428] ffff88007a0e9900 ffffffffa013b018 ffffffffa013b000 ffffffff00000000
[ 8640.104434] Call Trace:
[ 8640.104450] [<ffffffff8174a8a9>] schedule+0x29/0x70
[ 8640.104460] [<ffffffff8174d62d>] rwsem_down_write_failed+0x1ed/0x390
[ 8640.104472] [<ffffffff81381d03>] call_rwsem_down_write_failed+0x13/0x20
[ 8640.104482] [<ffffffff8174cf7d>] ? down_write+0x2d/0x40
[ 8640.104492] [<ffffffffa013906e>] foo_write+0x6e/0xa0 [firstmodule]
[ 8640.104503] [<ffffffff811d42f7>] vfs_write+0xb7/0x1f0
[ 8640.104513] [<ffffffff811d4e96>] SyS_write+0x46/0xb0
[ 8640.104523] [<ffffffff8174f47f>] tracesys+0xe1/0xe6
您正在颠倒使用 up
和 down
操作。当您想访问资源时调用 down
,然后在完成访问后调用 up
。
例如:
down_read(&foo_sem);
retval = simple_read_from_buffer(user, size, loff, fooBuffer,
fooBufferSize);
up_read(&foo_sem);