Есть ли способ, которым я могу использовать планирование сроков и в то же время установить привязку процессора к процессу в 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
Это происходит, даже если я в Судо.
Есть ли проблемы с моим кодом? Почему я не могу использовать 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 с конкретным ядром?