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

回到顶部