gpt4 book ai didi

copy_to_user 在字符设备读取函数中返回错误

转载 作者:行者123 更新时间:2023-11-30 16:37:31 29 4
gpt4 key购买 nike

我已经为我的内核模块实现了一个字符设备,并为其实现了一个读取函数。读取函数调用copy_to_user将数据返回给调用者。我最初以阻塞方式实现读取功能(使用 wait_event_interruptible),但即使我以非阻塞方式实现读取,问题也会重现。我的代码在 MIPS 处理器上运行。

用户空间程序打开字符设备并读入堆栈上分配的缓冲区。

我发现有时copy_to_user无法复制任何字节。此外,即使我将 copy_to_user 替换为对 memcpy 的调用(仅用于检查......我知道这不是正确的做法),并且之后立即打印出目标缓冲区,我发现 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 在字符设备读取函数中返回错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47863483/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com