copy_to_user在char设备读取函数中返回一个错误
我为我的内核模块实现了一个char设备并为其实现了一个读取函数。读函数调用copy_to_user
将数据返回给调用者。我最初以阻塞的方式实现了读取功能(使用wait_event_interruptible
),但即使以非阻塞方式实现读取,问题也会再现。我的代码在MIPS处理器上运行。copy_to_user在char设备读取函数中返回一个错误
用户空间程序打开char设备并读入堆栈中分配的缓冲区。
我发现的是偶尔copy_to_user
将无法复制任何字节。此外,即使我用(仅用于检查......我知道这不是正确的做法)调用替换copy_to_user
,然后立即打印目标缓冲区,我看到memcpy
失败复制任何字节。
我真的不知道如何进一步调试 - 我如何确定为什么内存不被复制?流程上下文有可能是错误的吗?
编辑:下面是一些伪代码概述了代码目前的样子:
用户模式(重复运行):
char buf[BUF_LEN]; FILE *f = fopen(char_device_file, "rb");
fread(buf, 1, BUF_LEN, f);
fclose(f);
内核模式:
char_device = create_char_device(char_device_name,
NULL,
read_func,
NULL,
NULL);
int read_func(char *output_buffer, int output_buffer_length, loff_t *offset)
{
int rc;
if (*offset == 0)
{
spin_lock_irqsave(&lock, flags);
while (get_available_bytes_to_read() == 0)
{
spin_unlock_irqrestore(&lock, flags);
if (wait_event_interruptible(self->wait_queue, get_available_bytes_to_read() != 0))
{
// Got a signal; retry the read
return -ERESTARTSYS;
}
spin_lock_irqsave(&lock, flags);
}
rc = copy_to_user(output_buffer, internal_buffer, bytes_to_copy);
spin_unlock_irqrestore(&lock, flags);
}
else rc = 0;
return rc;
}
回答:
它进行了相当多的调试,但最终Tsyvarev的提示(关于不采用自旋锁调用copy_to_user
的评论)似乎是原因。
我们的程序有一个后台线程,偶尔会启动一个新进程(fork
+ exec
)。当我们禁用此线程时,一切运行良好。我们拥有的最好理论是,fork使我们所有的内存页面都可以在写入时进行复制,所以当我们试图复制它们时,内核必须做一些无法使用自旋锁执行的工作。希望它至少有一定意义(尽管我已经猜到这只适用于子进程,并且父进程页面仍然是可写的,但是谁知道......)。
我们重写了我们的代码,使其无法锁定,问题消失。
现在我们只需要验证我们的无锁代码在不同的架构上确实是安全的。易如反掌。
以上是 copy_to_user在char设备读取函数中返回一个错误 的全部内容, 来源链接: utcz.com/qa/261337.html