Невозможно понять, как работает «текущий» макрос для архитектуры x86 - PullRequest
0 голосов
/ 27 декабря 2018

Я пытался понять, как работает макрос current, поэтому начал просматривать исходный код ядра Linux версии 4.19.Пытался понять для архитектуры x86

include / 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, почему мы типизируем его в struct thread_info в current_thread_info ().

Не могли бы вы объяснить, как выполняется текущий.Я где-то читал, что он находится вверху или внизу стека ядра

1 Ответ

0 голосов
/ 27 декабря 2018

Для приведения указателя - struct thread_info thread_info является первым членом 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.Он мог бы аналогичным образом использовать &current->thread_info, но его нельзя использовать, если определение struct task_struct является непрозрачным в некоторых контекстах (т. Е. Это неполный тип)!


Какот того, как работает DECLARE_PER_CPU, зависит.То, что вы узнали в прошлом, может больше не применяться здесь.Переменные, объявленные с DECLARE_PER_CPU, читаются и обновляются с помощью специальных макросов.Другое Это потому, что на x86 чтения происходят через специальный сегментный регистр.Другие архитектуры ЦП должны затем использовать совершенно другие средства доступа к значениям для каждого процессора.

Обычно переменные для процессора должны читаться с использованием this_cpu_read, что не позволяет GCC кэшировать его каким-либо образом, ноинформация о текущем потоке является исключением, поскольку текущий поток всегда выполняется в текущем потоке, независимо от того, на каком он процессоре.С 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.
 */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...