Нам дается проект, в котором мы реализуем контрольную точку памяти (базовая - это просто просматривает страницы и выгружает найденные данные в файл (также проверяет информацию о странице (закрытая, заблокированная и т. Д.)) И инкрементная, где мы смотрим только на то, если данные изменен ранее и выгружает его в файл). Насколько я понимаю, мы в значительной степени создаем уменьшенную версию состояний сохранения памяти (я могу ошибаться, но это именно то, что я получаю из этого). В настоящее время мы используем подход VMA к нашей проблеме, чтобы пройти через заданный диапазон (пока он не опускается ниже или выше диапазона пользовательского пространства (это означает отсутствие диапазона ядра или ниже пользовательского пространства)), чтобы сообщить о найденных данных со страниц, с которыми мы сталкиваемся. Я знаю, что vma_area_struct используется для доступа к vma (некоторые функции, включая find_vma ()). Моя проблема в том, что я не уверен, как мы проверяем отдельные страницы в этом заданном диапазоне адресов (пользователь дает нам) с помощью этой vma_area_struct. Я знаю только о struct page (это почти все), но я все еще изучаю ядро ​​в деталях, поэтому я обязательно пропущу кое-что. Что-то мне не хватает в vma_area_sruct при доступе к страницам?

Второй вопрос: что мы используем для перебора каждой отдельной страницы в найденной vma (с заданного начального и конечного адреса)?

0
MD_90 31 Окт 2018 в 20:25

1 ответ

Лучший ответ

VMA содержат виртуальные адреса их первого и (одного после) последнего байта:

struct vm_area_struct {
     /* The first cache line has the info for VMA tree walking. */

     unsigned long vm_start;         /* Our start address within vm_mm. */
     unsigned long vm_end;           /* The first byte after our end address
                                        within vm_mm. */
...

Это означает, что для получения данных страницы вам нужно сначала выяснить, в каком контексте работает ваш код?

Если это в контексте процесса, тогда простого подхода copy_from_user может быть достаточно для получения фактических данных и обхода страницы (через весь ваш PGD / PUD / PMD / PTE), чтобы получить PFN, а затем включить его. на struct page. (Будьте осторожны не , чтобы использовать соблазнительный virt_to_page(addr), поскольку он будет работать только с адресами ядра).

Что касается итерации, вам нужно выполнить итерацию только в PAGE_SIZE по виртуальным адресам, которые вы получаете от VMA.

Обратите внимание, что это предполагает , что страницы действительно сопоставлены. В противном случае (!pte_present(pte_t a)) вам может потребоваться переназначить его самостоятельно, чтобы получить доступ к данным.

Если ваша проверка выполняется в каком-то другом контексте (например, kthread / прерывание), вы должны переназначить страницу из свопа, прежде чем обращаться к ней, что является совершенно другим случаем. Если вам нужен простой способ, я посмотрю здесь: https: //www.kernel.org/doc/gorman/html/understand/understand014.html, чтобы понять, как обрабатывать поиск / получение подкачки.

0
Knightingale 3 Ноя 2018 в 01:12