【问题标题】:How ownership is checked during mutex unlock in kernel?在内核中的互斥锁解锁期间如何检查所有权?
【发布时间】:2015-08-18 06:52:57
【问题描述】:

我正在尝试了解 Linux 内核中互斥锁实现的内部结构。 在我看来,关于互斥锁实现的最基本的事情之一是

只有获得锁的线程才能释放锁 互斥体

但是,即使在完成互斥锁实现 (http://lxr.free-electrons.com/source/kernel/locking/mutex.c) 之后,我还是无法理解在 mutex_unlock 期间如何检查所有权?

根据实现:

void __sched mutex_unlock(struct mutex *lock){ 
     .......
     mutex_clear_owner(lock);  // just clears the owner
     __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath);
     ....
}

这里是 mutex_clear_owner 宏定义(http://lxr.free-electrons.com/source/kernel/locking/mutex.h#L25)。

static inline void mutex_clear_owner(struct mutex *lock)
{
    lock->owner = NULL;
}

那么如何判断调用了unlock函数的线程是否真的是线程被锁住了呢?

我错过了什么?

提前致谢。

【问题讨论】:

  • 据我所知,mutex_clear_owner 不会检查所有权,它会清除它。释放锁由不同的函数(mutex_unlock?)执行。
  • 是的,你是对的。但是 __mutex_fastpath_unlock 也不执行任何与检查所有权相关的操作。由于 clear_owner 是第一个语句并清除所有者,因此任何所有权都应该发生在那里。由于那里没有发生,我无法理解所有权检查是如何执行的。

标签: multithreading linux-kernel mutex


【解决方案1】:

你的问题不清楚。

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

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

如您所见,清除所有者需要使用#ifndef CONFIG_DEBUG_MUTEXES。

【讨论】:

  • 好的。如果我理解正确,这些信息仅供开发人员使用,内核不强制执行。因此,如果其他线程尝试解锁之前没有获得的互斥锁,它能够解锁它吗?
【解决方案2】:

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

这里是所有权检查 debug_mutex_unlock 函数。这只会在有意义的调试情况下调用。

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

【讨论】:

    猜你喜欢
    • 2014-10-09
    • 2018-01-10
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-31
    • 1970-01-01
    相关资源
    最近更新 更多