c - Linux 内核模块在迭代正在运行的进程以访问进程打开的文件时卡住计算机

标签 c module linux-kernel

我正在使用内核版本 3.x 开发内核模块。

我有一个函数负责确定正在运行的进程是否打开了给定文件。

这是我的代码(见我之后的评论):

struct task_struct *    process = NULL;
struct files_struct *   task_files = NULL;
struct fdtable *        fdt = NULL;
int                     fd_i;
char                    tmpbuf[256];
char *                  process_path = "";

for_each_process(process)
{
    // Ignore processes without files
    if (process->files == NULL)
        continue;

    printk(KERN_INFO "task_lock()...\n");
    task_lock(process);
    printk(KERN_INFO "task_lock() DONE\n");
    task_files = process->files;
    printk(KERN_INFO "task_unlock()...\n");
    task_unlock(process);
    printk(KERN_INFO "task_unlock() DONE\n");

    printk(KERN_INFO "files_fdtable()...\n");
    fdt = files_fdtable(task_files);
    printk(KERN_INFO "files_fdtable() DONE\n");

    printk(KERN_INFO "Iterating files...\n");
    for (fd_i = 0; fd_i < fdt->max_fds; fd_i++)
    {
        if (fcheck_files(task_files, fd_i) == my_file)
        {
            if (process->mm)
            {
                if (process->mm->exe_file)
                {

                    process_path = d_path(&process->mm->exe_file->f_path, tmpbuf, sizeof(tmpbuf));
                    break;
                } else {
                    printk(KERN_INFO "process->mm->exe_file is NULL\n");
                }
            } else {
                printk(KERN_INFO "process->mm is NULL\n");
            }
        }
    }
    printk(KERN_INFO "Files iteration finished\n");
}

此代码有效,变量 process_path 包含打开给定文件的进程的路径。 但是当机器上有巨大的负载时(所以经常通过这段代码),机器卡住(在一定时间后)并且最新打印的调试是:

task_unlock() DONE

然后我就看不出我做错了什么。

能否请您解释一下为什么我的代码会卡住机器以及如何修复它?

最佳答案

您设计模块的方式会导致系统卡住。请注意,您使用了 for_each_process(),这意味着它将遍历系统的每个进程。因此,当您对系统施加负载时,进程数会变大。此外,在 for_each_process() 循环中,您正在调用 task_lock/unlock() 并尝试对进程进行各种操作,所有这些操作都很昂贵,因为它们都有自己的锁。当系统负载较低时,它们并不明显,但随着系统负载越来越多,模块运行时的复杂性会增加,但在低负载时仍然不太明显。我建议使用 ftrace 之类的功能来检测您的模块,同时避免过度使用 printk(因为还需要安排 printk,为此目的使用 klogd)。并在低负载下检查您的模块如何在内核中运行。测量它在每个循环上花费了多少时间,你就会了解自己。内核是一个大野兽,里面发生了很多事情......

关于c - Linux 内核模块在迭代正在运行的进程以访问进程打开的文件时卡住计算机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16507448/

相关文章:

c - C语言中for(;1;)是什么意思?

c - 如何解决 printf 中的 %d 输出显示 num1、num2 和 sum 的 ascii 值,而不是它们分配的值

python - python 导入顺序如何影响名称?

javascript - 从不同模块访问模块数据

linux - 中断描述符表 (IDT) 修改

linux - 2.6 内核中的 EXPORT_SYMTAB

c++ - 如果我有相同的函数名,但一个是 C++,另一个是 C,如何区分 C++ 中的函数名

c - 为什么当我写入套接字时它可能是 "bad file number"

Python:在模块和类之间共享全局变量

linux - 在 Linux 内核中检测无限循环的简单方法