【问题标题】:Unable to understand how the "current" macro works for x86 architecture无法理解“当前”宏如何用于 x86 架构
【发布时间】:2019-05-25 05:42:42
【问题描述】:

我试图了解 current 宏的工作原理,因此开始浏览 Linux Kernel 源代码版本 4.19。试图了解 x86 架构

包括/asm-generic/current.h:8

#define get_current() (current_thread_info()->task)
#define current get_current()

然后我试图找到 current_thread_info() 的定义。

include/linux/thread_info.h

#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
 * For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the
 * definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels,
 * including <asm/current.h> can cause a circular dependency on some platforms.
 */
#include <asm/current.h>
#define current_thread_info() ((struct thread_info *)current)
#endif

然后我试图找到当前的定义

arch/x86/include/asm/current.h

DECLARE_PER_CPU(struct task_struct *, current_task);

static __always_inline struct task_struct *get_current(void)
{
        return this_cpu_read_stable(current_task);
}

#define current get_current()

get_current() 再次返回 struct task_struct,为什么我们要在 current_thread_info() 中将其类型转换为 struct thread_info。

您能否解释一下 current 是如何执行的。我在某处读到它位于内核堆栈的顶部或底部

【问题讨论】:

    标签: c linux process linux-kernel


    【解决方案1】:

    对于投射指针 - struct thread_info thread_infofirst member of the struct task_struct

    struct task_struct {
    #ifdef CONFIG_THREAD_INFO_IN_TASK
        /*
         * For reasons of header soup (see current_thread_info()), this
         * must be the first element of task_struct.
         */
        struct thread_info      thread_info;
    #endif
    

    强制转换是合法的——我们返回一个指向struct 的第一个成员的指针。它可以类似地使用&amp;current-&gt;thread_info,但如果struct task_struct 的定义在某些情况下是不透明(即它是不完整的类型),则不能使用它!


    至于DECLARE_PER_CPU 的工作原理,这取决于。你过去学到的东西可能不再适用于这里。用DECLARE_PER_CPU 声明的变量是使用特殊宏读取和更新的。其他 这是因为在 x86 上,读取是通过一个特殊的段寄存器发生的。其他 CPU 架构则必须使用一些完全不同的方法来访问 per-cpu 值。

    通常应该使用 this_cpu_read 读取 per-cpu 变量,这不允许 GCC 以任何方式缓存它,但当前线程信息是一个例外,因为当前线程始终在当前线程中运行,无论 CPU 是什么它开着。来自arch/x86/include/asm/percpu.h

    /*
     * this_cpu_read() makes gcc load the percpu variable every time it is
     * accessed while this_cpu_read_stable() allows the value to be cached.
     * this_cpu_read_stable() is more efficient and can be used if its value
     * is guaranteed to be valid across cpus.  The current users include
     * get_current() and get_thread_info() both of which are actually
     * per-thread variables implemented as per-cpu variables and thus
     * stable for the duration of the respective task.
     */
    

    【讨论】:

    • 我仍然无法获取存储在堆栈中的 thread_info 的位置..
    猜你喜欢
    • 2021-05-04
    • 2021-10-17
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2011-04-16
    相关资源
    最近更新 更多