【问题标题】:Why is spinlock no-op in Linux kernel (non-SMP)?为什么 Linux 内核(非 SMP)中的自旋锁无操作?
【发布时间】:2012-07-22 18:38:22
【问题描述】:

我已经阅读这篇文章很长一段时间了,但对我来说没有意义。可能是因为我对这一切都很陌生,仍然不了解一些内核概念。

这就是我想出的(没有错误或 NULL 处理,只是为了这个问题):

内核自旋锁在内核线程中执行,是抢占式的。

void spinlock_acquire(spinlock_t *spinlock)
{
  tryagain:
    while(spinlock->plock != UNLOCKED) ;
    context_switch_block;
    if(spinlock->plock != UNLOCKED) {
        context_switch_unblock;
        goto tryagain;
    }
    spinlock_lock(spinlock, current_thread);
    context_switch_unblock;
}

【问题讨论】:

  • 我不明白这个问题。或者至少我不明白您包含的代码与问题有何关系。
  • 单个 CPU 上的自旋锁,代码有什么问题?我读过在单 CPU 上的 Linux 中,自旋锁代码相当于没有操作,但为什么呢?
  • 完全看不懂你的代码......

标签: linux kernel spinlock


【解决方案1】:

在 Linux 是抢占式内核之前,UP 上的自旋锁基本上是无操作的。一旦内核被抢占,对preempt_disable() 的调用就会被添加到自旋锁中。

所以它或多或少是这样的:

  • 您想防止某些 CPU 冲突,请使用某种自旋锁。
  • 您想防止冲突的软中断、tasklet……使用spin_lock_bh,它禁用软中断、tasklet 等……(bh 是历史名称,它来自“下半部分”)。
  • 您想防止冲突的硬件中断使用 spin_lock_irq*,它会禁用硬件中断。
  • 所有自旋锁都可以防止抢占。
  • 在 UP 内核上,自旋锁不采用真正的自旋锁(因为没有冲突的 CPU,我们不能被抢占,并且有用于处理硬中断、软中断等的自旋锁变体...)。
  • 在带有 SMP 内核的 UP 机器上,自旋锁可能会变成 nop。
  • 即使在禁用抢占的 UP 内核上,如果启用,自旋锁也可能包含用于自旋锁调试的代码。

【讨论】:

  • 几乎是最令人满意的答案,赞成。但是为什么自旋锁只用于防止 CPU 冲突呢?不应该像互斥锁一样在任何地方使用它来防止多线程危害吗?互斥锁和自旋锁的唯一区别不是互斥锁阻塞线程直到可用性和自旋锁自旋直到可用性这一事实吗?清除后将选择此作为答案。
  • 是的,没错。我表达得很糟糕。第 4 点涵盖了这一点:所有自旋锁都通过 preempt_disable() 调用防止抢占。回想一下,您可能遇到的唯一危险是其他 CPU、中断(NMI、hardirqs、softirqs、tasklet...)和其他抢占您自己代码的内核线程。前四个要点涵盖。
  • 感谢您的宝贵时间,如果问题中的示例代码有误,您能否解释一下?
  • @user1075375:我不知道你从哪里得到这个例子,但它不是来自 Linux 内核。
【解决方案2】:

在非 SMP 上不需要自旋锁。由于自旋锁禁用中断,因此其他任何人都不可能在此时拥有锁。一旦线程 A 禁用中断,线程 B 就不可能尝试获取相同的锁,因为没有什么可以导致 A 失去 CPU 以支持 B。因此,所有非 SMP 上的自旋锁都是,好吧,什么都没有(除非你要求它禁用中断)。

沙查尔

【讨论】:

  • 为什么自旋锁会禁用中断?
  • @user1075375:普通自旋锁不禁用中断,spin_lock_irq* 禁用本地中断,当您有一个冲突的中断处理程序时使用它们,这将依次使用正常的自旋锁。跨度>
  • @user1075375:自旋锁必须在本地 CPU 上禁用中断的情况下运行。如果中断已经被禁用,自旋锁本身不必禁用中断本身。然后,由程序来确保没有代码可以运行会尝试在持有锁时获取锁。
  • 我不懂你 Shachar,假设我知道我需要一个相互共享的资源很短的时间,比如写一个 32 位寄存器或在 ram 中设置一个标志,我可以使用自旋锁而不是互斥锁,因为如果锁不可用,互斥锁会导致我的线程屈服,并且上下文切换非常消耗资源,所以当我可以在几个周期内获得锁时,我最终浪费了我的 cpu 资源来弹出线程。哦,好吧,我想我明白了,这不会是几个周期,因为只有一个 CPU,并且需要一个上下文切换来释放锁......谢谢。
  • 如果您不阻止中断,那么在您持有锁时,中断处理程序可能需要相同的临界区。无法解决此问题,因为在该处理程序返回之前,您无法完成临界区处理。这对互斥体来说不是问题,因为不允许在中断处理程序中获取它们。
猜你喜欢
  • 2012-10-27
  • 2011-03-23
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多