Multithreading 在内核中的互斥解锁期间如何检查所有权?

Multithreading 在内核中的互斥解锁期间如何检查所有权?,multithreading,linux-kernel,mutex,Multithreading,Linux Kernel,Mutex,我试图理解Linux内核中互斥实现的内部结构。 在我看来,互斥实现最基本的一点是 只有获取锁的线程才能释放服务器上的锁 互斥 然而,即使在经历了互斥实现()之后,我也无法理解在互斥解锁期间如何检查所有权 根据执行情况: void __sched mutex_unlock(struct mutex *lock){ ....... mutex_clear_owner(lock); // just clears the owner __mutex_fastpath_u

我试图理解Linux内核中互斥实现的内部结构。 在我看来,互斥实现最基本的一点是

只有获取锁的线程才能释放服务器上的锁 互斥

然而,即使在经历了互斥实现()之后,我也无法理解在互斥解锁期间如何检查所有权

根据执行情况:

void __sched mutex_unlock(struct mutex *lock){ 
     .......
     mutex_clear_owner(lock);  // just clears the owner
     __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath);
     ....
}
这是互斥对象\u clear\u owner宏定义()

那么,它如何检查调用了unlock函数的线程是否实际上是已锁定的线程

我错过了什么


提前谢谢。

您的问题不清楚

“只有获得锁的线程才能释放互斥锁”是程序员的信息。显然,如果说互斥体只能由锁定它们的线程解锁,并且有代码通过解锁由其他线程锁定的互斥体而违反此属性,那么大量的错误报告将不会对您有所帮助,并且在这里是毫无意义的

因此,检测此类违规尝试仅作为调试功能才有意义,在这种情况下,oops/panic是正常的


如您所见,清除所有者是由#ifndef CONFIG_DEBUG_mutex保证的。

现在我明白了@employee of the month想要说什么了

这里是所有权检查调试互斥锁解锁功能。这将仅在有意义的调试情况下调用

void debug_mutex_unlock(struct mutex *lock)
{
    if (likely(debug_locks)) {
        DEBUG_LOCKS_WARN_ON(lock->magic != lock);

        if (!lock->owner)
            DEBUG_LOCKS_WARN_ON(!lock->owner);
        else
            DEBUG_LOCKS_WARN_ON(lock->owner != current);

        DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
        mutex_clear_owner(lock);
    }

据我所知,互斥锁的所有者不检查所有权,而是清除它。释放锁是由不同的功能(互斥锁解锁?)执行的。是的,您是正确的。但是_mutex_fastpath_unlock也不会执行任何与检查所有权相关的操作。由于clear_owner是第一个声明并清除了所有者,因此任何所有权都应该发生在那里。由于没有发生这种情况,我无法理解所有权检查是如何执行的。好的。如果我理解正确的话,这些信息只供开发人员使用,而不是由内核强制执行。因此,如果其他线程尝试解锁一个先前未获取的互斥锁,它是否能够解锁它?
void debug_mutex_unlock(struct mutex *lock)
{
    if (likely(debug_locks)) {
        DEBUG_LOCKS_WARN_ON(lock->magic != lock);

        if (!lock->owner)
            DEBUG_LOCKS_WARN_ON(!lock->owner);
        else
            DEBUG_LOCKS_WARN_ON(lock->owner != current);

        DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
        mutex_clear_owner(lock);
    }