Linux 打开SMP时判断当前进程是否正在运行

Linux 打开SMP时判断当前进程是否正在运行,linux,linux-kernel,kernel,Linux,Linux Kernel,Kernel,我发现内核中有一个名为task\u的函数正在运行,其判断逻辑如下 static inline int task_current(struct rq*rq,struct task_struct*p) { 返回rq->curr==p; } 正在运行的静态内联int任务(struct rq*rq,struct task\u struct*p) { #ifdef配置\u SMP 在cpu上返回p->; #否则 返回任务_当前(rq,p); #恩迪夫 } cpu上的rq->curr和p->之间有什么区别

我发现内核中有一个名为
task\u的函数正在运行
,其判断逻辑如下

static inline int task_current(struct rq*rq,struct task_struct*p)
{
返回rq->curr==p;
}
正在运行的静态内联int任务(struct rq*rq,struct task\u struct*p)
{
#ifdef配置\u SMP
在cpu上返回p->;
#否则
返回任务_当前(rq,p);
#恩迪夫
}

cpu上的
rq->curr
p->之间有什么区别吗?我认为它们都意味着进程是由当前的cpu调度的。为什么SMP下需要单独的判断?

在多处理器系统(
CONFIG\u SMP
)上,调度程序通常需要连续获取并释放自旋锁
p->pi\u锁
(对于任务即
struct task\u struct
)和
rq->lock
(对于运行队列即
struct rq
)。由于锁争用是多处理器系统减速的主要因素之一,因此添加了
task\u struct
on\u cpu
字段,以避免获取
rq->lock
查看
rq->curr

在单处理器系统(no
CONFIG_SMP
)上,只有一个CPU和一个runqueue,并且在检查正在运行的任务时不需要获取runqueue锁。由于调度程序无论如何都不会执行任何锁定,因此我们还可以避免在
任务结构
中的
on\u cpu
字段中使用该字段,从而节省一些内存,并转储处理该字段的所有代码。事实上,如果您查看
struct task\u struct
的代码,您可以看到:

struct任务\u结构{
/* ... */
#ifdef配置\u SMP
cpu上的int;
/* ... */
#恩迪夫
/* ... */
}

下面是实现此优化的示例。Peter Zijlstra的一部分工作是减少调度程序中的锁争用(扩展“相关”字段以列出所有内容)。

cpu=1上的
是否意味着
rq->curr
被锁定?我不知道我是否理解right@user14102520否,
on_cpu=1
表示任务当前正在运行(即,它“在cpu上”)。这只是一种比
spin\u lock(rq->lock)更快的检查方法;勾选rq->curr==p;旋转解锁(rq->锁定)
。为什么会出现这样的情况,cpu=0上的
p->但是
rq->curr=p
@user14102520是谁说的?你在哪里看到的?对不起,因为我正在做进程迁移实验。当我使用
rq->curr
直接判断时,会导致系统异常,但在cpu上使用
p->on\u-cpu
不会导致问题,所以我认为
p->on\u-cpu=0
会出现
rq->curr=p