完全可抢占的Linux内核中的SCHED_FIFO策略是否使用kthread优先级?

时间:2019-03-12 13:18:13

标签: linux-kernel real-time scheduler kernel-module preemption

我已经构建了带有RT补丁的Linux内核。 它编译正确,我明白了 调度程序策略集

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);
}

现在,看着示波器屏幕,我发现与未修补的内核没有任何区别:

Pic 1

高优先级的绿色线程(HIGH),一旦绿色睡眠,就会被黄色的低优先级线程(LOW)抢占。 然后LOW运行直到完成...

更改甚至恢复优先级没有任何帮助。 影响情况的一件事是线程生成序列。 当我更改它时,得到这个:

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

Pic 2

LOW一直运行到HIGH之前完成

我希望看到的是这样的图片:

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修补内核,因此我什至无法确定 是否正常。我希望完全可抢占的内核是完全可替代的- 如果有处于运行状态的高优先级线程-它只会获取CPU时间。 我看到的只是一场没有优先考虑的比赛。

也许我做错了什么? 没有从用户空间尝试过。

仅用于全图显示-2个SCHED_NORMAL线程:

2 normal threads

被平均分配时间片。

0 个答案:

没有答案