Проблема синхронизации вывода

У меня есть существующий код, который берет список struct page * и создает таблицу дескрипторов для совместного использования памяти с устройством. Верхний уровень этого кода в настоящее время ожидает буфер, выделенный с помощью vmalloc или из пользовательского пространства, и использует vmalloc_to_page для получения соответствующей страницы структуры * .

Теперь верхний уровень должен справляться со всеми видами памяти, а не только с памятью, полученной с помощью vmalloc . Это может быть буфер, полученный с помощью kmalloc , указатель внутри стека потока ядра или другие случаи, о которых я не знаю. Единственная гарантия, что у меня есть, это то, что вызывающий этот верхний уровень должен гарантировать, что рассматриваемый буфер памяти отображается в пространстве ядра в этой точке (т. Е. доступ к буферу [i] допустим для всех 0 на данный момент). Как мне получить страницу структуры * , соответствующую произвольному указателю?

Поместив ее в псевдокод, у меня есть следующее:

lower_layer(struct page*);
upper_layer(void *buffer, size_t size) {
    for (addr = buffer & PAGE_MASK; addr <= buffer + size; addr += PAGE_SIZE) {
        struct page *pg = vmalloc_to_page(addr);
        lower_layer(pg);
    }
}

, и теперь мне нужно изменить upper_layer для работы с любым допустимым буфером (без изменения lower_layer ).

Я обнаружил virt_to_page , который Драйверы устройств Linux указывает, что работает на « логический адрес, [не] память из vmalloc или верхняя память ». Кроме того, is_vmalloc_addr проверяет, исходит ли адрес из vmalloc , а virt_addr_valid проверяет, является ли адрес действительным виртуальным адресом (источник для virt_to_page ; это включает kmalloc (GFP_KERNEL) и стеки ядра). А как насчет других случаев: глобальные буферы, верхняя память (когда-нибудь она появится, хотя я могу ее пока игнорировать), возможно, другие типы, о которых я не знаю? Поэтому я мог бы переформулировать свой вопрос следующим образом:

  1. Каковы все зоны памяти в ядре?
  2. Как отличить их друг от друга?
  3. Как получить информацию о сопоставлении страниц для каждый из них?

Если это имеет значение, код работает на ARM (с MMU), а версия ядра не ниже 2.6.26.

25
задан Gilles 'SO- stop being evil' 23 May 2011 в 15:23
поделиться