Я пытаюсь написать драйвер с пользовательской функцией mmap()
для PCIe BAR, с целью сделать этот BAR кэшируемым в кеш процессора. Я знаю, что это не лучший способ добиться максимальной пропускной способности и что порядок записи непредсказуем (и в этом случае проблем нет).как сделать mmap для кэшируемого PCIe BAR
Это аналогично тому, что описано в How would one prevent MMAP from caching values?
Процессор является Sandy Bridge i7, PCIe устройства Altera Stratix IV DEV. доска.
Во-первых, я попытался сделать это на CentOS 5 (2.6.18). Я изменил настройки MTRR, чтобы убедиться, что BAR не находится в неразрешимом MTRR и используется io_remap_pfn_range()
с _PAGE_PCD
и _PAGE_PWT
бит очищен. Считывает работу, как ожидалось: считывает возвращаемые правильные значения и второе чтение на один и тот же адрес не обязательно приводит к тому, что чтение переходит на PCIe (в FPGA проверяется счетчик чтения). Тем не менее, записи заставили систему замораживаться, а затем перезагружаться без сообщений в журналах или на экране.
Во-вторых, я попытался сделать это на CentOS 6 (2.6.32), имеющем поддержку PAT. Результат один и тот же: чтение работает правильно, запись вызывает зависание системы и перезагрузку. Интересно, что непрерывная запись в виде строки (AVX/SSE), не зависящая от времени/записи, работает, как и ожидалось, т. Е. Они всегда идут в FPGA, а FPGA наблюдает полную запись в кеш-строке, после чего считывает возвращаемые правильные значения. Однако простая 64-разрядная запись по-прежнему вызывает зависание/перезагрузку системы.
Я также попытался установить ioremap_cache()
, а затем iowrite32()
внутри кода водителя. Результат тот же.
Я думаю, что это проблема с оборудованием, но я был бы признателен, если кто-то может поделиться любыми идеями о том, что происходит.
EDIT: Я смог захватить сообщение MCE на CentOS 6: Исключить проверку компьютера: 5 Банк 5: be2000000003110a.
Я также пробовал один и тот же код на 2-гнездовом Sandy Bridge (Romley): чтение и невременное поведение записи одинаковы, простая запись не вызывает MCE/crash, но не влияет на состояние системы, то есть значение в память не изменяется.
Кроме того, я пробовал использовать тот же код на более старой 2-гнездовой системе Nehalem: простые записи также вызывают MCE, хотя коды разные.