カーネル バージョン 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はプロセスでspin_lockとspin_unlockを呼び出していないので、 task_lockとtask_unlockを使用しています。
- files_fdtableはspin_lockとspin_unlockを呼び出しているので、私はしません。
- fcheck_filesはspin_lockとspin_unlockも呼び出しているので、私はしません。
- d_pathはロックするように気をつけているので、私はしません。
私のコードがマシンをフリーズさせている理由と、それを修正する方法を教えてください。