Работа с данными, связанными с процессорами, на этапе компиляции

We use cookies. Read the Privacy and Cookie Policy

Работа с данными, связанными с процессорами, на этапе компиляции

Описать переменную, которая связана с определенным процессором, на этапе компиляции можно достаточно просто следующим образом.

DEFINE_PER_CPU(type, name);

Это описание создает переменную типа type с именем name, которая имеет интерфейс связи с каждым процессором в системе. Если необходимо объявить соответствующую переменную с целью избежания предупреждений компилятора, то необходимо использовать следующий макрос.

DECLARE_PER_CPU(type, name);

Работать с этими переменными можно с помощью функций get_cpu_var() и put_cpu_var(). Вызов функции get_cpu_var() возвращает l-значение (левый операнд, l-value) указанной переменной на текущем процессоре. Этот вызов также запрещает вытеснение кода в режиме ядра, а соответственный вызов функции put_cpu_var() разрешает вытеснение.

get_cpu_var(name)++; /* увеличить на единицу значение переменной

                        name, связанное с текущим процессором */

put_cpu_var(); /* разрешить вытеснение кода в режиме ядра */

Можно также получить доступ к переменной, связанной с другим процессором.

per_cpu(name, cpu)++; /* увеличить значение переменной name

                         на указанном процессоре */

Использовать функцию per_cpu() необходимо осторожно, так как этот вызов не запрещает вытеснение кода и не обеспечивает никаких блокировок. Необходимость использования блокировок при работе с данными, связанными с определенным процессором, отпадает, только если к этим данным может обращаться один процессор. Если процессоры обращаются к данным других процессоров, то необходимо использовать блокировки. Будьте осторожны! Применение блокировок рассматривается в главе 8, "Введение в синхронизацию выполнения кода ядра", и главе 9, "Средства синхронизации в ядре".

Необходимо сделать еще одно важное замечание относительно создания данных. связанных с процессорами, на этапе компиляции. Загружаемые модули не могут использовать те из них, которые объявлены не в самом модуле, потому что компоновщик создает эти данные в специальных сегментах кода (а именно, .data.percpu). Если необходимо использовать данные, связанные с процессорами, в загружаемых модулях ядра, то нужно создать эти данные для каждого модуля отдельно или использовать динамически создаваемые данные.