Как предотвратить предотвращение кэширования значений MMAP?

Я написал драйвер linux, который ioremaps экспортирует PCI BAR0 для конкретного устройства в двоичный атрибут sysfs, позволяющий пользователю напрямую управлять им.

Проблема возникает, когда я пытаюсь использовать MMAP поверх атрибута для прямого доступа к этому биту памяти (из программы пользовательской программы). Чтение выполняется просто отлично и возвращает ожидаемые значения, хотя, когда я пишу в эту память, он, похоже, кэшируется где-то между ядром и памятью и не доставляется в корневой комплекс GMCH (и, следовательно, устройство). То, что я хотел бы сделать, это иметь неявный барьер памяти записи после каждого доступа.

  • Есть ли способ предотвратить загрузку ядра из кэширования в бит памяти mmap-ed?

Последующие действия:

  • Вызывается msync() после каждого доступа к "принятому" способу сделать это?

Ответ 1

Идем дальше и ответим на это сам с моим решением.

В драйвере Kernel из моей функции sysfs mmap есть макрос в /include/asm/pgtable.h, который устанавливает правильные флаги для napache'd pfn remap. Это выглядит так:

vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
               vma->vm_end - vma->vm_start,
               vma->vm_page_prot))
    return -EAGAIN;

Кроме того, в userland mmap я использовал флаг MAP_SHARED в аргументе flags mmap.

Комбинация двух в конечном итоге сделала трюк.

Ответ 2

Можете ioremap_nocache() помочь?