内核模块和SCHED_RR线程的优先级 [英] Priority of kernel modules and SCHED_RR threads

查看:220
本文介绍了内核模块和SCHED_RR线程的优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个嵌入式Linux平台(Beagleboard,运行Angstrom Linux),连接两个设备:

I have an embedded Linux platform (the Beagleboard, running Angstrom Linux) with two devices connected:


  • 激光测距仪UTM 30)通过USB连接

  • 通过SPI连接的自定义外部板

写了一个Linux内核模块,负责SPI数据传输。它有一个IRQ处理程序,其中 spi_async

We have a written a Linux kernel module which is responsible for the SPI data transfer. It has an IRQ handler in which spi_async is called which in turn causes an async callback method to be called.

我的C ++应用程序由三个线程组成:

My C++ application consists of three threads:


  • 用于数据处理的主线程

  • 激光轮询线程

  • SPI轮询线程

我遇到的问题似乎是由上述模块如何交互造成的。

I am experiencing problems which seem to be caused by how the modules described above interact.


  • 当关闭USB设备(激光测距仪)时,我会正确接收所有SPI消息(每3ms消息一次,消息长度除以数据速率<1ms),与线程调度无关。

  • 当我打开USB设备,并且使用正常的线程调度(SCHED_OTHER,优先级0,没有很好的级别设置)运行我的程序大约1%的消息是丢失,因为spi_async的回调方法是在下一个IRQ发生时运行的(我可以处理这种情况不同,为了不松动消息,所以这不是一个大问题。)

  • 并且我使用SCHED_RR和

  • When I switch off the USB device (laser range finder) I receive all SPI messages correctly (1 message every 3ms, message length divided by data rate is <1ms), independent from thread scheduling
  • When I switch on the USB device and I run my program with normal thread scheduling (SCHED_OTHER, priority 0, no nice level set) about 1% of the messages is "lost" because the callback method of spi_async is running when the next IRQ occurs (I could handle this case differently in order not to loose the messages, so this is not a big issue.)
  • With the USB device turned on and I run the program with SCHED_RR and


  • priority = 10主线程

  • priority = 10用于SPI读取线程

  • 优先级= 4用于USB /激光轮询线程

我丢失了40%的消息,因为IRQ在调用spi-callback方法之前被再次触发! (我仍然可能找到一个解决方法,但问题是,我需要快速响应时间,在这种情况下不能再达到)。我需要使用线程调度和激光设备,所以我正在寻找一种方法来解决这种情况。

then I am loosing 40% of the messages because the IRQ is triggered again before the spi-callback method is called! (I could still maybe find a workaround, but the problem is that I need fast response times which can no longer be reached in this case). I need to use the thread scheduling and the laser device so I am looking for a way to solve this case.

问题1:

我的假设是,内核空间中的spi_async触发的IRQ处理程序和回调的优先级高于用户空间中运行的任何线程的优先级(无论是SCHED_RR还是SCHED_OTHER )。这意味着在我的应用程序中转向SCHED_RR不应该减慢SPI传输,但这似乎是非常错误的。是吗?

My assumption was that IRQ handlers and the callbacks triggered by spi_async in kernel space have higher priority than any thread running in user space (no matter if SCHED_RR or SCHED_OTHER). This would mean that turning to SCHED_RR in my application shouldn't slow down SPI transfer, but this seems very wrong. Is it?

问题2:

如何确定这里发生了什么?哪些调试助手存在? (或者你不需要任何进一步的信息?)对我来说,主要的问题是:为什么我只有在激光设备打开时才会遇到问题。 USB驱动程序可以消耗这么多时间吗?

How can I determine what happens here? Which debugging aids exist? (Or maybe you don't need any further information?) The main question for me is: why do I experience the problems only when the laser device is turned on. Could the USB driver consume so much time?

----- EDIT:

-----

spi_async的回调调用 wake_up_interruptible(& mydata-> readq); c $ c> wait_queue_head_t readq; )。从用户空间(我的应用程序)我调用一个函数,导致 poll_wait(file,& mydata-> readq,wait); 调用 read()

The spi_async's callback calls wake_up_interruptible(&mydata->readq); (with wait_queue_head_t readq;). From the user space (my app) I call a function which results in poll_wait(file, &mydata->readq, wait); When the poll returns the user space calls read().


  • 当我的应用程序使用 SCHED_OTHER 运行时,我可以看到回调方法首先完成之前在我的内核模块中的 read()方法。

  • 当我的应用程序在退出回调之前之前输入 SCHED_RR b $ b
  • When my application runs with SCHED_OTHER I can see that the callback method first finishes before the read() method in my kernel module is entered.
  • When my application runs with SCHED_RR read is entered before exiting the callback.

这似乎证明了用户空间线程的优先级高于回调方法的上下文的优先级。有没有办法改变这种行为,仍然有 SCHED_RR 我的应用程序的线程?

This seems to proof that the priority of the user space threads is higher than the callback method's context's priority. Is there any way to change this behaviour and still have SCHED_RR for my application's threads?

推荐答案

不是所有的内核线程都有一个RT优先级。想象一下,需要做一些背景工作的周期性唤醒线程正在唤醒。你不想让这个线程preemt你的RT线程。

Not all kernel thread have an RT priority. Imagine a periodically waking up thread that needs to do some background work is waking up. You don't want this thread to preemt your RT thread. So I guess your first assumption is wrong.

根据您的其他问题:


  • 您的主要处理循环通过队列接收SPI数据

  • spi处理线程提供主处理队列

似乎你的主要处理线程阻碍了spi驱动程序线程负责spi数据传输。

It seems your main processing thread get in the way of the spi driver thread responsible for the spi data transfer.

这是发生了什么:


  • 发出IRQ

  • 调用spi_async,表示数据传输排队,

  • spi主线程与您的主要处理线程,激光线程竞争,但是这个内核线程没有RT优先级,所以它每次都会丢失一个RR线程正在运行。

你可以回到正常的调度,同时使用各种CONFIG_PREEMPT_选项。或者与spi主驱动程序混乱,以确保任何延迟的工作排队具有足够的优先级。或者甚至不排队。

What you can do is going back to normal scheduling, while playing with the various CONFIG_PREEMPT_ options. Or mess with the spi master driver, to ensure that any delayed work is queued with enough priority. Or even not queued at all.

这篇关于内核模块和SCHED_RR线程的优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆