模块中tasklist_lock的替代方案?

时间:2012-01-30 22:26:51

标签: linux linux-kernel

出于学习目的,我想迭代完成所有任务 在模块中输出有关它们的不同信息。为了这个任务 我需要锁定所有任务的列表(我也不确定是否应该这样做。)。我见过一些例子 在内核代码中锁定tasklist_lock。不过这个符号 不能被模块使用。它的出口被删除了 c59923a15c12d2b3597af913bf234a0ef264a38b commit。

还有其他方法可以锁定任务列表吗?

2 个答案:

答案 0 :(得分:1)

您可以按如下方式使用stop_machine():

int for_each_task(void * data)
{
  struct task_struct * g, * p;
  do_each_thread(g, p) {
    // do the work
  } while_each_thread(g, p);
  return 0;
}

...
stop_machine(for_each_task, NULL, NULL);
...

stop_machine接口挂起所有任务,并在每个CPU上放置高优先级线程。因此,在回调中没有安排其他任务。

答案 1 :(得分:1)

stop_machine()引入空闲线程并禁用每个系统CPU中的中断,除了执行作为stop_machine()参数传递的用户定义函数的中断。这相当于在内核中保存每个自旋锁,并且只要用户定义的函数运行就会导致系统冻结。毋庸置疑,它对性能影响很大,但也提供了强大的一致性保证。

如果您只想从系统的任务中读取数据并且不介意绝对精确性(一致性),则可以在read-copy-update (RCU)关键部分中迭代进程的记帐列表。您还可以查看RCU in Wikipedia

struct task_struct *iter;
rcu_read_lock();
list_for_each_entry_rcu(iter, &init_task.tasks, tasks) {
   printf("The current task of the list is: %s\n.", iter->comm);
}
rcu_read_unlock();