gpt4 book ai didi

linux - SCHED_DEADLINE 的 sched_setaffinity()

转载 作者:太空宇宙 更新时间:2023-11-04 12:07:26 24 4
gpt4 key购买 nike

有没有一种方法可以在使用截止时间调度的同时将 cpu 亲和性设置为 linux 中的进程?我正在运行 4.16 内核。下面是我的测试代码:

#define _GNU_SOURCE
#include "include/my_sched.h"
#include <stdio.h>
#include <time.h>
#include <sys/time.h>

int main() {
struct sched_attr attr;
int x = 0;
int ret;
unsigned int flags = 0;
long int tid = gettid();

printf("deadline thread started [%ld]\n", tid);

/* Set scheduling properties */
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;

/* This creates a 100ms/300ms reservation */
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 100 * 1000 * 1000;
attr.sched_period = attr.sched_deadline = 300 * 1000 * 1000;

ret = sched_setattr(0, &attr, flags);
if (ret != 0) {
done = 0;
perror("sched_setattr");
printf("exit!\n");
exit(-1);
}

/* Set CPU affinity */
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
ret = sched_setaffinity(0, sizeof(mask), &mask);

if (ret != 0) {
done = 0;
perror("sched_setaffinity");
printf("exit!\n");
exit(-1);
}


return 0;
}

即使我编译上面的程序并在 sudo 中运行它,我也得到了错误:

sched_setaffinity: Device or resource busy

如果我交换 sched_setattr() 和 sched_setaffinity() 的顺序,我会得到一个不同的错误:

sched_setattr: Operation not permitted

即使我在 sudo 中也会发生这种情况。

我的代码有问题吗?为什么我不能在同一个程序中使用 sched_setaffinity() 和 sched_setattr() 进行截止时间安排?

对于任何有兴趣编译和试用该程序的人,下面是 my_include.h 的代码:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <linux/unistd.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <sys/syscall.h>
#include <pthread.h>

#define gettid() syscall(__NR_gettid)

#define SCHED_DEADLINE 6

/* XXX use the proper syscall numbers */
#ifdef __x86_64__
#define __NR_sched_setattr 314
#define __NR_sched_getattr 315
#endif

#ifdef __i386__
#define __NR_sched_setattr 351
#define __NR_sched_getattr 352
#endif

#ifdef __arm__
#define __NR_sched_setattr 380
#define __NR_sched_getattr 381
#endif

static volatile int done;

struct sched_attr {
__u32 size;

__u32 sched_policy;
__u64 sched_flags;

/* SCHED_NORMAL, SCHED_BATCH */
__s32 sched_nice;

/* SCHED_FIFO, SCHED_RR */
__u32 sched_priority;

/* SCHED_DEADLINE (nsec) */
__u64 sched_runtime;
__u64 sched_deadline;
__u64 sched_period;
};

int sched_setattr(pid_t pid,
const struct sched_attr *attr,
unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}

int sched_getattr(pid_t pid,
struct sched_attr *attr,
unsigned int size,
unsigned int flags)
{
return syscall(__NR_sched_getattr, pid, attr, size, flags);
}

我做了什么:

我试图深入研究执行相应健全性检查的内核代码。以下代码片段来自kernel/sched/core.c:

/*
* Don't allow tasks with an affinity mask smaller than
* the entire root_domain to become SCHED_DEADLINE. We
* will also fail if there's no bandwidth available.
*/
if (!cpumask_subset(span, &p->cpus_allowed) ||
rq->rd->dl_bw.bw == 0) {
task_rq_unlock(rq, p, &rf);
return -EPERM;
}

...

/*
* Since bandwidth control happens on root_domain basis,
* if admission test is enabled, we only admit -deadline
* tasks allowed to run on all the CPUs in the task's
* root_domain.
*/
#ifdef CONFIG_SMP
if (task_has_dl_policy(p) && dl_bandwidth_enabled()) {
rcu_read_lock();
if (!cpumask_subset(task_rq(p)->rd->span, new_mask)) {
retval = -EBUSY;
rcu_read_unlock();
goto out_free_new_mask;
}
rcu_read_unlock();
}

以上两节对应我之前提到的那两个错误。任何人都可以向我解释评论是什么意思吗?我知道什么是调度域和根域,但我看不出 SCHED_DEADLINE 任务在调度域方面与其他调度策略有何不同?为什么将 SCHED_DEADLINE 任务绑定(bind)到特定核心没有意义?

最佳答案

经过一些挖掘,我终于很好地理解了为什么设置关联会导致 SCHED_DEADLINE 调度程序出现问题。

对于只想将 EDF 任务绑定(bind)到核心子集的任何人,您可以引用 https://elixir.bootlin.com/linux/v4.17-rc3/source/Documentation/scheduler/sched-deadline.txt#L634 ,第 5 节。您可以使用 cpuset 和 cgroup 实用程序将核心分配给 EDF 任务。

不允许对 SCHED_DEADLINE 任务使用 sched_setaffinity() 是确保在 linux 内核中进行有效的可调度性测试的保守方法。考虑以下场景,其中机器有 9 个核心,任务 1 希望与核心 1、2、4、5 有关联,任务 2 希望与核心 3、4、5、6、7、8 有关联。

enter image description here

事实证明,如果不同 SCHED_DEADLINE 任务的亲和掩码部分重叠,可调度性测试将成为 NP 难题。因此,没有有效的方法来确定任务集是否可调度。任意核心亲和性的最先进的可调度性测试需要指数级的计算复杂度。向这种可调度性测试添加功能将大大降低内核的性能。

但是,我认为从内核的角度来看,这是一种实现可调度性的保守方法。这是因为如果 linux 管理员知道他在做什么,他可以有意地将所有 SCHED_DEADLINE 任务映射到特定的核心子集。在以下示例中,我们可以将核心 1、2、4、5 专用于 EDF 任务。效果与使用 cpuset 方法没有什么不同。无论如何,sched_setaffinity() 能够模拟全局、集群和分区的作业级固定优先级调度。

enter image description here

引用:

Gujarati, A.、Cerqueira, F. 和 Brandenburg, B.B.(2014 年)。具有任意处理器亲和性的多处理器实时调度:从实践到理论。实时系统,51, 440-483。

关于linux - SCHED_DEADLINE 的 sched_setaffinity(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50165719/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com