c - 通过直接在函数处理程序中使用写入函数的用户空间缓冲区来节省内存(Linux,内核)?

标签 c linux memory memory-management kernel

我有一个 Linux 文件系统,其中包含以下函数的实现:

 ssize_t (*write) (struct file *file, const char __user *buffer, size_t count, loff_t *pos);

现在假设我想使用缓冲区的数据来计算奇偶校验(在函数处理内)。 我可以使用

copy_from_user(void *to, const void __user *from, unsigned long n)

但问题是我需要首先为我的内核空间指针分配内存。我要复制的数据量是最大。大约 7.5 MB,最小。 512KB。如果我使用 kmalloc 在内核中分配内存,它可能会失败,而且我什至无法在内存池前面分配足够的内存,因为不知何故它也会失败......

那么:如果我在代码中使用用户空间的指针会发生什么?

...
     *(dest) ^= *(buf);
...

到目前为止,它似乎有效(尽管对于较小的内存区域)。 我不知道内存映射是如何工作的。用户空间内存可能不连续吗?还可以换掉吗?有什么危险?谢谢!

最佳答案

在任何情况下都不应该直接使用用户空间内存。

如果您的任务可以表示为用户数据的流处理,则无需分配内核内存来一次容纳整个用户数据。

分配较小大小的内存(例如 4KB)就足够了,将第一个用户数据 block 读入其中(使用copy_from_user),处理它,将下一个 block 读入相同的内核内存,处理它等等:

void* dest = kmalloc(4096, GFP_KERNEL); // or use __get_free_pages()
while(count > 0)
{
    int size = count >= 4096? 4096: count;
    copy_from_user(dest, buffer, size);
    <process-data-in-dest>
    count -= size;
    buffer += size;
}

关于c - 通过直接在函数处理程序中使用写入函数的用户空间缓冲区来节省内存(Linux,内核)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37446759/

相关文章:

c - 如何为网格中的所有标签添加 css 样式上下文提供程序?

带粗细绘制算法的圆

linux - awk 找到第一个匹配项,而不是所有匹配项

c - 是否可以通过用户编程来控制页出和页入?如果是的话怎么办?

c - 在我的 c 代码中删除重复项时出现错误

c - gentoo ld.gold 在 sys-libs/db 上失败

linux - 屏幕截图命令行工具的最快图像捕获

java - 将java路径永久设置为linux中的最新版本

c# - 私有(private)方法和属性与公共(public)方法和属性在 C#(和其他语言)中的内存占用

用 C 生成的 CRC 查找表总是给出不同的结果