Использует ли политика SCHED_FIFO в полностью вытесняемом ядре Linux приоритет kthread? - PullRequest
0 голосов
/ 12 марта 2019

Я собрал ядро ​​Linux с примененным исправлением RT.Он скомпилирован правильно, я вижу набор политик планировщика

CONFIG_PREEMPT_RT_FULL=y

ядро ​​говорит, что это PREEMPT RT:

debian@beaglebone:~$ uname -a
Linux beaglebone 4.14.94-ti-rt-r93 #2 SMP PREEMPT RT Mon Mar 11 12:09:49 MSK 2019 armv7l GNU/Linux

Чтобы проверить это, я использую BeagleBone Black и простой самодельный модуль ядра, который просто порождает2 потока ядра с разными приоритетами.

// ...
struct sched_param paramL = { .sched_priority = MAX_RT_PRIO - 20 };
struct sched_param paramH = { .sched_priority = MAX_RT_PRIO - 10 };
// ...
adev->high_thread = kthread_create(
    high_work_thread, adev, "high_pr_thread");
ret = sched_setscheduler(adev->high_thread, SCHED_FIFO, &paramH);

if (ret) {
    dev_warn(&adev->pdev->dev, "High priority rejected!\n");
}

adev->low_thread = kthread_create(
    low_work_thread, adev, "low_pr_thread");

ret = sched_setscheduler(adev->low_thread, SCHED_FIFO, &paramL);

if (ret) {
    dev_warn(&adev->pdev->dev, "Low priority rejected!\n");
}
wake_up_process(adev->high_thread);
wake_up_process(adev->low_thread);

Каждый поток переключает свой GPIO.Поток с высоким приоритетом (делает 100000 переключений, затем спит) * 5 раз

/* HIGH PRIO */
int i, j;
struct plng_arinc_device * adev = data;

for(j = 0; j != 5; j++) {
    for(i = 0; i != 100000; i++) {
        FLIP(high_val);
        gpiod_set_value(adev->gpioHIGH, high_val);
    }
    msleep(15);
}

Поток с низким приоритетом просто непрерывно переключает свой PIN-код 1000000 раз

/* LOW PRIO */
int i;
struct plng_arinc_device * adev = data;

for(i = 0; i != 1000000; i++) {
    FLIP(low_val);
    gpiod_set_value(adev->gpioLOW, low_val);
}

Теперь, глядя на экран осциллографа, я не наденуНе вижу никакой разницы с непропатченным ядром:

Рис 1

Зеленая нить с высоким приоритетом (HIGH), вытесняется желтой нитью с низким приоритетом (LOW)однажды зеленый спит.Затем LOW работает до завершения ...

Изменение или даже изменение приоритетов ничего не дает.Одной вещью, которая влияет на ситуацию, является последовательность порождения потока.Когда я изменил его, получил это:

wake_up_process(adev->low_thread);
wake_up_process(adev->high_thread);

Рис 2

LOW работает до завершения ДО ВЫСОКОГО

То, что я ожидаю увидеть, это изображениекак это:

Pic 3

На предыдущем изображении LOW установлен в политику SCHED_NORMAL:

// ...
struct sched_param paramL = { .sched_priority = 0 };
struct sched_param paramH = { .sched_priority = MAX_RT_PRIO - 10 };
// ...
ret = sched_setscheduler(adev->high_thread, SCHED_FIFO, &paramH);
// ...
ret = sched_setscheduler(adev->low_thread, SCHED_NORMAL, &paramL);
// ...

Я ожидал, что 2 потока SCHED_FIFO ведут себя одинаково

И СЕЙЧАС ВОПРОС: Так как это мой первый опыт работы с исправленным ядром RT, я даже не могу сказать, нормальное ли это поведение или нет.Я ожидаю, что полностью выгружаемое ядро ​​будет ПОЛНОСТЬЮ ПРЕДВАРИТЕЛЬНЫМ - если поток с высоким приоритетом находится в состоянии выполнения - он просто получает процессорное время.То, что я вижу, это просто гонка с приоритетом, НЕ принятым во внимание.

Может быть, я делаю что-то НЕПРАВИЛЬНОЕ?Не пробовал это из пользовательского пространства.

ТОЛЬКО для полной картинки - 2 нити SCHED_NORMAL:

2 нормальных нити

имеют одинаковые интервалы времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...