【问题标题】:Killing a tasklet while holdiing spin_lock_irqsave在持有 spin_lock_irqsave 的同时杀死一个 tasklet
【发布时间】:2017-09-26 13:45:52
【问题描述】:

我正在使用以下 API 来杀死一个 tasklet:

tasklet_kill();

在终止 tasklet 时,我使用 spin_lock_irqsave 禁用了本地中断。为什么内核会抛出以下消息(警告?):

Attempt to kill tasklet from interrupt

在持有 spin_lock 的同时使用tasklet_kill() 是否不可取?

【问题讨论】:

  • 我不知道消息的实际原因(实际上是notice,不是警告)。但是如果 tasklet 正在运行(在其他 CPU 上),则该函数打算等待直到它完成。给定的等待实际上是一个忙等待,也就是说,在禁用中断的情况下允许它。但是您确定要等待一个您专门移入 tasklet 并禁用中断的任务吗?
  • 是的。我希望任何待处理的小任务(已经安排好)都能完成。另外我希望没有新的小任务被安排,因此需要禁用中断以确保没有从中断处理程序中安排新的小任务

标签: kernel spinlock tasklet


【解决方案1】:

如果你看一下 func 本身,你会发现它有一个对 yield 的调用,它可以放弃 cpu。但在禁用中断和/或持有自旋锁的情况下,这是禁止的。

【讨论】:

  • 您确定在禁用中断的情况下禁止调用yield()吗?虽然此函数在内部调用schedule(),但它使用set_current_state(TASK_RUNNING); 执行此操作,即不更改线程的状态。据我了解,禁用中断yield 永远不会放弃cpu,它只是无操作。
  • 它调用 sys_sched_yield,就好像它是用户空间在做它一样
  • 我已经注意到系统调用。但同样,我不知道不能在禁用中断的情况下调用系统调用的一般规则。 (不过,通常会避免来自 Linux 内核的直接系统调用)。
  • 没有针对“任何”系统调用的规则,但系统调用是入口点,这样调用它们是违反分层的。玩具系统调用可能会起作用,但您不能指望常规系统调用会像这样。特别是对于这个系统调用,您可以轻松地检查它是否从禁用中断开始。 (而不是以 _irqsave 方式),然后尝试将线程从 cpu 上移开。简而言之,在禁用 irqs 的情况下调用 yield 是不安全的。
  • 好的,可能正在调用lockal_irq_disable() 意味着不应在禁用中断的情况下调用该函数。但是,消息只是通知,而不是警告错误,这看起来很可疑。
猜你喜欢
  • 2013-01-16
  • 2016-01-30
  • 2020-10-27
  • 2019-08-24
  • 1970-01-01
  • 2015-09-03
  • 2014-05-04
  • 2015-08-03
  • 1970-01-01
相关资源
最近更新 更多