cache_init()

Инициализировать библиотеку libcache

Прототип:

#include <sys/cache.h>
int cache_init( int flags,
struct cache_ctrl *cinfo,
const char *dllname );

Аргументы:

flags
Ноль или флаги управления поведением библиотеки согласованности кэша. В настоящее время определен только один флаг:
CACHE_INIT_FLAG_IGNORE_SCAN
Указать библиотеке рассматривать память устройства как неотслеживаемую, независимо от того, отображаются ли кеши данных в системе как отслеживаемые или нет. Это может потребоваться для устройств в системе, которые обходят механизм отслеживания шины, или как обход для аппаратных ошибок.
cinfo
Указатель на структуру cache_ctrl, которая содержит информацию о состоянии. Библиотека использует эту структуру для хранения различной информации, которая используется при выполнении операций синхронизации. Драйвер должен выделить и инициализировать эту структуру. Все поля структуры должны быть инициализированы нулями, за исключением поля fd. Дополнительные сведения о членах этой структуры см. в описании.
dllname
Путь к загружаемой DLL, которая предоставляет процедуры синхронизации кеша, или NULL для использования процедур по умолчанию.

Библиотека:

libcache

Описание:

Функция cache_init() инициализирует библиотеку согласованности кеша. Драйвер должен вызвать cache_init() перед использованием библиотеки.

Согласованность кэша

Драйверы устройств для оборудования, которое выполняет прямой доступ к памяти (DMA), используют данную библиотеку согласованности кэша. Эти устройства являются либо устройствами управления шиной, которые могут напрямую читать или изменять память, либо устройствами, которые используют контроллер DMA для передачи данных между устройством и памятью. Ключевым фактором является то, что доступ к памяти может получить агент, отличный от ЦП.

В некоторых системах согласованность кэша выполняется с помощью протокола отслеживания шины, который реализован аппаратно. В таких системах ЦП отслеживают все транзакции на шине памяти и автоматически синхронизируют свои кэши с памятью.

Например, если внешний агент изменяет данные в некоторой ячейке памяти, ЦП будет наблюдать цикл записи в память, и, если у него есть кэшированная копия данных в этой ячейке памяти, он сделает недействительной соответствующую запись в кэше. В следующий раз, когда ЦП попытается исследовать ячейку памяти, он будет извлекать измененные данные из памяти, а не извлекать устаревшие данные из кеша.

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

В других системах, где нет такого протокола отслеживания, реализованного на оборудовании, согласованность кэша между ЦП и внешними устройствами должна поддерживаться программным драйвером. Обычно это однопроцессорные системы, поскольку в SMP-системах отслеживание шины является обычным механизмом синхронизации процессоров друг с другом. Для работы в этих системах программное обеспечение драйвера должно предпринять специальные действия, чтобы обеспечить согласованность данных между процессором и внешними устройствами.

Драйвер различными способами обеспечивает согласованность данных для систем, в которых отсутствует протокол отслеживания шины. Первый - это подход «большого молотка», который просто отключает кеширование для любой области памяти, доступной как для ЦП, так и для внешнего устройства. Однако у этого подхода есть серьезные потери в производительности; для некоторых сетевых устройств в определенных системах пропускная способность снижается примерно до половины исходного значения.

Вы можете решить указанную выше проблему пропускной способности, используя кэшируемые буферы данных, но выполняя операции синхронизации с буферами данных в стратегических точках драйвера. Например, в случае передачи пакетов для сетевого устройства драйвер должен гарантировать, что все данные, относящиеся к пакету, были сброшены в память, прежде чем позволить агенту DMA начать копирование данных. В случае приема пакета драйвер должен сделать недействительными все кэшированные данные, относящиеся к буферу пакетов, прежде чем позволить агенту DMA передавать данные в буфер приема. Это исключает возможность того, что ЦП мог записать кэшированную часть данных в буфер памяти после того, как сетевое устройство обновило буфер новыми пакетными данными.

Драйвер может выполнять операции очистки (flushing) и аннулирования (invalidation) одним из двух способов. Он может выдавать специальные зависящие от ЦП инструкции, которые работают с кешем, или может использовать библиотеку согласованности кэша (libcache). Последний подход предпочтительнее, поскольку он делает ваш драйвер переносимым. Библиотека выполняет правильную работу в зависимости от типа процессора, на котором она работает. Для максимальной переносимости библиотеку необходимо использовать независимо от того, есть в системе протокол отслеживания шины или нет. Если в системе реализован протокол отслеживания шины, библиотека определяет это и гарантирует, что не будут выполняться ненужные операции синхронизации.

Возвращаемое значение:

0
Успешное завершение.
-1
Возникла ошибка. Код ошибки записан в errno. Если это случилось небезопасно для устройства использовать любые DMA операции применительно к кешируемым буферам. Также, вызов функций с указанием структуры cache_ctrl будет иметь непредсказуемые последствия.

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Предостережения:

Операция аннулирования кэша может иметь определенные отрицательные побочные эффекты, для избежания которых драйвер должен принять меры. Если буфер данных частично разделяет строку кэша с какой-либо другой частью данных (включая другой буфер данных), может произойти повреждение данных. Поскольку аннулирование выполняется с грануляцией строки кэша, аннулирование данных в начале или конце буфера может потенциально сделать недействительными важные данные, такие как программные переменные, что означает, что изменения, внесенные в данные ЦП, могут быть случайно потеряны.

Вы можете избежать этого, выполнив выравнивание буфера данных. Драйвер должен выравнивать начало буфера по размеру строки кэша. Он также должен выравнивать окончние буфера по размеру строки кэша. Для этого драйвер может использовать поле cache_line_size структуры cache_ctrl. Обратите внимание, что это значение может быть нулевым (например, если есть протокол согласования кеша, реализованный на оборудовании), и в этом случае драйверу не нужно выполнять какие-либо выравнивания.

Тематические ссылки:

struct cache_ctrl, cache_fini(), CACHE_FLUSH(), CACHE_INVAL()




Предыдущий раздел: Описание API библиотеки cache