我正在创建一个内核模块来查找所有进程的常驻页面

时间:2015-05-25 09:52:50

标签: linux process linux-kernel

我正在创建一个内核模块来查找所有进程的驻留页面。我正在使用get_mm_rss()和for_each_process但它可以正常工作 仅对于init进程/第一次迭代后的第一次它不起作用。

int __init schedp(void){
    struct task_struct *p;

    for_each_process(p) {
        int pid = task_pid_nr(p);
        printk("Process: %s (pid = %d) , (rpages : %lu)\n", 
                p->comm, pid, get_mm_rss(p->mm)); 
    } 
    return 0;
} 

结果:

BUG: unable to handle kernel NULL pointer dereference at 00000160,

2 个答案:

答案 0 :(得分:0)

您可能会在NULL中获得p->mm,因为某些任务可能包含无效mm指针,因为它们正在退出或没有mm(因为它们是for_each_process(p) { struct task_struct *t; /* * Main thread might exit, but other threads may still have * a valid mm. Find one. */ t = find_lock_task_mm(p); if (!t) continue; cpumask_clear_cpu(cpu, mm_cpumask(t->mm)); task_unlock(t); } 内核线程,不确定)。

当您对如何使用内核API感到困惑时,请始终在内核中查找示例。使用交叉引用工具快速搜索给了我kernel/cpu.c

find_lock_task_mm()

请注意,您需要致电task_unlock()NULL并明确核对{{1}}。

答案 1 :(得分:0)

最后它在创建一个检查mm_struct是否有效的函数后起作用for_each_process

struct task_struct *task_mm(struct task_struct *p){
struct task_struct *t;
rcu_read_lock();
for_each_thread(p, t) {
task_lock(t);
if (likely(t->mm))
goto found;
task_unlock(t);
}
t = NULL;
found:
rcu_read_unlock();
return t;
}